Motore di visualizzazione Razor: come aggiungere visualizzazioni parziali


84

Mi chiedevo quale sia, se possibile, il modo migliore per eseguire il rendering di un parziale utilizzando il nuovo motore di visualizzazione razor. Capisco che questo sia qualcosa che non è stato completato completamente nel tempo

In questo momento sto usando RenderPage per eseguire il rendering del controllo utente:

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

La pagina che chiama RenderPage utilizza una pagina di layout (master) con tre sezioni definite: TitleContent, HeadContent e Maincontent. Quando tento di eseguire il rendering del controllo delle impostazioni locali da questa pagina, sembra che anche queste sezioni siano necessarie: dovrebbero essere richieste solo nella pagina chiamante e sono presenti. Ricevo il seguente messaggio, indipendentemente dal fatto che includa o meno le sezioni nella mia vista parziale (ovviamente non voglio includere queste sezioni ma mi è sembrato un punto interessante per il debug ...).

Le seguenti sezioni sono state definite ma non sono state visualizzate nella pagina di layout "~ / Views / Shared / LocaleUserControl.cshtml": TitleContent; HeadContent; Contenuto principale

La mia visione parziale è la seguente (adattata dal seguente link ):

@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>

Risposte:


125

Il tuo partial assomiglia molto a un modello di editor, quindi potresti includerlo come tale (supponendo ovviamente che il tuo partial sia posizionato nella ~/views/controllername/EditorTemplatessottocartella):

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

O se questo non è il caso semplicemente:

@Html.Partial("nameOfPartial", Model)

Grazie per il feedback ... Html.EditorFor potrebbe essere una buona idea in questo caso, ma sarei interessato a vedere alternative in quanto non è il caso per esempi più complessi, sicuramente lo incontrerò di nuovo presto. Html.Partial non funzionerà in quanto deve derivare da ViewPage o ViewUserControl mentre il partial razor deriva da WebViewPage ...
JP.

4
Html.Partial funziona perfettamente. Avvia un nuovo progetto ASP.NET MVC 3 in Visual Studio utilizzando il motore di visualizzazione Razor, apri il _Layout.cshtml file nella Sharedcartella e verifica come viene eseguita l'inclusione da _LogOnPartial.cshtmlcui deriva WebViewPage(tramite Html.Partial). Quindi no, il parziale non ha bisogno di derivare da ViewPageo del ViewUserControltutto per Html.Partialfunzionare.
Darin Dimitrov

1
Hmmm, sembra che tu abbia ragione. Sembra anche che io abbia un po 'di debug da fare. Grazie!
JP.

1
L'ho usato Html.RenderPartialcon la pagina ASPX, che restituisce void. Html.Partialrestituisce un MvcHtmlString. Quindi, se il tuo partial contiene molti markup, creerai un oggetto stringa potenzialmente molto grande solo per GC immediatamente. Esiste un approccio che supporti il ​​rendering direttamente nell'output utilizzando Razor?
Drew Noakes

2
@Draw Penso che il wrapping di RenderPartial in un @{...}blocco dovrebbe funzionare. Non ho idea se esiste una soluzione migliore.
CodesInChaos

0

Se non vuoi duplicare il codice e, come me, vuoi solo mostrare le statistiche, nel tuo modello di visualizzazione, puoi semplicemente passare i modelli da cui vuoi ottenere i dati in questo modo:

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

Quindi, nel tuo controller esegui le tue query sui rispettivi modelli, passale al modello di visualizzazione e restituiscilo, ad esempio:

GameViewModel PlayerStats = new GameViewModel();

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

[codice per verificare i risultati]

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

Come ho detto, dovresti farlo solo se vuoi visualizzare le statistiche dalle tabelle pertinenti e non c'è altra parte del processo CRUD in corso, per motivi di sicurezza che altre persone hanno menzionato sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.