14

As I understand from the question below it should be possible to use different models for Get and Post actions. But somehow I'm failing to achieve just that.

What am I missing?

Related question: Using two different Models in controller action for POST and GET

Model

public class GetModel
{
    public string FullName;
    public string Name;
    public int Id;
}

public class PostModel
{
    public string Name;
    public int Id;
}

Controller

public class HomeController : Controller
{
    public ActionResult Edit()
    {
        return View(new GetModel {Id = 12, Name = "Olson", FullName = "Peggy Olson"});
    }

    [HttpPost]
    public ActionResult Edit(PostModel postModel)
    {
        if(postModel.Name == null)
            throw new Exception("PostModel was not filled correct");
        return View();
    }
}

View

@model MvcApplication1.Models.GetModel
@using (Html.BeginForm()) {
    @Html.EditorFor(x => x.Id)
    @Html.EditorFor(x=>x.Name)
    <input type="submit" value="Save" />
}
Community
  • 1
  • 1
Rasmus
  • 2,783
  • 2
  • 33
  • 43

2 Answers2

12

Your models aren't using proper accessors so model binding doesn't work. Change them to this and it should work:

public class GetModel
{
   public string FullName { get; set; }
   public string Name { get; set; }
   public int Id { get; set; }
}

public class PostModel
{
   public string Name { get; set; }
   public int Id { get; set; }
}
Trax72
  • 958
  • 5
  • 12
  • I thought those classes in question were missing them for simplicity reasons but were otherwise everyday properties. :) *Never trust example code to be much different from original* – Robert Koritnik Oct 11 '11 at 22:46
7

A bit of clarification

GET and POST controller actions can easily use whatever types they need to. Actually we're not talking about models here. Model is a set of classes/types that represent some application state/data. Hence application or data model.

What we're dealing here are:

  • view model types
  • action method parameter types

So your application model is still the same. And GetModel and PostModel are just two classes/types in this model. They're not model per-se.

Different types? Of course we can!

In your case you're using a view model type GetModel and then pass its data to PostModel action parameter. Since these two classes/types both have properties with same matching names, default model binder will be able to populate PostModel properties. If property names wouldn't be the same, you'd have to change the view to rename inputs to reflect POST action type property names.

You could as well have a view with GetModel type and then post action with several different prameters like:

public ActionResult Edit(Person person, IList<Address> addresses)
{
    ...
}

Or anything else. You'll just have to make sure that post data can be bound to these parameters and their type properties...

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404