Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET MVC3 Preferred Model Initializiation

I have been working in MVC recently, and I am curious about what the best way to initialize my view models is. Should I be mapping it directly in the controller, or should I be initializing the properties in a constructor for the view model. Also, when having lists, is this better practice since you will not have to repopulate them when there is a validation error.

For example, if i had the following model:

public FooBarViewModel
{
    public int FooBarId { get; set; }
    public string SomeInitialProperty1 { get; set; }
    public string SomeInitialProperty2 { get; set; }
    public string SomeInitialProperty3 { get; set; }
    public string SomeInitialProperty4 { get; set; }
    public int FooId { get; set; }
    public int BarId { get; set; }
    public IEnumerable<Foo> Foos { get; set; }
    public IEnumerable<Bar> Bars { get; set; }
}

and then the controller:

public MyController : Controller
{
    [HttpGet]
    public ActionResult FooBar(int foobarId)
    {
        var foobar = _fooBarRepository.GetById(foobarId);
        var model = new FooBarViewModel
                        {
                            FooBarId = foobar.Id;
                            SomeInitialProperty1 = foobar.SomeInitialProperty1;
                            SomeInitialProperty2 = foobar.SomeInitialProperty2;
                            SomeInitialProperty3 = foobar.SomeInitialProperty3;
                            SomeInitialProperty4 = foobar.SomeInitialProperty4;
                            Foos = foobar.Foos.ToList();
                            Bars = foobar.Bars.ToList();
                        }

        return View(model);
    }

    [HttpPost]
    public ActionResult FooBar(FooBarViewModel model)
    {
        if (ModelState.IsValid)
        {
             //process model
             return RedirectToAction("Index");
        }

        var foobar = _fooBarRepository.GetById(model.FoobarId);
        model.Foos = foobar.GetFoos.ToList();
        model.Bars = foobar.GetBars.ToList();
        return View(model);
    }
}

or should I do it in my model:

public FooBarViewModel
{
    public int FooBarId { get; set; }
    public string SomeInitialProperty1 { get; set; }
    public string SomeInitialProperty2 { get; set; }
    public string SomeInitialProperty3 { get; set; }
    public string SomeInitialProperty4 { get; set; }
    public int FooId { get; set; }
    public int BarId { get; set; }

    public IEnumerable<Foo> Foos 
    { 
        get { return _foos; }
    }
    private IEnumerable<Foo> _foos;

    public IEnumerable<Bar> Bars
    { 
        get { return _bars; }
    }
    private IEnumerable<Bar> _bars;

    public MyViewModel(FooBar foobar)
    {
        FooBarId = foobar.Id;
        SomeInitialProperty1 = foobar.SomeInitialProperty1;
        SomeInitialProperty2 = foobar.SomeInitialProperty2;
        SomeInitialProperty3 = foobar.SomeInitialProperty3;
        SomeInitialProperty4 = foobar.SomeInitialProperty4;
        _foos = foobar.Foos.ToList();
        _bars = foobar.Bars.ToList();
    }
}

then my controller:

public MyController : Controller
{
    [HttpGet]
    public ActionResult FooBar(int foobarId)
    {
        var foobar = _fooBarRepository.GetById(foobarId);
        var model = new FooBarViewModel(foobar);

        return View(model);
    }

    [HttpPost]
    public ActionResult FooBar(FooBarViewModelmodel)
    {
        if (ModelState.IsValid)
        {
             //process model
             return RedirectToAction("Index");
        }

        return View(model);
    }
}

Which is the preferred convention in MVC and why is it the best practice? Also, reasons why to choose one over the other? Thanks in advance.

like image 875
shuniar Avatar asked Sep 19 '11 18:09

shuniar


1 Answers

By default, I do not believe MVC will use the DependencyResolver to create the instance of your view model on postback. As such, it will only create a model with a parameterless constructor. This makes it less easy to initialize the object in the constructor.

You could create a custom model binder that created the objectt through DependencyResolver, but then you are deviating from normal practice.

I prefer to inialize my view models with AutoMapper.

like image 197
Erik Funkenbusch Avatar answered Oct 23 '22 12:10

Erik Funkenbusch