Supongamos que tengo ViewModel como
public class AnotherViewModel
{
public string Name { get; set; }
}
public class MyViewModel
{
public string Name { get; set; }
public AnotherViewModel Child { get; set; }
public AnotherViewModel Child2 { get; set; }
}
En la vista puedo renderizar un parcial con
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
En el parcial lo haré
<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>
Sin embargo, el problema es que ambos representarán name = "Name" mientras que yo necesito tener name = "Child.Name" para que la carpeta de modelos funcione correctamente. O, name = "Child2.Name" cuando renderizo la segunda propiedad usando la misma vista parcial.
¿Cómo hago para que mi vista parcial reconozca automáticamente el prefijo requerido? Puedo pasarlo como parámetro, pero esto es demasiado inconveniente. Esto es aún peor cuando quiero, por ejemplo, renderizarlo de forma recursiva. ¿Hay alguna manera de representar vistas parciales con un prefijo o, mejor aún, con la reconición automática de la expresión lambda de llamada para que
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
agregará automáticamente el "Niño" correcto. prefijo a las cadenas de nombre / identificación generadas?
Puedo aceptar cualquier solución, incluidos los motores de vista de terceros y las bibliotecas. De hecho, uso Spark View Engine ("resuelvo" el problema usando sus macros) y MvcContrib, pero no encontré una solución allí. XForms, InputBuilder, MVC v2: cualquier herramienta / conocimiento que proporcione esta funcionalidad será excelente.
Actualmente pienso en codificar esto yo mismo, pero parece una pérdida de tiempo, no puedo creer que estas cosas triviales no estén implementadas.
Pueden existir muchas soluciones manuales, y todas son bienvenidas. Por ejemplo, puedo forzar que mis parciales se basen en IPartialViewModel <T> {prefijo de cadena pública; Modelo T; }. Pero prefiero alguna solución existente / aprobada.
ACTUALIZACIÓN: hay una pregunta similar sin respuesta aquí .
helper.ViewData.TemplateInfo.HtmlFieldPrefix
en la forma de{oldprefix}.{newprefix}
new ViewDataDictionary(helper.ViewData)
connew ViewDataDictionary(((HtmlHelper)helper).ViewData)
. ¿Ves algún problema con eso?string oldPrefix = helper.ViewData.TemplateInfo.HtmlFieldPrefix; if (oldPrefix != "") name = oldPrefix + "." + name;
Hasta ahora, estaba buscando lo mismo que encontré en esta publicación reciente:
http://davybrion.com/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/
fuente
ViewDataDictionary
constructor que toma la corrienteViewData
, o perderá errores de estado del modelo, datos de validación, etc.Mi respuesta, basada en la respuesta de Mahmoud Moravej, incluido el comentario de Ivan Zlatev.
Editar: la respuesta de Mohamoud es incorrecta para la representación parcial anidada. Debe agregar el nuevo prefijo al prefijo anterior, solo si es necesario. Esto no quedó claro en las últimas respuestas (:
fuente
Usando MVC2 puedes lograr esto.
Aquí está la vista fuertemente tipada:
Aquí está la vista fuertemente tipada para la clase secundaria (que debe almacenarse en una subcarpeta del directorio de vistas llamada EditorTemplates):
Aquí está el controlador:
Aquí están las clases personalizadas:
Y la fuente de salida:
Ahora esto está completo. Establezca un punto de interrupción en la acción Crear controlador de publicación para verificar. Sin embargo, no use esto con listas porque no funcionará. Vea mi pregunta sobre el uso de EditorTemplates con IEnumerable para obtener más información al respecto.
fuente
Html.EditorFor
método para representar el formulario secundario. Esto es precisamente para lo que se supone que se usan las plantillas de editor. Esta debería ser la respuesta.Esta es una pregunta antigua, pero para cualquiera que llegue aquí en busca de una solución, considere usarla
EditorFor
, como se sugiere en un comentario en https://stackoverflow.com/a/29809907/456456 . Para pasar de una vista parcial a una plantilla de editor, siga estos pasos.Verifique que su vista parcial esté vinculada a ComplexType .
Mueva su vista parcial a una subcarpeta EditorTemplates de la carpeta de la vista actual, o a la carpeta Shared . Ahora es una plantilla de editor.
Cambiar
@Html.Partial("_PartialViewName", Model.ComplexType)
a@Html.EditorFor(m => m.ComplexType, "_EditorTemplateName")
. La plantilla del editor es opcional si es la única plantilla para el tipo complejo.Los elementos de entrada HTML se nombrarán automáticamente
ComplexType.Fieldname
.fuente
PartailFor para asp.net Core 2 en caso de que alguien lo necesite.
fuente
También encontré este problema y, después de mucho dolor, descubrí que era más fácil rediseñar mis interfaces de manera que no necesitaba publicar objetos de modelo anidados. Esto me obligó a cambiar los flujos de trabajo de mi interfaz: seguro que ahora requiero que el usuario haga en dos pasos lo que soñé hacer en uno, pero la facilidad de uso y la capacidad de mantenimiento del código del nuevo enfoque es de mayor valor para mí ahora.
Espero que esto ayude a algunos.
fuente
Puede agregar un ayudante para RenderPartial que toma el prefijo y lo coloca en ViewData.
Luego, un ayudante adicional que concatena el valor ViewData
y así en la vista ...
en el parcial ...
fuente
Como usted, agrego la propiedad Prefix (una cadena) a mis ViewModels que agrego antes de los nombres de entrada de mi modelo. (YAGNI previene lo siguiente)
Una solución más elegante podría ser un modelo de vista base que tenga esta propiedad y algunos HtmlHelpers que verifiquen si el modelo de vista se deriva de esta base y, de ser así, agregue el prefijo al nombre de entrada.
Espero que ayude,
Dan
fuente
¿Qué tal antes de llamar a RenderPartial?
Entonces en tu parcial tienes
fuente