문제

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://

도움이 되었습니까?

해결책

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)

다른 팁

According to your answer to nEEbz:

You are using:

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

this would turn into <input name="LoginVM.Email" ...>

Notice the LoginVM. part

Your login action probably looks like:

public ActionResult Login(LoginVM model) { }

so it expect field names like Email and Password, not LoginVM.Email and LoginVM.Password.

So you could could use Html.Textbox instead (so that the field name doesn't get autocreated).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top