C# 意外的模型绑定
在浏览带有个人帐户身份验证的搭建的MVC5模板时,我偶然发现了一个我无法理解的行为 给定一个请求urlC# 意外的模型绑定,c#,asp.net,asp.net-mvc,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 5,在浏览带有个人帐户身份验证的搭建的MVC5模板时,我偶然发现了一个我无法理解的行为 给定一个请求url http://localhost:53487/Account/ResetPassword?userId=4&code=T634Hfv%2BxMAlo2XjdLV6a%2Bd1%2BxGsfdiQiKRW0Nh2fB3I1U3S%2BNdXU4ixHC9uJ5F5PSRMZkQgV907CDH0x3aQPSdFliXJqD7nrjk3TLnOTawPeO8CJjk5OEyYijVur1i
http://localhost:53487/Account/ResetPassword?userId=4&code=T634Hfv%2BxMAlo2XjdLV6a%2Bd1%2BxGsfdiQiKRW0Nh2fB3I1U3S%2BNdXU4ixHC9uJ5F5PSRMZkQgV907CDH0x3aQPSdFliXJqD7nrjk3TLnOTawPeO8CJjk5OEyYijVur1i1Fr7DE7nmaDD93I000fXbQA%3D%3D
和AccountController中的操作方法
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
以及视图ResetPassword.cshtml
@model OPLA.Web.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>
}
加载视图时,行@Html.HiddenFor(model=>model.code)
生成此Html输出,并正确填充/绑定viewmodel的code
属性:
<input id="Code" name="Code" type="hidden" value="T634Hfv+xMAlo2XjdLV6a+d1+xGsfdiQiKRW0Nh2fB3I1U3S+NdXU4ixHC9uJ5F5PSRMZkQgV907CDH0x3aQPSdFliXJqD7nrjk3TLnOTawPeO8CJjk5OEyYijVur1i1Fr7DE7nmaDD93I000fXbQA==">
模型绑定器如何知道
code
查询字符串参数属于viewmodel的code
属性并自动绑定它?方法中有一个名为code
的参数。执行该方法时,code
的值将添加到ModelState
您的模型还有一个名为code
的属性。视图使用@Html.HiddenFor()
为该属性生成
。生成表单控件的所有HtmlHelper
方法(除了PasswordFor()
)通过按以下顺序读取值来确定
的值
ModelState
ViewDataDictionary
财产的实际价值
由于ModelState
包含code
的值(不区分大小写),因此值是从方法参数(即查询字符串值)设置的
有关为什么这种行为是故意的更详细解释,请参阅的第二部分。谢谢Stephen,在阅读了有关这种行为背后的原因的链接答案后,它是有意义的。我很好奇你是如何知道这种行为的,是否有任何文章/文档?我从未见过任何官方文档,但有一篇由MVC团队成员之一(我想是Brad Wilson?)撰写的文章讨论了从MVC-2到MVC-3的变化(它现在很旧了,我想我没有保留书签,但我会看看今天晚些时候有时间的时候我能不能找到它)在谷歌搜索了一下斯蒂芬·穆克之后,从里克·斯特拉尔那里找到了一个书签。这就是我指的那个(实际上是MVC-1到MVC-2的变化)。如果您通过查看,您可以看到设置值的优先级attributeThanks,以避免麻烦地挖掘帖子:)
<input id="Code" name="Code" type="hidden" value="T634Hfv+xMAlo2XjdLV6a+d1+xGsfdiQiKRW0Nh2fB3I1U3S+NdXU4ixHC9uJ5F5PSRMZkQgV907CDH0x3aQPSdFliXJqD7nrjk3TLnOTawPeO8CJjk5OEyYijVur1i1Fr7DE7nmaDD93I000fXbQA==">