Razor视图引擎 - 如何添加局部视图

85
我想知道在新的 Razor 视图引擎中,如果可能的话,渲染局部视图的最佳方法是什么。 我知道这是一些时间内没有完全完成的事情。
现在我正在使用 RenderPage 来渲染用户控件:
@RenderPage("~/Views/Shared/LocaleUserControl.cshtml",ViewData.Model)

RenderPage调用页面时使用了一个布局(master)页面,其中定义了三个部分:TitleContent、HeadContent和Maincontent。当我尝试从该页面呈现我的本地控件时,似乎这些部分也是必需的 - 它们应该只在调用页面中需要并且已经存在。无论我是否在我的部分视图中包含这些部分,我都会收到以下消息(显然我不想包含这些部分,但它似乎是一个有趣的调试点...)。

已经定义了以下部分,但没有在布局页 '~/Views/Shared/LocaleUserControl.cshtml' 上呈现:TitleContent;HeadContent;MainContent

我的部分视图如下所示(改编自以下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>
2个回答

127

你的部分视图看起来很像一个编辑器模板,因此你可以将其作为编辑器模板包含进去(当然前提是你的部分视图放置在 ~/views/controllername/EditorTemplates 子文件夹中):

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

或者如果不是这种情况,那么只需:

@Html.Partial("nameOfPartial", Model)

谢谢您的反馈。在这种情况下,Html.EditorFor可能是个不错的想法,但我很想看到其他选择,因为对于更复杂的示例来说并非如此- 我肯定很快就会再次遇到这种情况。Html.Partial将无法工作,因为它必须派生自ViewPage或ViewUserControl,而Razor部分派生自WebViewPage... - JP.
4
Html.Partial工作得非常好。在Visual Studio中使用Razor视图引擎开始一个新的ASP.NET MVC 3项目,打开“Shared”文件夹中的“_Layout.cshtml”文件,并查看如何包含从“WebViewPage”派生的“_LogOnPartial.cshtml”(使用Html.Partial)。因此,对于Html.Partial,部分不需要从ViewPage或ViewUserControl派生。 - Darin Dimitrov
1
嗯,看起来你是正确的。似乎我还有一些调试工作要做。谢谢! - JP.
1
我过去在ASPX页面中使用Html.RenderPartial,它返回void。而Html.Partial则返回一个MvcHtmlString。因此,如果你的部分视图包含大量标记,则会创建一个可能非常庞大的字符串对象,然后立即进行垃圾回收。是否有一种方法可以直接使用Razor将内容呈现到输出中? - Drew Noakes
2
@Draw 我认为将RenderPartial包装在@{...}块中应该可以解决问题。不知道是否有更好的解决方案。 - CodesInChaos

0

如果您不想重复编写代码,而且像我一样只想显示统计数据,那么在您的视图模型中,您可以只传递要获取数据的模型,如下所示:

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

然后,在您的控制器中,只需在相应的模型上运行查询,将它们传递给视图模型并返回它,例如:

GameViewModel PlayerStats = new GameViewModel();

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

[检查结果的代码]

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

就像我说的,你只应该在想要从相关表中显示统计信息,并且没有其他CRUD过程发生的情况下才这样做,出于其他人提到的安全原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接