开发者

How to use ViewModel

Ok, after some research I was unable to understand the "viewmodel thing".

I didn't find any article that explains me what are the steps to work with ViewModels compared to simply passing the Entity as a Model to the View. When using the pure Entity it is pretty straight-forward:

If creating a new entry, just show the view. If is post, validate, do Add(x) and voilá! When editting, populate an object and send it to the View. When posting, validate, change the state and save. No secret here.

But I am unable to create and edit ViewModels. Can someone help me on this?

To be short, I have this POCOs :

public class Vessel
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public int ShipownerId { get; set; }
    public virtual Shipowner Shipowner { get; set; }
}

public class Shipowner
{
    public int Id { get; set; }

    public string Name { get; set; }


    public virtual ICollection<Vessel> Vessels { get; set; }
}

And this View:

@model INTREPWEB.Models.VesselCreateViewModel
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
    <fieldset>
        <legend>Vessel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Vessel.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Vessel.Name)
            @Html.ValidationMessageFor(model => model.Vessel.Name)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.Vessel.ShipownerId, Model.Shipowners, String.Empty)
            @Html.ValidationMessageFor(model => model.Vessel.Name)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

I've created this ViewModel:

public class VesselCreateViewModel
{
    public Vessel Vessel { get; set; }

    public SelectList Shipowners { get; set; }

    public VesselCreateViewModel()
    {
        using (INTREPDB db = new INTREPDB())
        {
            var list = db.Shipowners.ToList()
                .Select(x => new SelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString()
                });
            Shipowners = new SelectList(list, "Value", "Text");
        }
    }

    public VesselCreateViewModel(int id)
    {
        using (INTREPDB db = new INTREPDB())
        {

            Vessel = db.Vessels.Find(id);

            var list = db.Shipowners.ToList()
                .Select(x => new SelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString()
                });
            Shipowners = new SelectList(list, "Value", "Text");
        }
    }
}

As you can see, it auto populates a collection for the View to show a DropDown menu. I was able to create new Vessels by doing the same way I do with only Models. But can't figure out what I'm doing wrong when editting this thing.

This is the wrong POST Edit method:

    [HttpPost]
    public ActionResult Edit(VesselCreateViewModel vm)
    {
        if (Mode开发者_运维问答lState.IsValid)
        {
            db.Entry(vm.Vessel).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(vm);
    }

What should I do to save this little monster?


as you can see you are only using the Model-part of your ViewModel in this code. This is IMHO typical so you pass the ViewModel to the View but only bind the Model in your Edit-Postback.

Then you can easily recreate the viewmodel based on the changed model if you have to.

BTW: IMO ViewModel is a bad name in this case. If I hear ViewModel I think of MVVM but this case the viewmodel is only some kind of static-typed View-Helper and should have no behavior.


Viewmodel little excerpt from Steve senderson book

MVC also uses the term view model, but refers to a simple model class that is used only to pass data from 
a controller to a view. We differentiate between view models and domain models, which are sophisticated 
representations of data, operations, and rules.

If you want to save view model you may use automapper


I'm guessing you should wrap around the db calls in a Using block just like in the VesselCreateViewModel constructors.

You could eventually use commands in your ViewModel to save, edit or delete your data and bind this command to Buttons or other Controls on the view.

I would recommend you two great books about MVVM, you find good examples, easy to understand them too.

Building Enterprise Applications with Windows® Presentation Foundation and the Model View ViewModel Pattern

Pro WPF and Silverlight MVVM - Effective Application Development with Model-View-ViewModel

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