asp.net-mvc-3 - vista - partial view mvc 5 c#
Usar una interfaz como tipo de modelo de una vista parcial+anotaciones de datos (3)
Mi idea no va a funcionar: este hilo me recordó que las clases no heredan atributos de sus interfaces. (Como lo señala la respuesta, ¿qué pasaría si dos interfaces especificaran la misma propiedad con diferentes atributos y ambas fueran implementadas por una clase?)
Podría funcionar con una clase base común. Voy a intentar eso mañana.
Gracias a todos.
Tengo un caso donde una vista parcial compleja necesita una validación diferente de los campos dependiendo de dónde se usa la vista parcial.
Pensé que podría evitar esto haciendo que la vista parcial tome una interfaz como el tipo de modelo e implemente dos modelos de vista diferentes basados en la interfaz. Las anotaciones de datos en los dos ViewModels serían diferentes. A continuación, proporcionaría una instancia del ViewModel correcto a la vista parcial.
Pero lo que estoy descubriendo es que las únicas anotaciones que se reconocen son las de la interfaz en sí. Los DA en la interfaz que implementa las clases de ViewModel se ignoran, aunque esos son los objetos que se pasan como modelos. Entonces mi plan no está funcionando.
¿Hay alguna forma de evitar esto? Un mejor enfoque? Preferiría no dividir la vista parcial en vistas separadas si puedo evitarla.
ETA: esta es una versión abreviada de la vista parcial, según lo solicitado:
@model IPerson
@Html.ValidationSummary(false)
<fieldset>
<table class="editForm">
<tr>
<td class="editor-label">
@Html.LabelFor(model => model.FirstName)
</td>
<td class="editor-field">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</td>
<td class="editor-label">
@Html.LabelFor(model => model.LastName)
</td>
<td class="editor-field">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</td>
</tr>
</table>
<fieldset>
La vista parcial real es bastante larga y tiene muchas declaraciones @if que gestionan la representación (o no) de secciones opcionales, pero no hace nada complicado.
Ann, tienes razón. Borré mi comentario No puede volver a publicar una interfaz en su vista. Sin embargo, no sé exactamente qué estás tratando de hacer ya que no puedo ver tu código. Tal vez algo como esto? Estoy pasando una interfaz a la vista, pero devolviéndola como la clase que estoy esperando. De nuevo, no estoy seguro de que la aplicación esté aquí.
Digamos que tienes clases como esta :
[MetadataType(typeof(PersonMetaData))]
public class Customer : IPerson {
public int ID { get; set; }
public string Name { get; set; }
[Display(Name = "Customer Name")]
public string CustomerName { get; set; }
}
public class Agent : IPerson {
public int ID { get; set; }
public string Name { get; set; }
}
public partial class PersonMetaData : IPerson {
[Required]
public int ID { get; set; }
[Required]
[Display(Name="Full Name")]
public string Name { get; set; }
}
public interface IPerson {
int ID { get; set; }
string Name { get; set; }
}
public interface IAgent {
int AgentType { get; set; }
}
public interface ICustomer {
int CustomerType { get; set; }
}
Su controlador se ve así :
public ActionResult InterfaceView() {
IPerson person = new Customer {
ID = 1
};
return View(person);
}
[HttpPost]
public ActionResult InterfaceView(Customer person) {
if (ModelState.IsValid) {
TempData["message"] = string.Format("You posted back Customer Name {0} with an ID of {1} for the name: {2}", person.CustomerName, person.ID, person.Name);
}
return View();
}
Y su vista se ve así :
@model DataTablesExample.Controllers.Customer
<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>
@if (@TempData["message"] != null) {
<p>@TempData["message"]</p>
}
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>IPerson</legend>
@Html.HiddenFor(model => model.ID)
<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>
<div class="editor-label">
@Html.LabelFor(model => model.CustomerName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CustomerName)
@Html.ValidationMessageFor(model => model.CustomerName)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Bueno, ¡en realidad tienes una idea muy razonable! y puede archivarse si utiliza la versión no genérica de los métodos HtmlHelper (por ejemplo, "@ Html.Editor" en lugar de "@ Html.EditorFor"), porque las versiones genéricas vuelven a crear el ModelMetadata (no sé por qué). basado en el tipo de parámetro genérico y no use los metadatos de modelo de la vista. Freaking horrible, ¿no?
Espero que esto ayude.