Modeling database objects in ASPNET MVC

I am having trouble trying to think that the best way is to recreate the database object in the controller action.

I want to use ModelBinders, so in my action I have access to the object through the parameter, instead of having to repeat the code to get the object from the database based on the identifier parameter. Therefore, I thought about ModelBinder making a data-level call to get the original object (or creating a new one if it does not exist in the database), and then associating any properties with the database object to update it. However, I read that ModelBinders should not make database queries (first comment of this article ).

If the ModelBinder does not have to execute the database query (so just use DefaultModelBinder), then what about database objects that have properties that are other db objects? They will never be assigned.

Saving the object after the user has edited it (properties 1 or 2 are edited in the view), there will be no data for the ModelBinded object, so saving it like this will cause the data in the database to be overwritten with invalid values, or NOT-NULL.

So what is the best way to get an object in a controller action from a database associated with form data submitted back from a view?

Pay attention to the use of NHibernate.

+5
4

, UpdateModel ( TryUpdateModel) .

public ActionResult Update( int id )
{
     DataContext dc = new DataContext();
     MyModel model = dc.MyModels.Where( m => m.ID == id ).SingleOrDefault();

     string[] whitelist = new string[] { "Name", "Property1", "Property2" };

     if (!TryUpdateModel( model, whitelist )) {
        ... model error handling...
        return View("Edit");
     }

     ViewData.Model = model;

     return View("Show");
}
+4

, , .

, :

public class ProductBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, 
        ModelBindingContext bindingContext, Type modelType)
    {
        if(modelType != typeof(Product))
            return null;

        var form = controllerContext.HttpContext.Request.Form;
        int id = Int32.Parse(form["Id"]);
        if(id == 0)
            return base.CreateModel(controllerContext, bindingContext, modelType);

        IProductRepository repository = ServiceLocator.Resolve<IProductRepository>();

        return repository.Fetch(id);                                    
    }       
}

, , .

Global.asax:

ModelBinders.Binders.Add(typeof(Product), new ProductBinder());

:

public ActionResult Save([Bind] Product product)
{
    ....

    _repository.Save(product);
}
+2

, ModelBinders, Separation Concern ModelBinders , , .
(DRY), / , ,

global.asax.cs MyModelBinderProvider MVC

ModelBinderProviders.BinderProviders.Add(new EntityModelBinderProvider 
{ 
     ConnectionString = "my connection string"
));

ModelBinderProvider

public class EntityBinderProvider: IModelBinderProvider
{
    public string ConnectionString { get; set; }

    public IModelBinder GetBinder(Type modelType)
    {
        if (Is known entity)
            return new EntityBinder(ConnectionString);
        else
            return null;
    }
}

Ben Scheirman

0

You really don't need to hit the database. Just setting the identifier of the objects will be enough to establish a connection up, but watch your cascades. Make sure your cascode settings will not update the associated object as it will clear the values.

-1
source

All Articles