ASP.NET MVC Razor mais de um formulário em uma página
-
26-09-2019 - |
Pergunta
Yo
Eu tenho uma página de registro no meu site - na parte superior da página, há um formulário de login para os usuários existentes. Na área principal, há o formulário de registro.
O login é uma visão parcial com @model ViewModels.LoginViewModel
O registro também é parcial com @model ViewModels.RegViewModel
A página principal que abriga esses parciais é uma visão com @model ViewModels.RegPageViewModel
Este viewmodel se parece:
public class RegViewModel
{
public RegisterVm RegisterVm { get; set; }
public LoginVm LoginVm { get; set; }
}
Quando envio a parte do registro da página (sua ação é registro/captura - a ação receptor espera um registrovm) ao controlador, ela reclama de ser aprovada no viewmodel errado
Qual é o problema com as Subviews e o ViewModel? Existe uma abordagem padrão para lidar com isso?
Devo ter um URL de envio para esta página que descobre se for uma solicitação de login ou uma solicitação de registro e depois lida com a postagem de acordo? Isso me parece confuso ...
http://monobin.com/__d33cf45a4 - Registervm.cs (LoginVm.cs é praticamente o mesmo)
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()
}
E finalmente 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://
Solução
Você precisa garantir que os elementos do formulário (como a caixa de texto etc.) tenham o mesmo ID que as propriedades RegisterVM e LoginVM. Sua teoria está certa, mas acho que você pode estar cometendo um erro na convenção de nomenclatura do MVC.
Se você puder compartilhar seu código de visualização + as classes da VM, poderemos ajudar melhor.
EDITAR:
Olhando para o seu código, acho que você deve passar o modelo de visualização para sua visão parcial. Como, por exemplo, a seguinte linha acredita que deve ser assim>
@Html.Partial("_Register", Model.RegisterVm)
Outras dicas
De acordo com sua resposta para Neebz:
Você está usando:
Html.TextBoxFor(x=>x.LoginVM.Email) // i guess
Isso se transformaria em <input name="LoginVM.Email" ...>
Observe o LoginVM.
papel
Sua ação de login provavelmente se parece:
public ActionResult Login(LoginVM model) { }
Então espera nomes de campo como Email
e Password
, não LoginVM.Email
e LoginVM.Password
.
Para que você possa usar Html.Textbox
em vez disso (para que o nome do campo não seja autococelado).