Question

Is there a pre-built ModelBinder I can use with LINQ to get an object from a DataContext and update it on a HTTP post?

For example, currently I have this block of code:

[AcceptVerbs (HttpVerbs.Post)]
public ActionResult Edit (Project project)
{
    var projectService = Factory.GetService<IProjectService> ();
    project = projectService.GetProject (project.ProjectId);

    UpdateModel<Project> (project);

    if (!ModelState.IsValid)
        return View (project);

    project = projectService.SaveProject (project);

    return RedirectToAction ("Details", new { id = project.ProjectId });
}

(IProjectService wraps up calls to a LINQ data context)

In order to actually perform the update to the database via the LINQ data context, I need to get the project instance again and then update that instance.

Any attempt to simply save the project instance without first getting it from the data context results in nothing being written back to the database - I'm assuming because the LINQ data context knows nothing of the object it doesn't do anything with it.

Using the Attach method on the Projects table class doesn't work either btw, it throws an exception.

Was it helpful?

Solution

You should look at the implementation in Mike Hadlow's (new BSD) SutekiShop.

In there you will find a DataBindAttribute and BindUsingAttribute which, if I understand correctly, do exactly what you want to do. Notice how the DataBindAttribute.Fetch property is used to rebind the incoming data, or not, (from an HttpPost) to a LINQ entity.

I followed this pattern for one of my projects using ASP.NET MVC and LINQ-To-SQL. It works beautifully.

Here's the source: http://www.google.com/codesearch?hl=en&lr=&q=DataBind+package%3Ahttp%3A%2F%2Fsutekishop.googlecode.com&sbtn=Search

OTHER TIPS

I think the project you pass in to the method is the one you want to perform UpdateModel with isn't it?

Otherwise you are trying to update with pre-existing values not new ones.

Just a thought,

Dan

Code cut out below

[AcceptVerbs (HttpVerbs.Post)]
public ActionResult Edit (Project project)

    UpdateModel<Project> (project);

    if (!ModelState.IsValid)
            return View (project);

    var projectService = Factory.GetService<IProjectService> ();

    project = projectService.SaveProject (project);

    return RedirectToAction ("Details", new { id = project.ProjectId });
}

You need to retrieve the original project as you do then to update it with the properties that have changed in project to update then to submit the update request.

EDIT

Try this code I found:

public static void CloneProperties(this object origin, ref object destination)
{ 
    if (destination == null) throw new ArgumentNullException("destination", "Destination object must first be instantiated."); 
    foreach (var destinationProperty in destination.GetType().GetProperties()) 
    {
       if (origin != null && destinationProperty.CanWrite) 
       { 
          origin.GetType().GetProperties().Where(x => x.CanRead && (x.Name == destinationProperty.Name && x.PropertyType == destinationProperty.PropertyType)) .ToList() .ForEach(x => destinationProperty.SetValue(destination, x.GetValue(origin, null), null)); 
       } 
    } 
} 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top