Pregunta

He simplificado escenario de prueba útiles para hacer esta pregunta:Un Producto puede tener muchos Componentes, un Componente puede pertenecer a muchos Productos.EF generan las clases, he adelgazado ellos de la siguiente manera:

public partial class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Component> Components { get; set; }
}
public partial class Component
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

La creación de un componente se logra a través de estas acciones de controlador:

public ActionResult Create(int ProductId)
{
    Product p = db.Products.Find(ProductId);
    Component c = new Component();
    c.Products.Add(p);
    return PartialView(c);
} 

[HttpPost]
public ActionResult Create(Component model)
{
    db.Components.Add(model);
    db.SaveChanges();
}

y la vista devuelto por el método GET se parece a esto:

@model Test.Models.Product

<fieldset>
    <legend>Product</legend>
    <div class="display-label">Name</div>
    <div class="display-field">@Model.Name</div>
</fieldset>

@Html.Action("Create", "Component", new {ProductId = Model.Id}) 
<p>
    @Html.ActionLink("Edit", "Edit", new { id=Model.Id }) |
    @Html.ActionLink("Back to List", "Index")
</p>

A partir de la cual se puede ver que la creación de componentes que se maneja en la misma página a través de la de arriba Html.Action - el código para que a la vista de la siguiente manera:

@model Test.Models.Component
@using Test.Models

<script type="text/javascript">
    function Success() {
        alert('ok');
    }
    function Failure() {
        alert('err');
    }
</script>
@using (Ajax.BeginForm("Create", "Component", new AjaxOptions
{
    HttpMethod = "Post",
    OnSuccess = "Success",
    OnFailure = "Failure"
}))
{
    <fieldset>
        <legend>Components</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        @Html.HiddenFor(x => x.Products.First().Id)
        @Html.HiddenFor(x => x.Products)
        @foreach (Product p in Model.Products)
        {
            @Html.Hidden("Products[0].Id", p.Id)
        }
        @foreach (Product p in Model.Products)
        {
            @Html.Hidden("[0].Id", p.Id)
        }
    </fieldset>
    <input type="submit" value="go" />
}

ok.esto es lo que yo estoy luchando con:Necesito el model parámetro de la [HttpPost]volver a obtener correctamente pobladas, es decir,debe contener un Producto, ya que no se puede crear el nuevo componente con un valor nulo del producto.Para obtener el producto que necesita para buscar a través de los productos de la id.Espero que debo ser capaz de hacer:

model.Products.Add(db.Products.Find(model.Products.First().Id));

o algo parecido, que se basa en model la recepción de la id.Esto significa que la vista tiene que colocar el id de allí, presumiblemente en un campo oculto, y como puede ser visto desde mi punto de vista código, he hecho varios intentos en los que pueblan este, todos los cuales han fracasado.

Normalmente prefiero el *Para los métodos ya que se convierten en responsables de la generación de corregir la nomenclatura.Si .Los productos fueron singular.Producto), podría hacer referencia a ella como x => x.Product.Id y todo estaría bien, pero ya que es plural, que yo no puedo hacer x => x.Products.Id así que he intentado x => x.Products.First().Id que compila y genera el valor correcto, pero se pone el nombre Id (lo cual es incorrecto ya que el modelo de cuaderno piensa que es Component.Id y no Component.Products[0].Id.

Mi segundo intento fue dejar HiddenFor iterate (como lo haría con EditorFor):

@Html.HiddenFor(x => x.Products)

pero que no produce nada - he leído que este helper no repetir.He intentado x => x.Products.First() pero eso no incluso compilar.Finalmente, decidí abandonar el *Para el código y el nombre del mismo:

@foreach (Product p in Model.Products)
{
    @Html.Hidden("Products[0].Id", p.Id)

y a pesar de que se ve a la derecha, la devolución no ver mi valor (Products.Count == 0).He visto en algún anuncio de que el formato debe verse como [0].Id pero eso no funciona bien.grr...

Deduzco que podía código como este:

@Html.Hidden("ProductId", p.Id)

y, a continuación, se mi controlador de acción como esta:

[HttpPost] ActionResult Create(Component model, int ProductId)

pero que parece eecky.es difícil creer que esto es tan difícil.alguien puede ayudar?

  • e

p.s.Tengo un proyecto en el que me podría poner a disposición para su descarga si alguien se preocupa

¿Fue útil?

Solución

En lugar de escribir los foreach los bucles de tratar de usar el editor de plantillas:

<fieldset>
    <legend>Components</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>

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

    @Html.EditorFor(x => x.Products)
</fieldset>

y dentro de la correspondiente editor de plantilla (~/Views/Shared/EditorTemplates/Product.cshtml)

@model Product
@Html.HiddenFor(x => x.Id)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top