views:

252

answers:

2

I'm using ASP.NET MVC (1.0), Spark View Engine (1.0) and SubSonic (3.0.0.3).

I'm having some trouble getting an "Edit" view to work correctly. So, in my controller, I have the following controller action that displays the edit form view:

[AcceptVerbs(HttpVerbs.Get)]
public virtual ActionResult Edit(string name)
{
    var plot = Plot.SingleOrDefault(p => p.UserID == LoggedInUser.ID && p.UrlFriendlyName == name);
    // ViewData["plot"] = plot;
    return View(plot);
}

The form on that view posts back to the following controller action:

[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Edit(Plot plot)
{
    var validator = new PlotValidator();
    try
    {
        var results = validator.Validate(plot);
        if (!results.IsValid)
        {
            ...
        }
    }
}

The problem that I'm having, is that the first controller action doesn't actually populate the form with the values from the Plot object submitted to it. The only way I can get it to populate the form is by adding the Plot to ViewData:

ViewData["plot"] = plot;

That populates the edit form, but when I edit the values, and submit it back to the second controller action listed above, it just sends back, basically a new plot with the new values, not the plot sent to the edit form with updated values.

I'm sure I'm probably just missing something simple, but I can't seem to figure out what it is. All of the fields on my form have IDs that are prefixed with "plot."

Anyone know/see what I'm doing wrong? Thanks.

+1  A: 

I don't know how it's done in the Spark view engine, but in the out-of-the-box view engine that comes with ASP.NET MVC, this is done by inheriting a strongly-typed view model object in the page using a page directive, rather than using the dictionary that comes with the plain-vanilla ViewPage.

So, instead of the first line of code in the view looking like this:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
 Inherits="System.Web.Mvc.ViewPage" %>

It will look more like this:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
     Inherits="System.Web.Mvc.ViewPage<HomePageViewModel>" %>

Your current controller code is expecting a strongly-typed object, but it is getting back a ViewData Dictionary instead. So no binding is occurring.

Consider reviewing the following podcast:

Exploring how to use ViewData (Strongly typed and weak typed) with Spark http://www.dimecasts.net/Casts/CastDetails/117

Robert Harvey
+1  A: 

Hey Robert - I don't know how Spark handles it's data, but I can tell you that the second part is pretty simple to fix.

First - you have to remember MVC won't reach into the DB for you. In your case your criteria for pulling out a record seems to involve two criteria - so you'll have to pull that again if you want to make sure the data is set properly. So on POST change your signature to this:

[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Edit(string id, FormCollection form)
{
//assuming you have some kind of PK
var plot = Plot.SingleOrDefault(p => p.ID == id);    
UpdateModel(plot, form.ToValueProvider());
var validator = new PlotValidator();
    try
    {
        var results = validator.Validate(plot);
        if (!results.IsValid)
        {
            ...
        }
    }
}

This is freehanded - but it's how you have to do it with L2S anyway...

Rob Conery
Yeah, I saw that in one of the Spark demo solutions (Northwind Demo I think) and I tried that, and for some reason, UpdateModel didn't seem to do anything. It didn't change the state of the plot at all, despite the fact that I could see that the form object had the expected data in it. I can't seem to get any of this stuff working as expected, which was why I figured it was just something I was missing.
Bob Yexley