รหัสนี้จะไม่ทำงาน
ModelState.Remove("Step");
model.Step = 2;
... เนื่องจาก HiddenFor always (!) อ่านจาก ModelState ไม่ใช่ตัวแบบ และหากไม่พบคีย์ "ขั้นตอน" ระบบจะสร้างค่าเริ่มต้นสำหรับประเภทตัวแปรนั้นซึ่งจะเป็น 0 ในกรณีนี้
นี่คือวิธีแก้ปัญหา ฉันเขียนมันเพื่อตัวเอง แต่ไม่รังเกียจที่จะแบ่งปันเพราะฉันเห็นหลายคนกำลังดิ้นรนกับตัวช่วย HiddenFor ที่ซุกซนนี้
public static class CustomExtensions
{
public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
ReplacePropertyState(htmlHelper, expression);
return htmlHelper.HiddenFor(expression);
}
public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
{
ReplacePropertyState(htmlHelper, expression);
return htmlHelper.HiddenFor(expression, htmlAttributes);
}
public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
{
ReplacePropertyState(htmlHelper, expression);
return htmlHelper.HiddenFor(expression, htmlAttributes);
}
private static void ReplacePropertyState<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
string text = ExpressionHelper.GetExpressionText(expression);
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(text);
ModelStateDictionary modelState = htmlHelper.ViewContext.ViewData.ModelState;
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
if (modelState.ContainsKey(fullName))
{
ValueProviderResult currentValue = modelState[fullName].Value;
modelState[fullName].Value = new ValueProviderResult(metadata.Model, Convert.ToString(metadata.Model), currentValue.Culture);
}
else
{
modelState[fullName] = new ModelState
{
Value = new ValueProviderResult(metadata.Model, Convert.ToString(metadata.Model), CultureInfo.CurrentUICulture)
};
}
}
}
จากนั้นคุณก็ใช้งานได้ตามปกติจากภายในคุณดู:
@Html.HiddenFor2(m => m.Id)
มันคุ้มที่จะพูดถึงมันใช้งานได้กับคอลเลกชันด้วย