Asp.net MVC Razor 页面上有多个表单
哟
,我的网站上有一个注册页面 - 页面顶部是现有用户的登录表单。主区域有登记表。
登录区域是带有 @model ViewModels.LoginViewModel
的部分视图 注册区域也是一个带有 @model ViewModels.RegViewModel
的部分
包含这些部分的主页是一个带有 @model ViewModels.RegPageViewModel
的视图
这个视图模型看起来像:
public class RegViewModel
{
public RegisterVm RegisterVm { get; set; }
public LoginVm LoginVm { get; set; }
}
当我将页面的注册部分(它的操作是注册/捕获 - 接收操作需要 RegisterVm)提交给它的控制器,它抱怨传递了错误的视图模型 子
视图及其视图模型是怎么回事?有处理这个问题的标准方法吗?
我是否应该为此页面提供一个提交 URL,以判断这是登录请求还是注册请求,然后相应地处理该帖子?不过,这对我来说似乎很混乱......
http://monobin.com/__d33cf45a4 - RegisterVm.cs (LoginVm.cs) 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");
}
}
w://
Yo
I have a registration page on my site - at the top of the page is a login form for existing users. In the main area there is the registration form.
The login are is a partial view with @model ViewModels.LoginViewModel
The registration are is also a partial with @model ViewModels.RegViewModel
The main page which houses these partials is a view with @model ViewModels.RegPageViewModel
This viewmodel looks like:
public class RegViewModel
{
public RegisterVm RegisterVm { get; set; }
public LoginVm LoginVm { get; set; }
}
When I submit the registration part of the page (it's action is register/capture - the receiving action expects a RegisterVm) to it's controller it complains about being passed the wrong viewmodel
What's the deal with subviews and their viewmodel? Is there a standard approach to dealing with this?
Should I have one submit URL for this page which figures out if it's a login request or a register request and then handles the post accordingly? That seems messy to me though...
http://monobin.com/__d33cf45a4 - RegisterVm.cs (LoginVm.cs is pretty much the same as this)
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()
}
And finally 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");
}
}
w://
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要确保表单元素(如文本框等)应与 RegisterVM 和 LoginVM 属性具有相同的 id。您的理论是正确的,但我认为您可能在 MVC 的命名约定中犯了错误。
如果您可以分享您的视图代码+ VM 类,那么我们将能够提供更好的帮助。
编辑:
查看您的代码,我认为您应该将视图模型传递给部分视图。例如下面这行相信应该是这样的>
@Html.Partial("_Register", Model.RegisterVm)
You need to ensure that the form elements (like the textbox etc) should have the same id as the RegisterVM and LoginVM properties. Your theory is right but I think you might be making a mistake in the naming convention of MVC.
If you can share your view code + the VM classes, then we'll be able to help better.
EDIT:
Looking at your code I think you should be passing the view model to your partial view. Like for example the following line believe should be like this >
@Html.Partial("_Register", Model.RegisterVm)
根据您对 nEEbz 的回答:
您正在使用:
这将变成
注意
LoginVM.
部分您的登录操作可能如下所示:
因此它需要诸如
Email
和Password
之类的字段名称,而不是LoginVM.Email
和LoginVM.Password
代码>.因此,您可以使用
Html.Textbox
(这样字段名称就不会自动创建)。According to your answer to nEEbz:
You are using:
this would turn into
<input name="LoginVM.Email" ...>
Notice the
LoginVM.
partYour login action probably looks like:
so it expect field names like
Email
andPassword
, notLoginVM.Email
andLoginVM.Password
.So you could could use
Html.Textbox
instead (so that the field name doesn't get autocreated).