MVC3 Viewmodel 绑定时,生成的Textbox 名称带前缀,
如果这个样子,模型验证中会有问题,并且TryUpdateModel取不到数据
因为传入的FormCollection中key都有了前缀。
如何把前缀处理掉?
<input id="mData_bill_no" name="mData.bill_no" type="hidden" value="">
public class PayEditViewModel { public PayMDto mData { get; set; } public IEnumerable<PayM2Dto> dData { get; set; } }
public partial class PayMDto { [DataMember()] public Int32 id { get; set; } [DataMember()] [DisplayName("订单编号")] [Required(ErrorMessage = "单据编号必须输入!")] [Display(Name = "单据编号")] public String bill_no { get; set; } [DataMember()] [DataType("Date")] [Display(Name = "单据日期")] [Required(ErrorMessage = "单据日期必须输入!")] public DateTime? bill_date { get; set; } [DataMember()] [Display(Name = "申请总额")] public Decimal? apply_total { get; set; } [DataMember()] [Display(Name = "付款银行")] public String account_bank { get; set; } [DataMember()] [Display(Name = "银行账号")] public String account_code { get; set; }
这个简单,直接写一个自定义的Helper,里面嵌套现在的EditorFor,取得返回的HtmlString,然后有针对性的修改即可。
这个方案有些靠谱,我写的那个会丢失一些验证和Class信息,回头试试你的这个方法!
的确可行,已经测试通过,多谢!
我也期待最佳答案!。。。。。。。。。。。!
那你也要出些分。 O(∩_∩)O哈哈~
@Alvin: 好啊,下次你有什么问题,我帮你解决,我不问你要豆豆!!!
@Alvin: “因为传入的FormCollection中key都有了前缀。” 给这个key也加上前缀
或者用js验证
是不是可以考虑将model设置为PayEditViewModel.mData
TryUpdateMode(PayMDto)
不行,PayMDto中有业务规则的验证
我猜你肯定是想通过js来操作input,但是由于id名称变了,所以无法操作。去掉就不必了,你可以通过其它方式来操作,比如增加自定义属性。如<input id="mData_bill_no" DataField='bill_no' name="mData.bill_no" type="hidden" value="">
可以看到,我加了一个DataField的自定义属性,浏览器解析时是不会报错的,随然不符合html标准,但也没什么不妥。
用的时候通过jquery来调用。$('[DataField="bill_no"]').val()
不妨你试试。
治标不治本呀
@Alvin: 哈哈,没准这真还是你最终采用的方式呢!
@百灵:
我肯定不去迁就这个方式,我有大量的业务验证在DTO中。
我现在让ViewModel直接继承需要验证的DTO,避免带成员变量名的问题。
真正的解决之道是自定义HtmlHelper,不过目前没有时间研究。
@Alvin: 好吧,期待你的最终解决方案。
@百灵:
基本解决,目前还不能取到值,有高手请看看
public static IHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string template=null,string xx=null,string namex = null, string Value = null) { var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); var name = ExpressionHelper.GetExpressionText(expression); string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); TagBuilder tagBuilder = new TagBuilder("input"); //-- ModelState modelState; if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) { tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); } fullName = fullName.ToString().Split('.')[1]; tagBuilder.GenerateId(fullName); tagBuilder.MergeAttribute("name", fullName, true); tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name)); //还不知道如何取得Value,暂时用参数中的值 string value=null; if (Value != null) { value = Value; } else if (modelState != null && modelState.Value != null) { value = modelState.Value.AttemptedValue; } else if (modelMetadata.Model != null) { value = modelMetadata.Model.ToString(); } else { value = string.Empty; } //- tagBuilder.MergeAttribute("value", value, true); return new HtmlString(tagBuilder.ToString(TagRenderMode.Normal)); }
差不多最终版把,value也取得了,只是方法签名还需要修改一下,应该是个成品了。
我自己把贴结了,关键是我看到的还是未结,dudu,何故?
1 public static IHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string template=null,string xx=null,string namex = null, string Value = null) 2 { 3 ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 4 var name = ExpressionHelper.GetExpressionText(expression); 5 string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); 6 TagBuilder tagBuilder = new TagBuilder("input"); 7 8 //-- 9 ModelState modelState; 10 if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) 11 { 12 tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); 13 } 14 15 fullName = fullName.ToString().Split('.')[1]; 16 tagBuilder.GenerateId(fullName); 17 tagBuilder.MergeAttribute("name", fullName, true); 18 tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name)); 19 20 string value=null; 21 if (Value != null) 22 { 23 value = Value; 24 } 25 tagBuilder.MergeAttribute("value", modelMetadata.Model.ToString(), true); 26 return new HtmlString(tagBuilder.ToString(TagRenderMode.Normal)); 27 }