No puedo entender, cómo utilizar TryUpdateModel y guardar la arquitectura MVC al mismo tiempo.

Si no me equivoco, el trabajo con datacontexts debe estar en el Modelo. Así que, dicho código

var db=new TestEverybody();//it is class, which was generated by EntityFramework 
var currentTesting=db.Testing.(t => t.id == id).First();

debe ser situada en el Modelo, no en el Controlador, ¿no es cierto?

Pero la ussual ejemplos de TryUpdateModel de uso es la siguiente:

    public ActionResult Edit(Testing obj)//Testing collection
    {
        var db = new TestEverybody();
        var currentTesting=db.Testing.(t => t.id == obj.id).First();
        TryUpdateModel(currentTesting);
        db.SaveChanges();            
        return RedirectToAction("Index");
    }

No de esta manera romper la arquitectura MVC? Trabajamos con base de datos en el controlador, no en el Modelo especial de la clase.

Así que, ¿cuál es la mejor manera de utilizar TryUpdateModel en un proyecto real?

  • Mi consejo, en un proyecto real, no la use. Usted debe utilizar la vista de modelos específicos y mapa entre las propiedades de su modelo de vista y los de las entidades que desea actualizar. TryUpdateModel/UpdateModel es codicioso y va a morder…eventualmente.
  • Es patrón MVVM? Donde puedo leer acerca de su método?
  • No, esto es MVC (bien hecho). He añadido una respuesta para explicar. Espero que esto ayude.
InformationsquelleAutor Sir Hally | 2011-10-12

