【问题标题】:ASP.NET MVC 2 - ViewModel PrefixASP.NET MVC 2 - ViewModel 前缀
【发布时间】:2011-01-29 05:25:43
【问题描述】:

我想在我的视图中使用 RenderPartial 两次,并关联不同的模型。问题是两个模型中都存在一些属性(昵称、密码)。它们没有前缀,因此即使是 id 或名称在输出中也是相等的。现在,如果我有昵称或密码的模型错误,这两个字段都会突出显示。

主视图:

<div>
    <% Html.RenderPartial("Register", Model.RegisterModel); %>
</div>
<div>
    <% Html.RenderPartial("Login", Model.LoginModel); %>
</div>

登录部分视图:

<% using (Html.BeginForm("Login", "Member")) { %>
<fieldset>
    <legend>Login</legend>
    <p>
        <%= Html.LabelFor(x => x.Nickname) %>
        <%= Html.TextBoxFor(x => x.Nickname) %>
    </p>
    <p>
        <%= Html.LabelFor(x => x.Password) %>
        <%= Html.PasswordFor(x => x.Password) %>
    </p>    
    <input type="submit" value="Login" />
</fieldset>
<% } %>

注册部分视图:

<% using (Html.BeginForm("Register", "Member")) { %>
<fieldset>
    <legend>Register</legend>
    <p>
        <%= Html.LabelFor(x => x.Nickname) %>
        <%= Html.TextBoxFor(x => x.Nickname) %>
    </p>
    <p>
        <%= Html.LabelFor(x => x.Email) %>
        <%= Html.TextBoxFor(x => x.Email) %>
    </p>
    <p>
        <%= Html.LabelFor(x => x.Password) %>
        <%= Html.PasswordFor(x => x.Password) %>
    </p>
    <p>
        <%= Html.LabelFor(x => x.PasswordRepeat) %>
        <%= Html.PasswordFor(x => x.PasswordRepeat) %>
    </p>
    <input type="submit" value="Register" />
</fieldset>
<% } %>

我该如何更改?

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-2 viewmodel modelbinders


    【解决方案1】:

    如果由于某种原因您不能执行 EditorTemplate,您可以在您的视图中执行此操作:

    var dataDict = new ViewDataDictionary();
    dataDict.TemplateInfo.HtmlFieldPrefix = "myPrefixHere";
    Html.RenderPartial("myPartialViewName", myPartialViewModel, dataDict);
    

    瞧,您的 PartialView 中的所有输入都将带有前缀。

    感谢 R0MANARMY 指出这一点。

    【讨论】:

    • 并作为一个衬里: Html.RenderPartial("myPartialViewName", myPartialViewModel, new ViewDataDictionary(){ TemplateInfo = new TemplateInfo(){ HtmlFieldPrefix = "myPrefixHere"}})
    • 如果我正在使用 RenderAction 并且该操作又返回 PartialView,那么 PartialView 和 RenderAction 都没有我可以看到的 ViewDataDictionary 重载。我希望这会是return PartialView( 的过载。有什么建议吗?
    • NM,发现我可以从 Partial 内部设置它,所以我将它传递给 ViewModel:@{ ViewData.TemplateInfo.HtmlFieldPrefix = Model.Id; }stackoverflow.com/a/6617869/84206
    【解决方案2】:

    您可以使用editor templates 来处理前缀,而不是使用Html.RenderPartial

    所以在你的主视图中:

    <div>
        <%-- See below what does the second argument mean --%>
        <%= Html.EditorFor(x => x.RegisterModel, "RegisterModel") %>
    </div>
    <div>
        <%= Html.EditorFor(x => x.LoginModel, "LoginModel") %>
    </div>
    

    然后创建一个文件夹Views/Shared/EditorTemplates/RegisterModel.ascx(这个文件的名字用在EditorFor辅助方法中)。还要注意,这个部分应该被强类型化为RegisterModel 属性的类型:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Ns.Models.RegisterModel>" %>
    
    <% using (Html.BeginForm("Register", "Member")) { %>
    <fieldset>
        <legend>Register</legend>
        <p>
            <%= Html.LabelFor(x => x.Nickname) %>
            <%= Html.TextBoxFor(x => x.Nickname) %>
        </p>
        <p>
            <%= Html.LabelFor(x => x.Email) %>
            <%= Html.TextBoxFor(x => x.Email) %>
        </p>
        <p>
            <%= Html.LabelFor(x => x.Password) %>
            <%= Html.PasswordFor(x => x.Password) %>
        </p>
        <p>
            <%= Html.LabelFor(x => x.PasswordRepeat) %>
            <%= Html.PasswordFor(x => x.PasswordRepeat) %>
        </p>
        <input type="submit" value="Register" />
    </fieldset>
    <% } %>
    

    您可以在Views/Shared/EditorTemplates/LoginModel.ascx 中为登录模型定义不同的部分

    【讨论】:

      【解决方案3】:

      看起来TextBoxFor 有一个重载,允许您指定额外的 HTML 属性。这不是一个理想的解决方案,但它应该让您更改呈现的文本框的 id(可能还有名称?)。当然,当您尝试发布表单时,更改名称可能会搞砸。

      【讨论】:

        【解决方案4】:

        首先,您可以使用Html.TextBox("input form name", ...) 并将名称设置为您想要的任何名称。还有一个更大的问题是如何在Html.RenderPartial() 级别上提供前缀?您已经在提供模型实例。因此,在不改变他们的视图模型的情况下,只有另一种可能性:为RenderPartial() 编写自己的重载,它会采用前缀并将其传递给其他人。

        看看这个。有人写了一大堆支持设置前缀的重载。 TextBoxFor rendering to HTML with prefix on the ID attribute

        如果缺少任何内容,您可以查看如何使用您可能需要的其他内容来扩展这些模式。

        【讨论】:

        • 您不需要为 RenderPartial 编写自己的重载,已经有一个重载可以让您重新定义 ViewData 集合是什么。您可以在其中添加您的前缀并让您的模型查找它。见:msdn.microsoft.com/en-us/library/dd470827.aspx
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多