ASPNET MVC框架的两个小问题
mvc框架中有个听起来很不错的功能,那就是在form提交后,能够自动给实体赋值,只要属性名和html的元素名相同即可,基本上能够实现常见的实体内容绑定,修改等等,而且还具备自动的表单错误验证功能。如此强大的功能,应该能使开发更有效率,但在使用方面还是有些小麻烦。
mvc框架中将form的values自动赋值到实体中的主要调用方法是TryUpdateModel,关键的辅助类是FormCollection。大部分的工作都在FormCollection中完成,传递给contoller方法的FormCollection对象是mvc框架自动生成的。在给实体赋值时,依次通过实体的属性名取获取对应FormCollection中的value。而就是在提取FormCollection的value时,抛出了异常,请看如下异常信息:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
System.Web.Mvc.FormCollection.System.Web.Mvc.IValueProvider.GetValue(String key) +4
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +219
System.Web.Mvc.Controller.TryUpdateModel(TModel model, String prefix, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider) +449
System.Web.Mvc.Controller.TryUpdateModel(TModel model, IValueProvider valueProvider) +56
根据异常信息可判断,在调用GetValue方法时传入了一个nul值,于是抛出了个错误参数的异常。起初怀疑是不是在反射时没有权限访问属性,导致返回空的属性名,尝试添加权限控制等也没有解决问题。也仔细查看了一下自己写的代码,比对<<Pro Asp.Net MVC Framework>>一书的代码,也没有发现差别。唯一的差别是我用的MVC版本是RC2的,而书上用的是RC1的版本,估计是新版本不支持造成的。
最后通过网上搜索,得到的结果差点让人跳起来。这是RC2中经过确认的一个bug,解决的方法是修改源代码,重新编译一个dll。所改的代码也很简单,把FormCollection.GetValue()中的String.IsNullOrEmpty() 去掉即可。
本以为可以平稳的运行了,可却出现另外一个错误。从Html.CheckBox("chb")返回的值居然不能正常地转为bool类型,每次运行都返回类型转换失败的异常。跟踪调试后发现从form传递过来的居然是"true,false"这样的字符串,难怪会转换失败。现在问题是为什么会传回这样的值呢,界面上就只有一个Checkbox控件。继续查看页面的html源码发现,多出了一个和checkbox同名的隐藏域,value是false,因此每次提交之后都返回两个值"true,false"。难道又是框架的问题?经过搜索之后发现,依旧是框架的错。网上给出的解释是当选中时返回"true,false",没选中的时候返回"false"。于是急忙尝试了一下,果真如此。这个问题也好解决,改框架代码、自定义一个Htmlhelper的扩展方法生成checkbox,又或者取checkbox值的时候支取第一个单词,我采用最后一种方法。
解决以上两个问题之后,总算能顺利地跑起来了。真够折腾,看来开源的框架还不能完全的依赖。但不过怎样,MVC框架比起经典ASPNET来,还是很有优势的。