views:

95

answers:

3

Let's say I have an edit view that is strongly-typed to a table called "MyData". The view has multiple tabs, each with several different fields from the table. For performance, the data is only loaded when the tab is viewed, so if you only edit a field on tab 1 and submit the form, the data for tab 2 will not be loaded.

The problem I'm running into is on the submit. I'm doing the typical routine of finding the existing record in the database and updating the passed values:

<AcceptVerbs(HttpVerbs.Post)> _
Function Edit(ByVal data As MyData) As ActionResult

    Using dc = New MyDataContext
        Dim orig = dc.MyDatas.Single(Function(x) x.id = data.id)
        orig.name = data.name
        orig.desc = data.desc
        ...
        SubmitChanges()
    End Using

    Return View(orig)

End Function

However, this method doesn't know which tabs were loaded, so if the tab with "desc" on it is not loaded, this method thinks the user blanked out the "desc" field, and sends NULL to the database.

How can I construct this so that only loaded fields are sent to the database, and unloaded fields are ignored?

+1  A: 

Is there any reason you're not using UpdateModel(orig)?

If you were using model binding, rather than manually going through the form contents and assigning the values, this would be taken care of for you. The default model binding behaviour is to ignore properties that have no corresponding form values.

You may want to take a look at this post, and the linked article in there, to learn more about model binding.

womp
I'm assuming you don't mean "UpdateModel(orig)", since that doesn't reference any of the form data, but how would I set that up from my original example? Would it be "UpdateModel(data)"? When I try that, I get an unhelpful "The model of type 'MyProject.MyData' was not successfully updated."
gfrizzle
A: 

Maybe a ViewModel pattern can help you here, where you part your original model like the tabs views something like:

public class Tab1 
    {
        public string pproperty1 { get; set; }
        public string pproperty2 { get; set; }
    }
    public class Tab2
    {
        public string pproperty3 { get; set; }
        public string pproperty4 { get; set; }
    }
    public class Tab3
    {
        public string pproperty5 { get; set; }
        public string pproperty6 { get; set; }
    }
    public class ViewModels
    {
        public Tab1 TAB1 { get; set; }
        public Tab2 TAB2 { get; set; }
        public Tab3 TAB3 { get; set; }
    }

So When you Bind the Posted values if the Tab2 == null then you know that this properties were not loaded neither changed by the user.

PD : Sorry for the c#, it been a time seen I vb coded.

Omar
A: 

I would recommend having a separate action method for each tab that just updates the fields on that tab. The form on each tab would then just submit to the appropriate action.

Eric Petroelje