this is the master page :
这是母版页:
<%@ 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>
Partial View
<%= 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>
This is the problem:
这就是问题:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
**ViewData["Categoriass"] = new SelectList(catRepository.FindAllCategorias().AsEnumerable(), "id", "nome", 3);**
return View();
}
Since the partial view is in the master page, how do I get its model?
由于局部视图位于母版页中,我如何获取其模型?
4 个解决方案
#1
1
I think you should create an ActionFilter and apply it on your controllers.
我认为你应该创建一个ActionFilter并将其应用到你的控制器上。
Create an action filter like this
像这样创建一个动作过滤器
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);
}
}
Then apply it on the controller and it will be available for all actions as well. Like so;
然后将其应用于控制器,它也可用于所有操作。像这样;
[DataForMasterPage]
public class CategoriaController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
}
On the partial view you just call the ViewData as usual, no need to change anything
在局部视图上,您可以像往常一样调用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>
Might have performance issues, but its one of the simplest ways to avoid setting the ViewData on every method.
可能存在性能问题,但它是避免在每个方法上设置ViewData的最简单方法之一。
#2
0
You can create base class for your controllers and set it during creation if you need to query for it with every request:
您可以为控制器创建基类,并在创建期间设置它,如果您需要使用每个请求进行查询:
public class BaseController : Controller
{
public BaseController()
{
var catRepository = ...;
ViewData["Categoriass"] = new SelectList(catRepository.FindAllCategorias().AsEnumerable(), "id", "nome", 3);
}
}
That is not really efficient,because it will be executed with every controller. You can also create action filter which sets ViewData and apply it where needed.
这不是很有效,因为它将在每个控制器上执行。您还可以创建动作过滤器,用于设置ViewData并在需要时应用它。
#3
0
I have try Nick Masao & LukLed solutions, both of them are works.
我尝试过Nick Masao和LukLed解决方案,两者都是有效的。
However, the viewdata is set for masterpage, in my case, i assume masterpage will render every page.
但是,viewdata是为masterpage设置的,在我的例子中,我假设masterpage将呈现每个页面。
I have to apply the [DataForMasterPage] attribute (Nick Masao's solutions) or or inherits the BaseController (LukLed's solutions) on every View's Controller.
我必须应用[DataForMasterPage]属性(Nick Masao的解决方案)或者在每个View的Controller上继承BaseController(LukLed的解决方案)。
So, is it possible create a Class and invoke on Global.asax Application_Start event to make it Set viewdata everytimes?
那么,是否有可能创建一个类并在Global.asax Application_Start事件上调用以使其每次都设置为viewdata?
#4
0
You could also create a ContentPlaceHolder where you want the partial view to render and call the RenderPartial() from the underlying pages. That way you can pass the model as usual.
您还可以创建一个ContentPlaceHolder,您希望部分视图在底层页面中呈现并调用RenderPartial()。这样你就可以像往常一样传递模型。
#1
1
I think you should create an ActionFilter and apply it on your controllers.
我认为你应该创建一个ActionFilter并将其应用到你的控制器上。
Create an action filter like this
像这样创建一个动作过滤器
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);
}
}
Then apply it on the controller and it will be available for all actions as well. Like so;
然后将其应用于控制器,它也可用于所有操作。像这样;
[DataForMasterPage]
public class CategoriaController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
}
On the partial view you just call the ViewData as usual, no need to change anything
在局部视图上,您可以像往常一样调用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>
Might have performance issues, but its one of the simplest ways to avoid setting the ViewData on every method.
可能存在性能问题,但它是避免在每个方法上设置ViewData的最简单方法之一。
#2
0
You can create base class for your controllers and set it during creation if you need to query for it with every request:
您可以为控制器创建基类,并在创建期间设置它,如果您需要使用每个请求进行查询:
public class BaseController : Controller
{
public BaseController()
{
var catRepository = ...;
ViewData["Categoriass"] = new SelectList(catRepository.FindAllCategorias().AsEnumerable(), "id", "nome", 3);
}
}
That is not really efficient,because it will be executed with every controller. You can also create action filter which sets ViewData and apply it where needed.
这不是很有效,因为它将在每个控制器上执行。您还可以创建动作过滤器,用于设置ViewData并在需要时应用它。
#3
0
I have try Nick Masao & LukLed solutions, both of them are works.
我尝试过Nick Masao和LukLed解决方案,两者都是有效的。
However, the viewdata is set for masterpage, in my case, i assume masterpage will render every page.
但是,viewdata是为masterpage设置的,在我的例子中,我假设masterpage将呈现每个页面。
I have to apply the [DataForMasterPage] attribute (Nick Masao's solutions) or or inherits the BaseController (LukLed's solutions) on every View's Controller.
我必须应用[DataForMasterPage]属性(Nick Masao的解决方案)或者在每个View的Controller上继承BaseController(LukLed的解决方案)。
So, is it possible create a Class and invoke on Global.asax Application_Start event to make it Set viewdata everytimes?
那么,是否有可能创建一个类并在Global.asax Application_Start事件上调用以使其每次都设置为viewdata?
#4
0
You could also create a ContentPlaceHolder where you want the partial view to render and call the RenderPartial() from the underlying pages. That way you can pass the model as usual.
您还可以创建一个ContentPlaceHolder,您希望部分视图在底层页面中呈现并调用RenderPartial()。这样你就可以像往常一样传递模型。