ASP.NET MVC 2 - ViewModel前缀

时间:2010-03-18 21:18:19

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

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

主要观点:

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

登录PartialView:

<% 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>
<% } %>

注册PartialView:

<% 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>
<% } %>

我该如何更改?

4 个答案:

答案 0 :(得分:12)

如果由于某种原因无法进行EditorTemplate,可以在View中执行此操作:

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

请注意,PartialView中的所有输入都将作为前缀。

感谢R0MANARMY指出这一点。

答案 1 :(得分:8)

您可以使用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

中为登录模型定义不同的部分

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

检查一下。有人编写了一大堆支持设置前缀的重载。 TextBoxFor rendering to HTML with prefix on the ID attribute

如果缺少任何一种,你可以看到如何扩展这些模式以及你可能需要的其他模式。