ASP.NET MVC如何在布局中使用PartialView?

时间:2015-07-14 15:14:05

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我需要使用局部视图在Layout中渲染菜单(如果有更好的方法,请告诉我)。我这样做(在布局中):

 @if (User.IsInRole("Admin"))
   {
      @Html.Partial("AdminMenu")
   }

这就是我在Controller中调用它的方式:

public ActionResult AdminMenu()
  {
      var am = _amr.GetAdminMenu();
      return PartialView(am);
  }

所以这是我的部分观点:

@model IEnumerable<DigitalHubOnlineStore.ViewModels.AdminMenuViewModel>

<div class="dropdown">
    <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        Admin menu
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
        @foreach (var item in Model)
        {
            <li><a href="@Html.DisplayFor(modelItem => item.MenuItemUrl)">@Html.DisplayFor(modelItem => item.MenuItemName)</a></li>
        }
    </ul>
</div>

不幸的是它没有用。

2 个答案:

答案 0 :(得分:4)

您需要使用

@{Html.RenderPartial("Admin");}

Html.Partial只将视图作为字符串返回,它不会将其写入响应,因此只是调用它什么也不做,返回的字符串超出了范围。它之所以存在,是因为你可以渲染一个字符串的局部视图,然后在多个地方插入字符串,而不必多次渲染局部视图。例如,如果您希望相同的分页标记位于页面的顶部和底部。或者您可能希望复制选项卡部分视图以创建多个选项卡等等。

要让您当前的代码正常运行,请尝试使用

Model ......
@{
   Layout=.....
   var adminMenu = Html.Partial("Admin");
}
@if (User.IsInRole("Admin"))
{
   Html.Raw(adminMenu);
}

Html.RenderPartial执行相同的操作,但内部调用Write将其写入响应。

现在,如果你的部分正在接受一个模型,那么你需要给它一个控制器方法,

[ChildActionOnly]
public ActionResult AdminMenu(AdminMenuViewModel model)
{
    return Partial(model);
}

然后将您的主叫代码更新为

 @{Html.RenderAction("AdminMenu", "ControllerHere", new { model = TheAdminViewModelHere });}

我个人认为我使用ChildOnlyAction来获取部分视图,因为我可以将所有处理逻辑移动到控制器中以获得更好的局部视图。它还允许部分视图了解它的父上下文,因为它允许您访问控制器以向模型添加信息以传递到局部视图。

答案 1 :(得分:3)

您必须在父视图中返回菜单集合,将相关模型发送到Partial,或者从您的部分调用另一个HtmlForm,AjaxForm或ajax调用。

@Html.Partial("Partials/AdminMenu",Model.AdminMenuItems)

OR

//SERVER
  public ActionResult AdminMenu()
  {
      var am = _amr.GetAdminMenu();
      return Json(am,JsonBehaviour.AllowGet);
  }



  //CLIENT
    @using (Ajax.BeginForm("AdminMenu","AdminController", null,  
        new AjaxOptions
        {
            OnSuccess = "renderSuccess",
            OnFailure = "renderFailure",
            OnBegin = "renderBegin"
        },
        new
        {
            id = "frmViewerAdminMenu",
            name = "frmViewerAdminMenu"
        })
    )
    {
    ...

        <script type="text/javascript">
            function renderSuccess(ajaxContext){
               /// ajaxContext is whatever comes back from GetAdminMenu()
            }
        </script>
     ...
    }

OR

- 服务器渲染视图

public ActionResult AdminMenuRenderView()
{
    return Partial("AdminMenuPartial",GetAdminMenuItems());
}

- 部分AdminMenuViewDynamicLoader

 @using (Ajax.BeginForm("AdminMenuRenderView","AdminController", null,  
    new AjaxOptions
    {
        OnSuccess = "renderSuccess",
        OnFailure = "renderFailure",
        OnBegin = "renderBegin"
    },
    new
    {
        id = "frmViewerAdminMenu",
        name = "frmViewerAdminMenu"
    })
)
{
...
    <div id="divAdminMenuContent"></div>

    <script type="text/javascript">
        function renderSuccess(ajaxContext){
            $('#divAdminMenuContent').html(ajaxContent);
        } 
    </script>
 ...
}

- 部分AdminMenuPartial

@model IEnumerable<DigitalHubOnlineStore.ViewModels.AdminMenuViewModel>

<div class="dropdown">
    <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        Admin menu
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
        @foreach (var item in Model)
        {
            <li><a href="@Html.DisplayFor(modelItem => item.MenuItemUrl)">@Html.DisplayFor(modelItem => item.MenuItemName)</a></li>
        }
    </ul>
</div>