Asp.net MVC中Razor常见的问题与解决方法总结
前言
最近在学习asp.net mvc razor,在使用中遇到了不少的问题,所以想着总结下来,没有经验的童鞋就是这样磕磕碰碰出来的经验。话不多说,来一起看看详细的介绍:
一、datatype的错误提示消息无法自定义
这也许是asp.net mvc的一个bug。viewmodel中定义了datatype为date字段:
[required(errormessage = "birthday must be input!")] [datatype(datatype.date, errormessage = "please enter a date like(2017-07-19).")] public datetime birthday { get; set; }
razor生成的html如下:
<input name="birthday" class="form-control" id="birthday" type="text" value="" data-val-required="birthday must be input!" data-val="true" data-val-date="字段 birthday 必须是日期。">
required的错误消息和定义的一样,而datatype的消息却没有??既然datatype有自定义消息的公开属性为啥不起作用?如果有知道的欢迎留言。
解决方法:
通过javascript在页面load的时候替换掉原来的消息。
$("#txtdesignateddate").attr('data-val-date', 'please enter a date like(2017/1/1)');
二、d-mmm-yy格式的英文日期在ie中验证出错,而在chrome中没问题
razor模型绑定设置如下:
@html.labelfor(m => m.birthday, new { @class = "col-md-2 control-label" }) @html.textboxfor(m => m.birthday, "{0:d-mmm-yy}", new { @class = "form-control" })
edge测试情况:显示日期不对的错误消息。
chrome测试情况:居然没有错误提示!!
如果是英文以外同样格式的日期,都会显示日期不对错误消息。这到底怎么回事?
官网(http://jqueryvalidation.org/date-method/)其实也有说明:
翻看js代码:
// http://docs.jquery.com/plugins/validation/methods/date date: function( value, element ) { return this.optional(element) || !/invalid|nan/.test(new date(value).tostring()); }, // http://docs.jquery.com/plugins/validation/methods/dateiso dateiso: function( value, element ) { return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); },
dateiso也只支持yyyy-mm-dd 或者yyyy/mm/dd格式的验证。没办法只能重写一个验证方法覆盖原来的。
解决方法:
(function ($) { $.validator.methods.date = function (value, element) { return this.optional(element) || datecheck(value); } }(jquery));
自定义一个datecheck函数就可以了。
三、dropdownlist设置默认选择项偶尔会无效
action端设置:
return view(new registerviewmodel { birthday = datetime.now, birthcity = city.shanghai });
view端设置:
@html.dropdownlistfor(m => m.birthcity, new selectlistitem[] { new selectlistitem{ text="jiangxi",value="1"}, new selectlistitem{ text="beijing",value="2"}, new selectlistitem{ text="shanghai",value="3"}, new selectlistitem{ text="shengzhen",value="4"}, }, new { @class = "form-control" })
偶尔这样的设置无法选择action中设置的选项,如果有知道原因的欢迎留言。
解决方法:用selectlist替代selectitem列表。
@html.dropdownlistfor(m => m.birthcity, new selectlist(new selectlistitem[] { new selectlistitem{ text="jiangxi",value="1"}, new selectlistitem{ text="beijing",value="2"}, new selectlistitem{ text="shanghai",value="3"}, new selectlistitem{ text="shengzhen",value="4"}, }, "value", "text", model.birthcity), new { @class = "form-control" })
四、密码输入自动提示在chrome中无法禁止
autocomplete = "off"
在chrome58以后都无效了。这个是浏览器的问题没办法了。
五、disabled的控件值不上传给服务器
解决方法:通过javascript在submit之前将控件的disabled属性删除,submit完成之后再复原disabled属性。
六、html.hiddenfor()的控件值不更新
由于hiddenfor默认先使用modelstate的数据,所以在modelstate验证失败的情况下,重新加载画面可能hiddenfor的控件数据是旧的。
解决方法:
modelstate.clear();
七、list与dictionary的数据razor如何绑定
viewmodel属性:
public list listtest { get; set; } public dictionary> dictest { get; set; }
view端绑定:
@for (int i = 0; i < model.listtest.count; i++) { @html.textboxfor(m => m.listtest[i].name, new { @class = "form-control" }) @html.textboxfor(m => m.listtest[i].phone, new { @class = "form-control" }) }
@for (int i = 0; i < model.dictest.count; i++) { string key = model.dictest.keys.elementat(i); < input type="hidden" name="dictest[@i].key" value="@key" /> for (int j = 0; j < model.dictest[key].count; j++) { @html.textbox($"dictest[{i}].value[{j}].name", model.dictest[key][j].name, new { @class = "form-control" }) @html.textbox($"dictest[{i}].value[{j}].phone", model.dictest[key][j].phone, new { @class = "form-control" }) } }
生成的html如下:
<input name="listtest[0].name" class="form-control" id="listtest_0__name" type="text" value="lxb1"> <input name="listtest[0].phone" class="form-control" id="listtest_0__phone" type="text" value="123"> <input name="listtest[1].name" class="form-control" id="listtest_1__name" type="text" value="lxb2"> <input name="listtest[1].phone" class="form-control" id="listtest_1__phone" type="text" value="1234"> <input name="listtest[2].name" class="form-control" id="listtest_2__name" type="text" value="lxb3"> <input name="listtest[2].phone" class="form-control" id="listtest_2__phone" type="text" value="12345">
<input name="dictest[0].key" type="hidden" value="jx"> <input name="dictest[0].value[0].name" class="form-control" id="dictest_0__value_0__name" type="text" value="lxb1"> <input name="dictest[0].value[0].phone" class="form-control" id="dictest_0__value_0__phone" type="text" value="123"> <input name="dictest[0].value[1].name" class="form-control" id="dictest_0__value_1__name" type="text" value="lxb2"> <input name="dictest[0].value[1].phone" class="form-control" id="dictest_0__value_1__phone" type="text" value="1234"> <input name="dictest[1].key" type="hidden" value="sz"> <input name="dictest[1].value[0].name" class="form-control" id="dictest_1__value_0__name" type="text" value="lxb3"> <input name="dictest[1].value[0].phone" class="form-control" id="dictest_1__value_0__phone" type="text" value="12345"> <input name="dictest[1].value[1].name" class="form-control" id="dictest_1__value_1__name" type="text" value="lxb4"> <input id="dictest_1__value_1__phone" class="form-control" value="123456" name="dictest[1].value[1].phone">
其中控件的name很重要。
list: viewmodelpropertyname[index].modelpropertyname
格式。
dictionary:key设置为viewmodelpropertyname[index].key
,value设置为viewmodelpropertyname[index].value
八、尽量多使用editorfor
比如将第7点的dictest使用editorfor。首先需要在shared或者controller自身文件夹下创建editortemplates文件夹,然后在editortemplates文件夹中添加分部页。代码如下:
@using mvcdemo.models; @model list @for (int i = 0; i < model.count; i++) { @html.textboxfor(m => m[i].name, new { @class = "form-control" }) @html.textboxfor(m => m[i].phone, new { @class = "form-control" }) }
调用页面设置:
list的时候
@html.editorfor(m => m.listtest, "_partialperson", $"listtest")
dictionary的时候
@for (int i = 0; i < model.dictest.count; i++) { string key = model.dictest.keys.elementat(i); <input type="hidden" name="dictest[@i].key" value="@key" /> @html.editorfor(m => m.dictest[key], "_partialperson", $"dictest[{i}].value") }
生成的html:
<div class="col-md-10"> <input name="listtest[0].name" class="form-control" id="listtest_0__name" type="text" value="lxb1"> <input name="listtest[0].phone" class="form-control" id="listtest_0__phone" type="text" value="123"> <input name="listtest[1].name" class="form-control" id="listtest_1__name" type="text" value="lxb2"> <input name="listtest[1].phone" class="form-control" id="listtest_1__phone" type="text" value="1234"> <input name="listtest[2].name" class="form-control" id="listtest_2__name" type="text" value="lxb3"> <input name="listtest[2].phone" class="form-control" id="listtest_2__phone" type="text" value="12345"> </div>
<div class="col-md-10"> <input name="dictest[0].key" type="hidden" value="jx"> <input name="dictest[0].value[0].name" class="form-control" id="dictest_0__value_0__name" type="text" value="lxb1"> <input name="dictest[0].value[0].phone" class="form-control" id="dictest_0__value_0__phone" type="text" value="123"> <input name="dictest[0].value[1].name" class="form-control" id="dictest_0__value_1__name" type="text" value="lxb2"> <input name="dictest[0].value[1].phone" class="form-control" id="dictest_0__value_1__phone" type="text" value="1234"> <input name="dictest[1].key" type="hidden" value="sz"> <input name="dictest[1].value[0].name" class="form-control" id="dictest_1__value_0__name" type="text" value="lxb3"> <input name="dictest[1].value[0].phone" class="form-control" id="dictest_1__value_0__phone" type="text" value="12345"> <input name="dictest[1].value[1].name" class="form-control" id="dictest_1__value_1__name" type="text" value="lxb4"> <input name="dictest[1].value[1].phone" class="form-control" id="dictest_1__value_1__phone" type="text" value="123456"> </div>
这样就简化了不少,也到达了重用。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。