Razor View Engine - Wie kann ich Teilansichten hinzufügen?

84

Ich habe mich gefragt, was, wenn es möglich ist, der beste Weg ist, einen Teil mit der neuen Razor View Engine zu rendern. Ich verstehe, dass dies zu diesem Zeitpunkt noch nicht vollständig abgeschlossen war

Im Moment verwende ich RenderPage, um das Benutzersteuerelement zu rendern:

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

Die Seite, die RenderPage aufruft, verwendet eine Layoutseite (Masterseite) mit drei definierten Abschnitten: TitleContent, HeadContent und Maincontent. Wenn ich versuche, mein Gebietsschemasteuerelement von dieser Seite aus zu rendern, werden diese Abschnitte anscheinend ebenfalls benötigt - sie sollten nur auf der aufrufenden Seite erforderlich sein und vorhanden sein. Ich erhalte die folgende Meldung, unabhängig davon, ob ich die Abschnitte in meine Teilansicht einbeziehe oder nicht (natürlich möchte ich diese Abschnitte nicht einschließen, aber es schien ein interessanter Debugging-Punkt zu sein ...).

Die folgenden Abschnitte wurden definiert, aber nicht auf der Layoutseite '~ / Views / Shared / LocaleUserControl.cshtml' gerendert: TitleContent; Hauptinhalt; Hauptinhalt

Meine Teilansicht lautet wie folgt (angepasst über den folgenden 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>
JP.
quelle

Antworten:

124

Ihr Teil sieht einer Editorvorlage sehr ähnlich, sodass Sie ihn als solchen einfügen können (vorausgesetzt natürlich, dass Ihr Teil im ~/views/controllername/EditorTemplatesUnterordner abgelegt ist ):

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

Oder wenn dies nicht einfach der Fall ist:

@Html.Partial("nameOfPartial", Model)
Darin Dimitrov
quelle
Vielen Dank für das Feedback ... Html.EditorFor ist in diesem Fall vielleicht eine gute Idee - aber ich würde mich für Alternativen interessieren, da dies bei komplexeren Beispielen nicht der Fall ist - ich werde auf jeden Fall bald wieder darauf stoßen. Html.Partial funktioniert nicht, da es von ViewPage oder ViewUserControl abgeleitet werden muss, während der Rasiermesserteil teilweise von WebViewPage ...
JP stammt.
4
Html.Partial funktioniert einwandfrei. Starten Sie ein neues ASP.NET MVC 3 - Projekt in Visual Studio mit der Razor - Ansicht - Engine, öffnen Sie die _Layout.cshtml Datei in dem SharedOrdner und Kasse , wie die Einbeziehung _LogOnPartial.cshtmlwelche stammt aus WebViewPageerfolgt (mit Html.Partial). Also nein, der Teil muss nicht von ViewPageoder ViewUserControlüberhaupt nicht abgeleitet werden, um Html.Partialzu arbeiten.
Darin Dimitrov
1
Hmmm, es sieht so aus, als ob du richtig bist. Es sieht auch so aus, als hätte ich etwas zu debuggen. Vielen Dank!
JP.
1
Ich habe früher Html.RenderPartialmit der ASPX-Seite gearbeitet, die void zurückgibt. Html.Partialgibt ein zurück MvcHtmlString. Wenn Ihr Teil also viele Markups enthält, erstellen Sie ein möglicherweise sehr großes Zeichenfolgenobjekt, um es sofort zu GCen. Gibt es einen Ansatz, der das direkte Rendern in die Ausgabe mit Razor unterstützt?
Drew Noakes
2
@Draw Ich denke, das Umschließen von RenderPartial in einen @{...}Block sollte funktionieren. Keine Ahnung, ob es eine bessere Lösung gibt.
CodesInChaos
0

Wenn Sie keinen Code duplizieren möchten und wie ich nur Statistiken anzeigen möchten, können Sie in Ihrem Ansichtsmodell einfach die Modelle übergeben, von denen Sie Daten abrufen möchten:

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

Führen Sie dann in Ihrem Controller einfach Ihre Abfragen für die jeweiligen Modelle aus, übergeben Sie sie an das Ansichtsmodell und geben Sie sie zurück. Beispiel:

GameViewModel PlayerStats = new GameViewModel();

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

[Code, um zu überprüfen, ob Ergebnisse]

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

Wie ich bereits sagte, sollten Sie dies nur dann wirklich tun, wenn Sie Statistiken aus den relevanten Tabellen anzeigen möchten und aus Sicherheitsgründen, die andere oben erwähnt haben, kein anderer Teil des CRUD-Prozesses stattfindet.

Jay
quelle