我有一个包含许多小部件的应用,其内容取决于请求特定路由的用户。简单地说:如果请求小部件操作,则必须呈现其内容,否则它是空的。考虑这样的路线/行动:
我的foo动作:
public ActionResult Foo(string id) {
if (ModelState.IsValid) {
var response = FooService.GetData(id);
// Inject Foo widget to Index
}
return RedirectToAction("Index");
}
我知道可以使用ViewBag或其他方法发送变量并使用条件来决定是否渲染部分视图。但是......应该有更好的方法来做到这一点,对吗?
答案 0 :(得分:3)
当我想用非平凡的绑定逻辑(调用数据库,组合复杂对象等)构建共享视图时,我使用MVC的Html.RenderActionResult。每个窗口小部件的绑定逻辑包含在PartialViewResult方法中,该方法使用Html.RenderAction()从* .cshtml文件调用。
<强> ContentController:强>
public ActionResult Index(int id)
{
var indexViewModel = new IndexViewModel
{
Id = id,
Title = "My Title",
SubHeader = "Wow its 2016"
};
return View(indexViewModel);
}
public PartialViewResult PopularContent(int id)
{
var popularContentViewModel = new List<PopularContentViewModel>();
// query by id to get popular content items
return PartialView("_PopularContent", popularContentViewModel);
}
public PartialViewResult Widget2(int id)
{
return PartialView("_Widget2Partial");
}
<强> Index.cshtml:强>
@model StackOverflow.RenderAction.ViewModels.IndexViewModel
<h1>@Model.Title</h1>
<h2>@Model.SubHeader</h2>
--RenderAction will call out to the specified route.
--Note the use of the Id parameter from the viewmodel.
@{Html.RenderAction("PopularContent", "Content", new {Model.Id});}
答案 1 :(得分:0)
ASP.NET MVC属性路由可以是一个很好的解决方案:
在您的控制器中:
public class WidgetController : Controller
{
[Route("myapp/foowidget", Name = "FooWidget")]
public ActionResult FooWidget()
{
//create any model and return any view or partial or redirect
}
[Route("myapp/boowidget/{id:int}", Name = "BooWidget")]
public ActionResult BooWidget(int id)
{
//create any model and return any view or partial or redirect
}
}
然后在视图中,您可以按名称调用路径:
@Url.RouteUrl("FooWidget")
或
@Url.RouteUrl("BooWidget")
或
@Html.RenderPartial("FooWidget")
如果url是/ myapp / something / id, @Url.RouteUrl("BooWidget")
将呈现或连接当前url中的id,因为你的Route属性定义:&#34; myapp / boowidget / {id:int} &#34 ;.事实上,@Url.RouteUrl("BooWidget")
可能会从格式/ controllerName / action / id的任何当前url中提取id,但您必须进行测试。
并注意如何将您的WidgetController和您的url分开关注点路由不以任何方式依赖于该控制器的名称。这是属性路由的一个很好的功能,您可以声明自定义路由以及组织控制器,并从控制名称的名称约定依赖性中断,该控件名称是用户在浏览器中看到的url controllerName / action的一部分。
关于Html.RenderPartial ,我不确定RenderPartial&#34;是否连接&#34;或者将能够像#34; FooWidget&#34;一样路由到您的RouteName。如果它确实很棒。
如果不是你的解决方案:
public class WidgetController : Controller
{
public ActionResult FooWidget()
{
//model, you choose, return a partial
}
public ActionResult RedirectUser()
{
//do a redirect
}
public ActionResult BooWidget()
{
//any model, any partial
}
public ActionResult BooWidget(int id)
{
//any model, any partial
}
}
控制器中的每个方法都是单一目的,具有独特的签名并且做一件事,没有条件可以传入,也没有必要的决定。