开发者

Is there a way to update a ViewModel in MVC2?

开发者 https://www.devze.com 2022-12-21 10:48 出处:网络
This code works: [HttpPost] public ActionResult Edit(int id, FormCollection fc) { Movie movie = ( from m in _ctx.Movie.Include(\"MovieActors\")

This code works:

[HttpPost]
public ActionResult Edit(int id, FormCollection fc)
{
    Movie movie =
        (
            from m in _ctx.Movie.Include("MovieActors")
                where m.MovieID == id select m
        ).First();
    MovieActorViewModel movieActor = new MovieActorViewModel(movie);

    if (TryUpdateModel(movieActor))
    {
        _ctx.ApplyPropertyChanges(movieActor.Movie.EntityKey.EntitySetName,
            movieActor.Movie);
        _ctx.SaveChanges();
    }

    return View(movieActor);
}

However, I am not sure how to test this, and in general would much rather have the method take a typed model like:

[HttpPost]
public ActionResult Edit(MovieActorViewModel movieActor)

Is this possible? What changes to my MovieActorViewModel class do I need to make in order to enable this? That class looks like this:

public class MovieActorViewModel
{
    public Movie Movie { get; set; }
    public Actor Actor { get; set; }

    public PublisherDealViewModel(Movie movie)
    {
        this.Movie = movie;
        this.Actor =
            (
                from a in 开发者_JAVA技巧this.Movie.Actors
                    where a.ActorID == 1 select a
            ).First();
    }
}

The view is typed (inherits ViewPage) simple:

<% using (Html.BeginForm()) {%>
    Movie Title: <%= Html.TextBoxFor(model=>model.Movie.Title) %><br/>
    Actor Name: <%= Html.TextBoxFor(model=>model.Actor.Name) %>
<% } %>


It's absolutely possible. The default binder in MVC2 will attempt to bind the values in the form that is posted to the action based on the names of the fields in the form. If you are using helpers like Html.TextBoxFor() and the names of your Model match up properly, the values in the model should be automagically populated.

If, however, the names in your form don't match up perfectly to the properties on your ViewModel, you may have to do some tweaking. You can use the BindAttribute to customize the way binding happens, to some degree:

public ActionResult SomeAction([Bind(Prefix="MyEntity" Include="Property1,Property2)] MyEntityModel someEntity)

BindAttribute allows you to specify which properties you want bound, and you can use the Exclude parameter to explicitly exclude some from binding. If you want to bind properties from the form to properties of a complex object in your ViewModel (i.e. MyViewModel.MyDataObject) then Prefix can be used. Your form names will be "MyDataObject.FirstName" when you use the strongly-typed helpers in that case. Prefix allows you to specify a prefix for the form field names.

You can also define totally custom Binders. Jimmy Board of LosTechies has a blog post about this.


When you are creating a View, check "Create a strongly-typed view", and select MovieActorViewModel as View data class. And in this case you might want "Edit" as your View content type.


Ok, this is weird, and might be related to the specific MVC version installed on my machine... (v2.0.0.0 from the RC1 installation), but I actually solved this by renaming the properties from

public Movie Movie { get; set; }
public Actor Actor { get; set; }

to

public Movie TheMovie { get; set; }
public Actor TheActor { get; set; }

seems like the default binder gets confused when the prop name is the same as the class name?

0

精彩评论

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