2011-01-28 32 views
15

Esto quizás sea muy simple, pero parece que no puedo resolverlo por mi cuenta. He creado un simple modal db y la entidad que tiene este aspectomenú desplegable en mvc3 editar formulario

enter image description here

Estoy tratando de crear un crear la forma que me permite añadir una nueva Orden. Tengo un total de 3 tablas, entonces lo que trato de hacer es tener el formulario que permite a la persona ingresar la fecha del pedido y también una lista desplegable que me permite seleccionar un producto de la tabla del producto

Quiero ser capaz de crear una vista Agregar o Editar que me permita insertar el Fecha de pedido en la Tabla de pedidos y también insertar el ID de pedido y el ID de producto seleccionado en OrderProduct.

¿Qué pasos tengo que hacer aquí.

He creado una OrderController y marcado "Agregar acciones" y que añade un CREATE VIEW que se parece a este

@model Test.OrderProduct 

@{ 
    ViewBag.Title = "Create2"; 
} 

    <h2>Create2</h2> 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>OrderProduct</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.OrderID) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.OrderID) 
      @Html.ValidationMessageFor(model => model.OrderID) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.ProductID) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.ProductID) 
      @Html.ValidationMessageFor(model => model.ProductID) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

Esto crea la vista que contiene un cuadro de texto para ambos IdPedido y ProductID sin embargo no hay fecha.

Mi controlador ya no haya sido cambiada CreatePost

[HttpPost] 
    public ActionResult Create(FormCollection collection) 
    { 
     try 
     { 
      var data = collection; 
      // TODO: Add insert logic here 
      // db.Orders.AddObject(collection); 
      return RedirectToAction("Index"); 
     } 
     catch 
     { 
      return View(); 
     } 
    } 

Mis preguntas son,

¿1.How intercambiar ProductID cuadro de texto a ser un desplegable que se rellena a partir del producto 2.How puedo obtener los datos de la colección FormCollection? Pensé en sólo un foreach sin embargo yo no sé cómo obtener el nombre inflexible

Cualquier ayuda para un novato sería muy útil.

¡Gracias!

+0

Es curioso que esta es la pregunta exacta que tengo en este momento, y sin embargo nadie ha respondido aquí. Pensé que los yonquis de MVC habrían saltado en esto en 2 segundos planos. –

Respuesta

25

Lo primero es lo primero, no se una a la entidad de orden. Nunca se vincule a un objeto EF, siempre intente y use un ViewModel. Hace la vida más simple para View, y ese es el objetivo aquí.

Por lo tanto, tienen un modelo de vista así:

public class CreateOrderViewModel 
{ 
    public int OrderId { get; set; } 
    public DateTime OrderDate { get; set; } 
    public int SelectedProductId { get; set; } 
    public IEnumerable<SelectListItem> Products { get; set; } 
} 

Eso es todo en este momento.

retorno que a la vista de su acción [HttpGet] controlador:

[HttpGet] 
public ActionResult Create() 
{ 
    var model = new CreateOrderViewModel 
    { 
     Products = db.Products 
        .ToList() // this will fire a query, basically SELECT * FROM Products 
        .Select(x => new SelectListItem 
        { 
         Text = x.ProductName, 
         Value = x.ProductId 
        }); 
    }; 

    return View(model); 
} 

A continuación, para hacer la lista de los productos: (HTML básico excluido)

@model WebApplication.Models.CreateOrderViewModel 

@Html.DropDownListFor(model => model.SelectedProductId, Model.Products) 

La única cosa que no hago saber cómo hacerlo es vincular al campo DateTime. Supongo que necesitarías un método de extensión (HTML Helper) que da como resultado un Selector de Fecha o algo así. Para esta Vista (crear una nueva orden), simplemente por defecto a DateTime.Now.

Ahora, en la acción [HttpPost] controlador:

