Проблемы с частичным представлением в ASP.NET MVC 2 - PullRequest
1 голос
/ 22 апреля 2010

это главная страница:

<%@ 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();
    }

Поскольку частичное представление находится на главной странице, как мне получить его модель?

Ответы [ 4 ]

1 голос
/ 22 апреля 2010

Я думаю, что вы должны создать 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 для каждого метода.

0 голосов
/ 12 июля 2011

Вы также можете создать ContentPlaceHolder, где вы хотите, чтобы частичное представление отображалось, и вызывать RenderPartial () из нижележащих страниц. Таким образом, вы можете передать модель как обычно.

0 голосов
/ 12 июля 2011

Я пробовал решения Nick Masao и LukLed, оба они работают.

Однако, viewdata настроен для masterpage, в моем случае, я предполагаю, что masterpage будет отображать каждую страницу.

Мне нужно применить атрибут [DataForMasterPage] (решения Ника Масао) или или наследовать BaseController (решения LukLed) на каждом контроллере представления.

Итак, возможно ли создать класс и вызвать на Global.asax Application_Startсобытие, чтобы сделать это Set ViewData каждый раз?

0 голосов
/ 22 апреля 2010

Вы можете создать базовый класс для своих контроллеров и установить его во время создания, если вам нужно запрашивать его при каждом запросе:

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

Это не очень эффективно, потому что оно будет выполняться с каждым контроллером. Вы также можете создать фильтр действий, который устанавливает ViewData и применять его при необходимости.

...