ASP.NET MVC 2 中的局部视图问题

Posted

技术标签:

【中文标题】ASP.NET MVC 2 中的局部视图问题【英文标题】:Problems with Partial Views in ASP.NET MVC 2 【发布时间】:2010-04-22 11:47:33 【问题描述】:

这是母版页:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />

    <asp:ContentPlaceHolder ID="header1" runat="server" />
</head>

<body>
<div class="page">
    <div id="header">
        <div id="title">
            <h1>My MVC Application</h1>
        </div>

        <div id="logindisplay">
            <% Html.RenderPartial("LogOnUserControl"); %>
        </div> 

        <div id="menucontainer">

            <ul id="menu">              
                <li><%= Html.ActionLink("Home", "Index", "Home")%></li>
                <li><%= Html.ActionLink("About", "About", "Home")%></li>
                <li><%= Html.ActionLink("Imoveis", "Index", "Categoria")%></li>
                <li><%= Html.ActionLink("Admin", "Index", "Admin")%></li>
                <li><%= Html.ActionLink("User", "Index", "User")%></li>
            </ul>

        </div>
    </div>
    <div id="left">

     <% Html.RenderPartial("~/Views/Imovel/Pesquisa.ascx"); %>   

    </div>
    <div id="main">
        <asp:ContentPlaceHolder ID="MainContent" runat="server" />

        <div id="footer">
        </div>
    </div>
</div>
</body>
</html>

局部视图

  <%= Html.DropDownList("categoria_id", (SelectList)ViewData["Categoriass"], "--Selecciona um--")%>



            <div class="editor-label">
            <%= Html.LabelFor(model => model.categoria_id) %>
        </div>
        <div class="editor-field">
            <%= Html.DropDownListFor(model => model.categoria_id, (SelectList)ViewData["Categorias"], "--Selecciona um--")%>

            <%= Html.ValidationMessageFor(model => model.categoria_id) %>
        </div>

这就是问题所在:

    public ActionResult Index()
    
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        **ViewData["Categoriass"] = new SelectList(catRepository.FindAllCategorias().AsEnumerable(), "id", "nome", 3);**



        return View();
    

由于部分视图在母版页中,我如何获取它的模型?

【问题讨论】:

【参考方案1】:

我认为您应该创建一个 ActionFilter 并将其应用到您的控制器上。

像这样创建一个动作过滤器

public class DataForMasterPageAttribute : ActionFilterAttribute

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    
        //initiate your repository

           var catRepository = ...;

        //then create the viewdata like so

        filterContext.Controller.ViewData["Categorias"] = new SelectList(catRepository.FindAllCategorias().AsEnumerable(), "id", "nome", 3);
    


然后将它应用到控制器上,它也可用于所有操作。像这样;

[DataForMasterPage]
public class CategoriaController : Controller

      public ActionResult Index()
      
            ViewData["Message"] = "Welcome to ASP.NET MVC!";
            return View();
      

在局部视图上,您​​只需照常调用 ViewData,无需更改任何内容

<div class="editor-label">
        <%= Html.LabelFor(model => model.categoria_id) %>
    </div>
    <div class="editor-field">
        <%= Html.DropDownListFor(model => model.categoria_id, (SelectList)ViewData["Categorias"], "--Selecciona um--")%>

        <%= Html.ValidationMessageFor(model => model.categoria_id) %>
    </div>

可能存在性能问题,但它是避免在每个方法上设置 ViewData 的最简单方法之一。

【讨论】:

【参考方案2】:

如果您需要在每个请求中查询它,您可以为您的控制器创建基类并在创建过程中设置它:

public class BaseController : Controller

    public BaseController()
    
        var catRepository = ...;
        ViewData["Categoriass"] = new SelectList(catRepository.FindAllCategorias().AsEnumerable(), "id", "nome", 3);
    

这不是很有效,因为它将与每个控制器一起执行。您还可以创建设置 ViewData 的操作过滤器并在需要的地方应用它。

【讨论】:

【参考方案3】:

我尝试过 Nick Masao 和 LukLed 的解决方案,它们都有效。

但是,viewdata 是为 masterpage 设置的,在我的情况下,我假设 masterpage 将呈现每个页面。

我必须 应用 [DataForMasterPage] 属性(Nick Masao 的解决方案)或 或者 继承 BaseController(LukLed 的解决方案) 在每个视图的控制器上。

那么,是否可以创建一个类并在 Global.asax Application_Start 事件上调用以使其每次都设置视图数据?

【讨论】:

【参考方案4】:

您还可以创建一个 ContentPlaceHolder,您希望在其中渲染局部视图并从底层页面调用 RenderPartial()。这样你就可以像往常一样传递模型了。

【讨论】:

以上是关于ASP.NET MVC 2 中的局部视图问题的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 通用局部视图模式

在 ASP.NET MVC 中使用 jQuery 渲染局部视图

如何在 ASP.NET MVC 中使用 Ajax 调用刷新局部视图?

asp.net mvc 中的部分视图

如何在 ASP.NET MVC 中控制局部视图的条件显示

如何从 ASP.NET MVC 控制器的局部视图中读取值