Asp.net MVC Razor在一个页面上有多个表单

时间:2010-11-21 12:42:36

标签: asp.net-mvc viewmodel razor

我的网站上有一个注册页面 - 页面顶部是现有用户的登录表单。在主要区域有登记表。

登录是@model ViewModels.LoginViewModel的部分视图 注册也是@model ViewModels.RegViewModel

的部分注册

包含这些部分的主页是@model ViewModels.RegPageViewModel

的视图

此视图模型如下所示:

public class RegViewModel
{
    public RegisterVm RegisterVm { get; set; }
    public LoginVm LoginVm { get; set; }
}

当我提交页面的注册部分(它的操作是注册/捕获 - 接收操作需要RegisterVm)到它的控制器时,它会抱怨传递错误的viewmodel

子视图和他们的视图模型有什么关系?有没有一个标准的方法来处理这个?

我是否应该为此页面提供一个提交URL,以确定它是登录请求还是注册请求,然后相应地处理帖子?虽然这对我来说似乎很混乱......

http://monobin.com/__d33cf45a4 - RegisterVm.cs(LoginVm.cs与此基本相同)

http://monobin.com/__m69132f76 - RegPageVm.cs

Register.cshtml:

@model xxxx.ViewModels.RegPageVm
@{
    View.Title = "Register";
    Layout = "~/Views/Shared/_BareBones.cshtml";
}
<link rel="stylesheet" href="@Url.Content("~/Public/Css/signup.css")" type="text/css" />
<div id="sign-up-container">
    <div id="sign-up-box">
        <div id="sign-up-box-left">
            <img src="@Url.Content("~/Public/Images/Signup_176x81.png")" />
        </div>
        <div id="sign-up-box-right">
           @Html.Partial("_Register")
        </div>
    </div>
</div>
<div class="clear">
</div>

_Register.cshtml:

@model xxxx.ViewModels.RegisterVm

@using (Html.BeginForm("Capture", "Register", FormMethod.Post))
{
    <table class="sign-up-box-inner">
        <tr>
            <td class="label-area">
                @Html.LabelFor(x => x.Email)
            </td>
            <td class="field-area">
                @Html.TextBoxFor(x => x.Email, new { @class = "login-input", title = "Enter Name" })
            </td>
        </tr>
        <tr>
            <td class="label-area">
                @Html.LabelFor(x => x.Password)
            </td>
            <td class="field-area">
                @Html.PasswordFor(x => x.Password, new { @class = "login-input", title = "Enter Name" })
            </td>
        </tr>
        <tr>
            <td class="label-area">
                @Html.LabelFor(x => x.UserName)
            </td>
            <td class="field-area">
                @Html.TextBoxFor(x => x.UserName, new { @class = "login-input", title = "Enter Name" })
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="image" src="../../Public/Images/Submit_150x47.png" class="submit-button" />
            </td>
        </tr>
    </table>
    @Html.AntiForgeryToken()
}

最后是RegisterController.cs:

public class RegisterController : Controller
    {
        public ActionResult Index()
        {
           return View();
        }

        [HttpPost, ValidateAntiForgeryToken]
        public ActionResult Capture(RegisterVm registerVm)
        {
            if (!ModelState.IsValid)
            {
                return View("index", new RegPageVm()
                {
                    LoginVm = new LoginVm(),
                    RegisterVm = registerVm
                });
            }

            return RedirectToAction("index", "Event");
        }
    }

瓦特://

2 个答案:

答案 0 :(得分:4)

您需要确保表单元素(如文本框等)应具有与RegisterVM和LoginVM属性相同的ID。你的理论是正确的,但我认为你可能在MVC的命名约定中犯了一个错误。

如果您可以共享您的视图代码+ VM类,那么我们将能够提供更好的帮助。

修改

查看您的代码我认为您应该将视图模型传递给部分视图。例如,以下行相信应该是这样的&gt;

@Html.Partial("_Register", Model.RegisterVm)

答案 1 :(得分:-1)

根据您对nEEbz的回答:

您正在使用:

Html.TextBoxFor(x=>x.LoginVM.Email) // i guess

这会变成<input name="LoginVM.Email" ...>

注意LoginVM.部分

您的登录操作可能如下:

public ActionResult Login(LoginVM model) { }

因此它需要EmailPassword等字段名称,而不是LoginVM.EmailLoginVM.Password

因此您可以使用Html.Textbox代替(以便字段名称不会被自动处理)。