将参数从url传递到视图

时间:2015-10-20 23:03:11

标签: c# asp.net asp.net-mvc razor asp.net-mvc-5

我注意到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中提取数据,何时不知道?

1 个答案:

答案 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()