将参数从网址传递到视图
本文关键字:视图 址传 参数 | 更新日期: 2023-09-27 18:18:39
我注意到 mvc 默认项目中的一些东西让我想知道它是如何工作的。当我使用个人用户帐户身份验证创建默认 MVC 项目时,Visual Studio 使用两个"重置密码"操作来搭建帐户控制器基架。一个通过 GET 请求接受字符串参数。操作如下所示:
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : 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 样式,并且视图知道从 URL 初始化模型属性。有趣的是,这仅在我使用 @Html.HiddenFor()
时才有效。这如何工作,视图如何知道何时从 URL 中提取数据,何时不从中提取数据?
因为你的方法
public ActionResult ResetPassword(string code)
DefaultModelBinder
会将 code
的值添加到ModelState
HiddenFor(m => m.Code)
方法使用来自ModelState
的值,而不是来自模型的值(如果存在(,因此它将呈现
<input type="hidden" name="Code" id="Code" value="###" />
其中###
是传递给方法的值。
您关于"视图知道从 URL 初始化模型属性">的说法不正确。该模型未初始化,实际上您可以使用null
进行测试
<div>@Model.Code</div>
这将引发"对象引用未设置为对象的实例">异常,而
<div>@ViewData.ModelState["Code"].Value.AttemptedValue</div>
将显示正确的值。
旁注:从您的评论中,DisplayFor(m => m.Code)
不显示该值的原因是它正在使用ViewData
中的值(这是null
,因为模型是null
的(。默认显示模板使用以下代码(请参阅源代码(
internal static string StringTemplate(HtmlHelper html)
{
return html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue);
}
与使用以下代码的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()
方法将呈现
<form action="Account/ResetPassword/###" ... >