Motor de vista de Razor - ¿Cómo puedo agregar vistas parciales?

84

Me preguntaba cuál, si es posible, es la mejor manera de renderizar un parcial usando el nuevo motor de vista de afeitar. Entiendo que esto es algo que no se terminó por completo cuando

En este momento estoy usando RenderPage para representar el control de usuario:

@RenderPage("~/Views/Shared/LocaleUserControl.cshtml",ViewData.Model)

La página que llama a RenderPage utiliza una página de diseño (maestra) con tres secciones definidas: TitleContent, HeadContent y Maincontent. Cuando intento representar mi control de configuración regional desde esta página, parece que estas secciones también son necesarias; solo deberían ser necesarias en la página de llamada y están presentes. Recibo el siguiente mensaje, independientemente de si incluyo o no las secciones en mi vista parcial (obviamente no quiero incluir estas secciones pero me pareció un punto de depuración interesante ...).

Las siguientes secciones se han definido pero no se han representado en la página de diseño '~ / Views / Shared / LocaleUserControl.cshtml': TitleContent; HeadContent; Contenido principal

Mi vista parcial es la siguiente (adaptada del siguiente enlace ):

@inherits System.Web.Mvc.WebViewPage<LocaleBaseModel>
@using System.Web.UI;

<p>
     @Html.LabelFor(model => Model.CountryName)
    <br />
    @Html.DropDownListFor(model => Model.CountryName,null, string.Empty, new { @class = "text", accesskey="u"})
</p>
<p>
     @Html.LabelFor(model => Model.StateProvince)
    <br />
     @Html.DropDownListFor(model => Model.StateProvince, null, string.Empty, new { @class = "text", accesskey="t" })
</p>


<script type="text/javascript">
    $(function () {
        var countries = $("#CountryName");
        var statesprovinces = $("#StateProvince");
        countries.change(function () {
            statesprovinces.find('option').remove();
            var url = '@Url.Action("GetStatesProvinces", "Base")';
            $.getJSON(url, { countryId: countries.val() }, function (data) {
                $(data).each(function () {
                    $("<option value=" + this.ID + ">" + this.Name + "</option>").appendTo(statesprovinces);
                });
            });
        });
    });
</script>
JP.
fuente

Respuestas:

125

Su parcial se parece mucho a una plantilla de editor, por lo que podría incluirlo como tal (asumiendo, por supuesto, que su parcial se coloca en la ~/views/controllername/EditorTemplatessubcarpeta):

@Html.EditorFor(model => model.SomePropertyOfTypeLocaleBaseModel)

O si este no es el caso simplemente:

@Html.Partial("nameOfPartial", Model)
Darin Dimitrov
fuente
Gracias por los comentarios ... Html.EditorFor puede ser una buena idea en este caso, pero me interesaría ver alternativas, ya que este no es el caso para ejemplos más complejos, definitivamente volveré a encontrarme con esto pronto. Html.Partial no funcionará ya que debe derivar de ViewPage o ViewUserControl, mientras que el parcial de la maquinilla de afeitar se deriva de WebViewPage ...
JP.
4
Html.Partial funciona perfectamente bien. Inicie un nuevo proyecto ASP.NET MVC 3 en Visual Studio usando el motor de vista Razor, abra el _Layout.cshtml archivo en la Sharedcarpeta y compruebe cómo se realiza la inclusión de _LogOnPartial.cshtmlcuál deriva WebViewPage(usando Html.Partial). Entonces no, el parcial no necesita derivar de ViewPageo ViewUserControlen absoluto para Html.Partialfuncionar.
Darin Dimitrov
1
Hmmm, parece que tienes razón. También parece que tengo que depurar un poco. ¡Gracias!
JP.
1
Solía ​​usar Html.RenderPartialcon la página ASPX, que devuelve vacío. Html.Partialdevuelve un MvcHtmlString. Entonces, si su parcial contiene mucho marcado, entonces creará un objeto de cadena potencialmente muy grande solo para GC inmediatamente. ¿Existe un enfoque que admita la representación directamente en la salida usando Razor?
Drew Noakes
2
@Draw Creo que encajar RenderPartial en un @{...}bloque debería funcionar. No tengo idea de si hay una solución mejor.
CodesInChaos
0

Si no desea duplicar el código y, como yo, solo desea mostrar estadísticas, en su modelo de vista, puede pasar los modelos de los que desea obtener datos de la siguiente manera:

public class GameViewModel
{
    public virtual Ship Ship { get; set; }
    public virtual GamePlayer GamePlayer { get; set; }     
}

Luego, en su controlador simplemente ejecute sus consultas en los modelos respectivos, páselos al modelo de vista y devuélvalo, ejemplo:

GameViewModel PlayerStats = new GameViewModel();

GamePlayer currentPlayer = (from c in db.GamePlayer [more queries]).FirstOrDefault();

[código para comprobar si hay resultados]

//pass current player into custom view model
PlayerStats.GamePlayer = currentPlayer;

Como dije, solo debe hacer esto si desea mostrar estadísticas de las tablas relevantes, y no hay ninguna otra parte del proceso CRUD, por razones de seguridad que otras personas han mencionado anteriormente.

Arrendajo
fuente