model - tutorial - mvc c# windows forms ejemplo
Modelo que contiene una lista de modelos(MVC-3, Razor) (1)
Este problema me ha estado plagando durante dos días. Hay algunas publicaciones similares, pero ninguna que solucione mi problema por completo.
Usando MVC-3, sintaxis Razor:
- EDIT.cshtml -
@using (Html.BeginForm("Edit", "My", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<!-- Some fields... -->
<div class="editor-field">
@Html.TextAreaFor(m => m.LongDescription)
@Html.ValidationMessageFor(m => m.LongDescription)
</div>
<!-- Some more fields work... Including picture upload (summary).-->
<input name="button" type="submit" value="Add Picture" />
<!-- Picture Item display -->
@foreach(var thumbnail in Model.ThumbnailImagePathAndNames)
{
<img src="@Url.Content(@thumbnail.ThumbnailPicturePath)" alt="" width="200" />
@Html.RadioButtonFor(o=>o.SelectedImage, @thumbnail.ImageGUID) Primary Picture
<!-- Checkbox to mark for deletion -->
@Html.CheckBoxFor(o=>thumbnail.Delete) Delete ???????? <!---- Here is a problem - I don''t understand how this should work -->
}
<input id="Submit1" name="button" type="submit" value="Complete Edit!" />
}
- MyController.cs -
[HttpPost]
public ActionResult Edit(String button, HttpPostedFileBase file, MyMainModel model)
{
// if button = submit picture, work with picture here and break(long story)
// save model data
// if valid, save and redirect
// not valid or error, load up view like normal but with error messages
model.LoadThumbnails();
return View(model);
}
- MyMainModel.cs -
public class MyMainModel
{
// some properties...
public Guid? SelectedImage { get; set; }
[Display(Name = "Detailed Description")]
public String LongDescription { get; set; }
// some more properties....
// and finally my list of models
public IList<ThumbnailModel> ThumbnailImagePathAndNames { get; set; }
public void LoadThumbnails()
{
// load up initial thumbnail models
this.ThumbnailImagePathAndNames = new List<ThumbnailModel>(readDataService.GetThumbnailModels(this.SomeID));
}
}
- ThumbnailModels.cs -
public class ThumbnailModel
{
public Guid ImageGUID { get; set; }
public String FullSizePicturePath { get; set; }
public String ThumbnailPicturePath { get; set; }
public bool Delete { get; set; }
}
¿Entonces, cuál es el problema? Bueno, cuando la "Edición completa!" se presiona el botón, se llama a Editar de MyController, como se esperaba, con todos los datos de MyMainModle intactos ... excepto por la lista de MiniaturaModelo, que resulta ser nula.
¿Cómo se supone que se hará esto? He intentado muchos enfoques diferentes para esto, incluida la creación de una plantilla editable y el uso de EditFor (o => ... todo en vano (esto se volvió confuso ya que no sabía si se suponía que el EditFor era para toda la colección o simplemente un solo elemento en la colección, lo intenté de ambas formas). Todos solían funcionar hasta que añadí la complejidad de la casilla de verificación para su eliminación, por lo que necesitaba recuperar la lista de MiniaturasModelos para verificar el valor interno de la propiedad Eliminar.
Gracias a todos por leer e intentar entender esto.
[Descargo de responsabilidad: algunos nombres de variables y métodos se han cambiado para proteger el programa inocente. Se eliminó una gran cantidad de código y se reemplazó por un código de comentario.]
Aquí hay un ejemplo que he puesto para ilustrar algunos conceptos:
Modelo:
public class MyMainModel
{
public Guid? SelectedImage { get; set; }
public string LongDescription { get; set; }
public IEnumerable<ThumbnailModel> ThumbnailImagePathAndNames { get; set; }
public HttpPostedFileBase File { get; set; }
}
public class ThumbnailModel
{
public Guid ImageGUID { get; set; }
public bool Delete { get; set; }
}
Controlador:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyMainModel
{
// TODO: fetch from the repository instead of hardcoding
ThumbnailImagePathAndNames = new[]
{
new ThumbnailModel { ImageGUID = Guid.NewGuid() },
new ThumbnailModel { ImageGUID = Guid.NewGuid() },
new ThumbnailModel { ImageGUID = Guid.NewGuid() },
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyMainModel model)
{
... the model will be properly bound here
}
}
Ver:
@model AppName.Models.MyMainModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm("index", "home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="editor-field">
@Html.TextAreaFor(m => m.LongDescription)
@Html.ValidationMessageFor(m => m.LongDescription)
</div>
<input type="file" name="file" />
<!-- Use different names for the upload and complete submit
buttons so that you can distinguish which one was clicked
in the POST action
-->
<input name="upload" type="submit" value="Add Picture" />
@Html.EditorFor(x => x.ThumbnailImagePathAndNames)
<input name="complete" type="submit" value="Complete Edit!" />
}
Plantilla del editor: ( ~/Views/Home/EditorTemplates/ThumbnailModel.cshtml
):
@model AppName.Models.ThumbnailModel
<!-- Pass the image id as hidden field -->
@Html.HiddenFor(x => x.ImageGUID)
@Html.CheckBoxFor(x => x.Delete)