开发者

.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;开发者_JS百科 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.


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.


Generally speaking you want heavy models and light controllers, so you do as little as possible in your controller.

General design pattern reasons you should initialize the ViewModel in the view model?

  • DRY - if you have more than one action which has to initialize the ViewModel, you're wither repeating that code, or you're putting it in a private method in the controller. To me, if you need to put a private method in a controller it's a fairly strong indication that code doesn't belong in the controller at all.
  • cohesion -- In general, a Foo object should know how to instantiate a Foo object from some other object, because it has responsibility for knowing about itself. Putting that logic somewhere else reduces cohesion and introduces coupling.


I am always using the 2nd approach but with a "all-properties as parameters"-contructor instead of inserting "Foobar" to the constructor ( kind of a violation of the MVVM pattern, as the ViewModel should stay independent ).

For me it's best practice because you can hide additional logic in the viewmodel and you have the possibility to create different behaviour by using different constructors.


I think you've done a nice job in the second case. In my opinion, getting an object ready for use is the responsibility of that object itself.

What if you need another instance of that class somewhere else? You'd have to copy the initialization code from wherever you created it first.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