Do not update property in BBDD from Controller

1

I need to show in a View (Web form) a property of the Data Model that comes from a DB and that after performing the Submit, the Controller's action does not perform the Update on those fields in the DB but with the rest of properties of the Model.

I've tried with the [Bind(Exclude="prop1, pro2")] and it does not work, I update the values to NULL.

I need the update on those fields in the database not to be carried out since a process in the background can modify those values and then they would be 'crushed'.

Is there a way to update only the fields I need and not all?

EDIT

I use MVC v5 and EntityFramework v6.

I think the solution would be to use the DbContext.Entry(model).Property(x => x.property).IsModified = false; method.

The problem is that I have detected that I am using a DbContext 'private', derived from the original EntityFramework and the use of this method Entry is not implemented: (

I'll have to ignore that problem and update the fields since you can not modify the DbContext 'private'.

Thank you.

    
asked by MA Prado 11.05.2016 в 12:08
source

3 answers

0

Please do not use the Entity Framework models like the MVC Model.

The reason is that you are leaving the possibility to an attack known as Overposting, which is when a request is modified to send values of more fields than the user interface allows and ends with the possible modification of undesired values.

It is true that one of the ways is to use the attribute [Bind] to choose which fields you want to exclude but this is a fragile solution because:

  • Fields are specified as string . It is not strongly typed and is susceptible to typing and desynchronization errors if the names of the properties are changed
  • Responsibilities are being mixed between the Entity Framework "entity" whose responsibility is persistence, and the MVC view model whose responsibility is to transport information to and from the view.
  • The best recommendation that I can give you is to create a viewmodel , that is, a specific model for the view and that in the controller or in another class below you do the update of the EF model.

    Super-simplified example:

    EF Entity:

    public class Empleado
    {
        public int ID { get; set; }
        public string Nombre { get; set; }
        public int Sueldo { get; set; } //Este campo no debe ser actualizado
        //... mas campos
    }
    

    ViewModels:

    public class EmpleadoViewModel
    {
        //Solo los campos que quiero mostrar en la vista
        public int ID { get; set; }
        public string Nombre { get; set; }
        public int Sueldo { get; set; } 
    }
    
    public class EmpleadoPostViewModel
    {
        //Solo los campos que quiero actualizar
        public int ID { get; set; }
        public string Nombre { get; set; }
    }
    

    Action Get:

    public ActionResult GetEmpleado(int id)
    {
        var empleado = _db.Empleados.Find(id);
    
        return View(new EmpleadoViewModel {
            ID = empleado.ID,
            Nombre = empleado.Nombre
        });
    }
    

    Action Post:

    [HttpPost]
    public ActionResult SaveEmpelado(EmpleadoPostViewModel empleadoActualizado)
    {
        var empleadoBD = _db.Empleados.Find(empleado.ID);
    
        empleadoBD.Nombre = empleadoActualizado.Nombre;
    
       _db.SaveChanges();        
    
        return RedirectToAction("ActionAlCualRedirigir");
    }
    
        
    answered by 11.05.2016 / 17:40
    source
    1

    But you do not need any attribute of [Bind()] , by default if the property name of the control in the view maps to the property of the class is assigned directly

    using(@Html.BeginForm()){
    
       <input type="text" name="prop1" />
       <input type="submit" value="Guardar" />
    
    }
    

    In the controller

    public class xxController : Controller {
    
       //otros action
    
       [HttpPost]
       public ActuonResult Index(xxModel model){
    
       }
    }
    

    The model class

    public class xxModel
    {
        public string prop1 {get;set;}
    }
    

    As you will see if the name of the textbox matches the name of the model class that you define in the action dodne the submit is done the binding is direct, you do not need any attribute

        
    answered by 11.05.2016 в 15:44
    0

    Maybe you should use the contario attribute (include all the properties you want to update), for example:

    public ActionResult Edit([Bind(Include="prop1, prop2, prop3")] TU_CLASE clase)
    {
        if (ModelState.IsValid)
        {
            db.Entry(clase).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(clase);
    }
    
        
    answered by 11.05.2016 в 15:32