Question

For MVC4, What's the best-practice way to send a ViewModel used to populate a view back to a controller via POST?

Was it helpful?

Solution

Lets assume you want a login form with this view model:

public class LoginModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    public bool RememberMe { get; set; }
}

Using this view model in a view is straight-forward, just send a new instance of LoginModel to the view:

public ActionResult Login()
{
    var model = new LoginModel();
    return View(model);
}

Now we can create the Login.cshtml view:

@model App.Models.LoginModel

@using (Html.BeginForm())
{
    @Html.LabelFor(model => model.UserName)
    @Html.TextBoxFor(model => model.UserName)
    @Html.ValidationMessageFor(model => model.UserName)

    @Html.LabelFor(model => model.Password)
    @Html.PasswordFor(model => model.Password)
    @Html.ValidationMessageFor(model => model.Password)

    @Html.CheckboxFor(model => model.RememberMe)
    @Html.LabelFor(model => model.RememberMe)

    <input type="submit" value="Login" />
}

Now we have to create an action in the controller which handles the post of this form. We can do that like this:

[HttpPost]
public ActionResult Login(LoginModel model)
{
    if (ModelState.IsValid)
    {
        // Authenticate the user with information in LoginModel.
    }

    // Something went wrong, redisplay view with the model.
    return View(model);
}

The HttpPost attribute will ensure that the controller action only can be reached via a post request.

MVC will use its magic and binds all the properties from the view back to a LoginModel instance populated with the values from the post.

OTHER TIPS

One way is to have your Post controller accept the ViewModel as its parameter then map its properties to your domain model.

public class Model
{
     public DateTime Birthday {get;set;}
}

public class ViewModel
{
     public string Month {get;set;}
     public string Day {get;set;}
     public string Year {get;set;}
}

Controller

[HttpPost]
public ActionResult Create(ViewModel viewModel)
{
    string birthday = viewModel.Month + "/" + viewModel.day + "/" + viewModel.year;

    Model model = new Model { Birthday = Convert.ToDateTime(birthday) } ;
    // save 
    return RedirectToAction("Index");
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top