Summary of common Razor Problems and Solutions in Asp.net MVC, mvcrazor
Preface
Recently I have encountered a lot of problems in using Asp.net MVC Razor, so I want to sum up my experience. Let's take a look at the detailed introduction:
1. Datatype error message cannot be customized
This may be a Bug in Asp.net MVC. ViewModel defines the DataType as Date field:
[Required(ErrorMessage = "Birthday must be input!")][DataType(DataType.Date, ErrorMessage = "Please enter a date like(2017-07-19).")]public DateTime BirthDay { get; set; }
The HTML generated by Razor is as follows:
<Input name = "BirthDay" class = "form-control" id = "BirthDay" type = "text" value = "" data-val-required = "Birthday must be input! "Data-val =" true "data-val-date =" the field BirthDay must be a date. ">
The error message of Required is the same as the defined one, but the message of DataType does not ?? Why is the public attribute of a custom message in DataType ineffective? If you have any idea, please leave a message.
Solution:
Use Javascript to replace the original message when loading the page.
$("#txtDesignatedDate").attr('data-val-date', 'Please enter a date like(2017/1/1)');
2. An error occurred while verifying the English date in d-MMM-yy format in IE, but no problem in Chrome
The Razor model binding settings are as follows:
@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 test: displays error messages with incorrect dates.
Chrome test: no error prompt !!
If the date format is not English, the error message is displayed. What the hell is going on?
Official website (http://jqueryvalidation.org/date-method/) in fact there are instructions:
Looking at the JS Code:
// http://docs.jquery.com/Plugins/Validation/Methods/datedate: function( value, element ) { return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());}, // http://docs.jquery.com/Plugins/Validation/Methods/dateISOdateISO: function( value, element ) { return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);},
DateISO only supports yyyy-MM-dd Or yyyy/MM/dd format verification. There is no way to override only one verification method to overwrite the original one.
Solution:
(function ($) { $.validator.methods.date = function (value, element) { return this.optional(element) || DateCheck(value); }}(jQuery));
You can customize a DateCheck function.
3. The default options for DropDownList settings occasionally become invalid.
Action side settings:
return View(new RegisterViewModel { BirthDay = DateTime.Now, BirthCity = City.Shanghai });
View side settings:
@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" })
Occasionally, you cannot select the option set in the Action. If you have any reason, leave a message.
Solution:Replace the SelectItem list with SelectList.
@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" })
4. Password Input automatically prompts that the password cannot be disabled in Chrome
autocomplete = "off"
It will be invalid after Chrome58. This is a problem with the browser.
5. The Disabled control value cannot be passed to the server.
Solution:Use Javascript to delete the Disabled attribute of the control before submit. After the submit is complete, restore the Disabled attribute.
6. The control value of Html. HiddenFor () is not updated.
Because modeldenfor uses ModelState data by default, if ModelState verification fails, the screen may be reloaded and the control data of HiddenFor is old.
Solution:
ModelState.Clear();
7. How to bind Razor to List and Dictionary data
ViewModel attributes:
public List ListTest { get; set; }public Dictionary> DicTest { get; set; }
View binding:
@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" }) }}
The generated Html is as follows:
<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">
The control name is very important.
List:viewmodelpropertyname[index].modelpropertyname
Format.
Dictionary: key settingsViewmodelpropertyname [index]. Key
, Value is setviewmodelpropertyname[index].Value
8. Use EditorFor as much as possible
For example, use EditorFor for DicTest. Create the EditorTemplates folder in the Shared or Controller folder, and add the branch page in the EditorTemplates folder. The Code is as follows:
@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" })}
Call page settings:
List
@Html.EditorFor(m => m.ListTest, "_PartialPerson", $"ListTest")
When 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")}
Generated 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>
This simplifies a lot and achieves reuse.
Summary
The above is all the content of this article. I hope the content of this article will help you in your study or work. If you have any questions, please leave a message, thank you for your support.