我注意到mvc默认项目中有些东西让我想知道它是如何工作的。当我创建一个带有个人用户帐户身份验证的ddefault MVC项目时,Visual Studio将使用两个" ResetPassword"来支持一个AccountController。动作。通过GET请求接受字符串参数的一个。行动看起来像这样:
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
View看起来像这样:
@model SISGRAD_MVC.Models.ResetPasswordViewModel
@{
ViewBag.Title = "Reset password";
}
<h2>@ViewBag.Title.</h2>
@using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Reset your password.</h4>
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Code)
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Reset" />
</div>
</div>
我使用URL,GET样式中的代码访问Action,并且视图知道从URL初始化model属性。一点感兴趣的是,只有在我使用@Html.HiddenFor()
时才有效。这是如何工作的,以及视图如何知道何时从URL中提取数据,何时不知道?
答案 0 :(得分:2)
因为你的方法是
public ActionResult ResetPassword(string code)
DefaultModelBinder
会将code
的值添加到ModelState
HiddenFor(m => m.Code)
方法使用来自ModelState
的值,而不是模型中的值(如果它们存在,那么它将呈现
<input type="hidden" name="Code" id="Code" value="###" />
其中###
是您传递给方法的值。
&#34;视图知道从URL&#34; 初始化模型属性的声明不正确。该模型未初始化,实际上是null
,您可以使用
<div>@Model.Code</div>
将抛出&#34;对象引用未设置为对象的实例。&#34; 异常,而
<div>@ViewData.ModelState["Code"].Value.AttemptedValue</div>
将显示正确的值。
附注:根据您的评论,DisplayFor(m => m.Code)
未显示该值的原因是它使用ViewData
中的值(null
,因为模型为{ {1}})。默认显示模板使用以下代码(请参阅source code)
null
而不是使用以下代码的internal static string StringTemplate(HtmlHelper html)
{
return html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue);
}
(请参阅source code
HiddenFor(m => m.Code)
另请注意,如果您使用default:
string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName, format) : valueParameter), isExplicitValue);
break;
定义路线,则无需在视图中添加隐藏的输入。默认情况下,它将作为路由值添加 - url: "Account/ResetPassword/{code}"
方法将呈现
BeginForm()