2 Comentarios

  1. 114

    Desde la OP preguntó, he aquí un ejemplo de la Perspective patrón, o como me gusta llamarlo – ASP.NET MVC se hace correctamente.

    Así que ¿por qué utilizar una vista de modelo específico

    1. Sólo debe pasar la información a la vista que necesita.
    2. A menudo tendrás que añadir más vista-meta-datos (tales como el título/descripción de los atributos). Estos no pertenecen a las entidades.
    3. Utilizando TryUpdateModel/UpdateModel está mal. No uso (voy a explicar por qué).
    4. Es muy raro que su punto de vista-modelos de coincidir exactamente con las entidades. La gente a menudo terminan añadiendo resto de sus entidades o (no mucho mejor) usando sólo ViewBag en lugar de establecimiento inflexible de tipos de vista de las propiedades del modelo.
    5. Si usted está usando un ORM que se puede ejecutar en problemas con los Perezosos cargado de propiedades (N+1). Sus puntos de vista no deben emitir consultas.

    Vamos a empezar con una simple entidad:

    public class Product {
        public int Id {get;set;}
        public string Name {get;set;}
        public string Description {get;set;}
        public decimal Price {get;set;}
    }

    Y digamos que usted tiene un sencillo formulario donde el usuario puede sólo actualización de la Name y Description del producto. Pero usted está utilizando (el muy codicioso) TryUpdateModel.

    Así que el uso de cualquier número de herramientas (como Fiddler) para la construcción de un puesto a mí mismo y envíe el siguiente:

    Nombre=WhatverIWant&Description=UnluckyFool&Precio=0

    Bien el ASP.NET cuaderno de modelo MVC se va a inspeccionar el formulario de entrada de la colección, a ver que estas propiedades existen en su entidad y enlazar automáticamente para usted. Así que cuando usted llama «TryUpdateModel» en la entidad a la que usted acaba de recuperar de la base de datos, todas las propiedades coincidentes serán actualizados (incluyendo el Precio!). Tiempo para una nueva opción.

    Ver Modelo Específico

    public class EditProductViewModel {
        [HiddenInput]
        public Guid Id {get;set;}
    
        [Required]
        [DisplayName("Product Name")]
        public string Name {get;set;}
    
        [AllowHtml]
        [DataType(DataType.MultilineText)]
        public string Description {get;set;}
    }

    Este contiene sólo las propiedades que necesitamos en nuestro punto de vista. Aviso también hemos añadido algunos de validación de atributos, los atributos de la pantalla y algunos mvc atributos específicos.

    Por no ser restringidos en lo que tenemos en nuestra opinión, el modelo puede hacer que sus puntos de vista mucho más limpio. Por ejemplo, podríamos hacer todo nuestro formulario de edición al tener la siguiente en nuestra opinión:

    @Html.EditorFor(model => model)

    Mvc inspeccionar todos los atributos que hemos añadido a nuestro modelo de vista y automáticamente el alambre hasta la validación, las etiquetas y la correcta campos de entrada (es decir, un área de texto para la descripción).

    Publicar el formulario

    [HttpPost]
    public ActionResult EditProduct(EditProductViewModel model) {
    
        var product = repository.GetById(model.Id);
    
        if (product == null) {
            return HttpNotFound();
        }
    
        //input validation
        if (ModelState.IsValid) {
    
            //map the properties we **actually** want to update
            product.Name = model.Name;
            product.Description = model.Description;
    
            repository.Save(product);
    
            return RedirectToAction("index");
        }
    
        return View(model)
    }

    Es bastante obvio a partir de este código lo que hace. No tenemos ningún efectos indeseables cuando actualizamos nuestra entidad, ya que estamos explícitamente la configuración de las propiedades de nuestra entidad.

    Espero que esto explique la Vista-Modelo patrón suficiente para que usted desea utilizar.

    • Gracias. ¿Cuál es la mejor manera automática la asignación de propiedad? «modelo» sólo tiene el Nombre y la Descripción, así que Si intento usar ApplyCurrentValues, el precio será reemplazado por nulo, ¿no?
    • El común de la pregunta – cómo obtener el modelo de objeto de viewmodel objeto y el mapa de la viewmodel propiedades del modelo del uno? He tratado de evitar la asignación de «producto.Nombre = modelo.Nombre», porque el modelo contiene una gran cantidad de propiedades
    • Usted puede asignar automáticamente las propiedades de la entidad para su viewmodel el uso de algo como AutoMapper. En mi opinión (y la mayoría de la gente en la AutoMapper grupo) usted no debe mapa al revés (desde la perspective de regreso a su entidad) como una vez más, esto puede conducir a resultados inesperados.
    • Pero, ¿cómo puedo organizar la lógica de actualización en tal caso? De acuerdo a nuestro ejemplo, he viewModel con 3 propiedades (Id, Nombre, Descripción) y el modelo con 4 unidades (Id, nombre,Descripción, Precio). Por tanto, debo cambiar los viejos datos (Nombre y Descripción) en el Modelo, porque no puedo escribir método de Actualización para el viewModel, debido a que cada modelo puede tener un montón de viewModels. Así que, ¿cómo evitar la asignación de viewModel de vuelta a la modelo?
    • No entiendo la pregunta. No se puede evitar la asignación de la viewModel para el modelo, ni se debe. Ese fue el punto de los de arriba, para mostrar cómo se debe asignar entre una vista del modelo específico y de una entidad.
    • Sí, he de entender. Gracias!
    • +1 esta es una respuesta excelente y me ha ayudado a superar algunos de los problemas que estaba enfrentando con mi aplicación. Este siempre le pareció una gran cantidad de duplicación pero su respuesta demuestra por qué es una buena idea – que en realidad hace que la aplicación sea mucho más sencillo de desarrollar y mucho más fáciles de mantener.
    • ¿Cuál sería su consejo para ser acción de los métodos que devuelven una lista de entidades (E. G. productos)? Le recomiendo utilizar el enfoque de la I. E. regreso IEnumerable<ProductViewModel> o retorno IEnumerable<Producto>? Para que quede claro que estoy hablando de los métodos que responden a las solicitudes HTTP GET.
    • Usted debe devolver IEnumerable<ProductViewModel>.
    • Si AutoMapper está bien usar EF -> VM, ¿cómo puede no estar bien, a la inversa? O más bien, las mismas trampas de estas últimas existen en la antigua, ¿verdad? Así que si usted no convertir de VM -> EF ya que el exceso de propiedades pueden ponerse de mala gana, entonces seguramente los mismos problemas que existen en el reverso. Además, ya que usted está en control de su VM propiedades, es fácil que a nombre de ellos de manera diferente si no ellos quieren AutoMapped. Peor aún, el código repetitivo para la copia de propiedades de no vivir en los Controladores de todos modos, así que ahora tendrás 1 estrategia para la copia de VM -> EF, pero otra para EF -> VM. que feo
    • Si utiliza TryUpdateModel con una lista de cadenas para incluir/excluir, no de que retire la naturaleza agresiva de ella? No podría usted especificar también el enlace de atributo en el ActionResult parámetro para evitar la sobre-publicación? Que me guste más que de derecho las sentencias de asignación para cada propiedad para actualizar a como se hizo en el ejemplo.

  2. 19

    Así, dicho código debe estar situada en el Modelo, no en el Controlador, ¿no es cierto?

    No necesariamente. Personalmente prefiero poner código de acceso a datos en un repositorio. A continuación, utilice inyección de constructor a pasar algún repositorio específico de aplicación para el controlador (por ejemplo, si yo estaba usando EF, me gustaría escribir un EF repositorio de la aplicación). Por lo que el controlador tendrá este aspecto:

    public class HomeController: Controller
    {
        private readonly IMyRepository _repository;
        public HomeController(IMyRepository repository)
        {
            _repository = repository;
        }
    
        public ActionResult Edit(int id)
        {
            var currentTesting = _repository.GetTesting(id);
            TryUpdateModel(currentTesting);
            _repository.SaveChanges();            
            return RedirectToAction("Index");
        }
    }
    • Probablemente sería útil para mostrar (o explicar) cómo introducir el repositorio, ya MVC crea una instancia del controlador para usted. Esto es generalmente utilizado para las Pruebas con Burla, por lo que su Controlador puede crear una instancia de la ActulRepository en su constructor predeterminado. Sin embargo, novato devs podía mirar a esta y estará en una pérdida para saber cómo obtener su real Repo en _repository sin crear instancias a nivel local.
    • Estoy de acuerdo, como yo soy uno de ellos =)

Dejar respuesta

Please enter your comment!
Please enter your name here