[HttpPost] 
public ActionResult Create(CreateOrderViewModel model) 
{ 
    try 
    { 
     // TODO: this manual stitching should be replaced with AutoMapper 
     var newOrder = new Order 
     { 
     OrderDate = DateTime.Now, 
     OrderProduct = new OrderProduct 
     { 
      ProductId = SelectedProductId 
     } 
     }; 

     db.Orders.AddObject(newOrder); 
     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

Ahora, yo también creo que su modelo de EF necesita trabajo.

Para mí (en inglés), un producto puede tener muchos pedidos y un pedido puede tener muchos productos.

Por lo tanto, debe ser un muchos-a-muchos. Actualmente es un 1-1 con una tabla de combinación redundante. ¿Lo generó desde un DB? Si es así, su DB posiblemente necesite trabajo.

usted debe tener una propiedad de navegación llamado productos en la Orden de entidad, que hace referencia a una colección de Producto, posible gracias a un silencio unirse a la mesa de unirse a la de muchos a muchos.

Esto también significa que ya no tiene una DropDownList, sino una MultiSelectDropDownList.

+0

en el método '[HttpGet]' anterior, sigo obteniendo un error diciéndome que no puedo convertir imp en cadena para el valor 'value = x.id' bit! Agregué un 'ToString()' pero luego recibí este error: Error No se puede convertir implícitamente el tipo 'System.Collections.Generic.IEnumerable ' en 'System.Collections.Generic.IEnumerable '. Existe una conversión explícita (¿falta un molde?) – Ben

+0

@Ben - lo más probable es que falte una referencia de uso – RPM1984

+0

@ RPM1984 ¿Podría explicar por qué no enlazar directamente a EF? ¿Cual es la razon? Si uno lo mira, parece más simple, las anotaciones son respetadas y todo. – Anderson

1

He estado luchando con esto durante el último día o dos también. Compartiré mi conocimiento limitado con la esperanza de que ayudará a alguien más.

Nota que utilizo un singleton con una lista pre-poblado para mantener mi aplicación de ejemplo pequeña (es decir, no EF o interacción DB).

Para mostrar la lista de productos que tendrá que tener un ViewBag o elemento ViewData que contiene la lista de productos. Puede configurar esta opción en el controlador con algo como

ViewData["ProductList"] = new SelectList(Models.MVCProduct.Instance.ProductList, "Id", "Name", 1); 

A continuación, actualice la vista a algo como:

<div class="editor-field">@Html.DropDownList("ProductList")</div> 

para el puesto/Crear paso/de actualización que hay que buscar en el FormCollection a obtiene tus resultados Leer otras publicaciones parece que solía haber un error aquí, pero ahora está solucionado, así que asegúrese de tener lo último. Para mi ejemplo, tengo una DropDownList para Producto, así que solo obtengo el Id seleccionado y luego voy a buscar ese Producto en mi lista.

[HttpPost] 
    public ActionResult Create(FormCollection form)//Models.MVCOrder newOrder) 
    { 

     MVC.Models.MVCOrder ord = Models.MVCOrder.Instance.CreateBlankOrder(); 
     //Update order with simple types (e.g. Quantity) 
     if (TryUpdateModel<MVC.Models.MVCOrder>(ord, form.ToValueProvider())) 
     { 
      ord.Product = Models.MVCProduct.Instance.ProductList.Find(p => p.Id == int.Parse(form.GetValue("ProductList").AttemptedValue)); 
      ord.Attribute = Models.MVCAttribute.Instance.AttributeList.Find(a => a.Id == int.Parse(form.GetValue("attributeId").AttemptedValue)); 
      UpdateModel(ord); 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      return View(ord); 
     } 
    } 

Solo he estado trabajando en MVC3 durante los últimos días, por lo que cualquier consejo sobre la mejora de lo anterior sería apreciado.

2

Gracias Craig. Sus pocos días (como en el momento de la publicación) de MVC han resuelto mis pocos días de intentar recuperar el valor seleccionado de DropDownListFor.

No tuve ningún problema en la vista Crear para obtener el valor seleccionado de la DDLF, pero la vista Editar fue completamente diferente; nada de lo que intenté devolvió el valor seleccionado a la Publicación. Noté que el valor seleccionado estaba al acecho en AttemptedValue of the ModelState, por lo que Dr.Google me remitió aquí.

Tenía esta en mi opinión

@Html.DropDownList(model => model.ContentKeyID, Model.ContentKeys, Model.ContentKeyName) 

donde ContentKeys es un SelectList poblada de la BD a través de un modelo de vista, y ContentKeyName es el nombre Curently seleccionado.

Lo extraño es que tengo otra DDL en la vista poblada de manera idéntica. Este funciona Por qué, no sé. Es el segundo DDL en el formulario, pero no puedo ver eso haciendo una diferencia.

He leído en otro lugar que podría haber sido que estaba usando Guids como Id, pero eso no pareció marcar la diferencia - Cambié a Int32, pero no creo que tuviera que hacerlo - Creo que es enumeraciones que no están de acuerdo con DDLF. Nullables parece no hacer ninguna diferencia tampoco.

Ahora que he añadido la colección forma a mi puesto ActionResult, y obtener el valor seleccionado mediante

-view

@Html.DropDownList("ContentKey", Model.ContentKeys) 

controlador -en (Mensaje)

contentKeyId = int.Parse(form.GetValue("ContentKey").AttemptedValue); 

todo es bueno, y puedo continuar con cosas más emocionantes. ¿Por qué las cosas más simples pueden mantenerte así por tanto tiempo?

Cuestiones relacionadas