好的,我正在开发一个像网站一样的MVC CMS,并在宣布使用以下模式的路线时。我将动作名称和控制器名称封装到类似的类
中public class UrlUtilsUnhandledErrorsExtensions
{
private readonly UrlHelper _urlHelper;
public UrlUtilsUnhandledErrorsExtensions(UrlHelper urlHelper)
{
_urlHelper = urlHelper;
}
public String GetLatestErrors()
{
return _urlHelper.Action("GetLatestErrors", "UnhandledErrors");
}
}
然后而不是写
@Url.Action("GetLatestErrors", "UnhandledErrors")
我写
@Url.Action(Url.Utils().UnhandledErrors().GetLatestErrors())
我发现这种方法更容易维护,因为如果控制器名称更改,我只需要更改一个类。
这适用于任何链接,控制器重定向(返回重定向(...))以及接受由
返回的虚拟路径的任何内容public String GetLatestErrors()
{
return _urlHelper.Action("GetLatestErrors", "UnhandledErrors");
}
但是问题出现了:我不能用这种方法使用Html.Action()。它需要控制器名称和操作名称,但我希望它使用虚拟路径。 在挖掘并研究MVC源代码后,我意识到我需要编写自己的Html.Action扩展方法,它只接受虚拟路径。
所以这是我的解决方案
public void ActionFromUrl(this HtmlHelper htmlHelper, String url)
{
RouteValueDictionary rvd = null;
rvd = new RouteValueDictionary();
String action = String.Empty;
String controller = String.Empty;
foreach (Route route in htmlHelper.RouteCollection)
{
if (route.Url == url.Substring(1)) // url starts with / for some reason
{
action = route.Defaults["action"] as String;
controller = route.Defaults["controller"] as String;
break;
}
}
RequestContext rc = ((MvcHandler)HttpContext.Current.CurrentHandler).RequestContext;
rc.RouteData.Values["action"] = action;
rc.RouteData.Values["controller"] = controller;
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
IController controllerImpl = factory.CreateController(rc, controller);
controllerImpl.Execute(rc);
}
它有效,但由于它基于Html.RenderAction方法,它只是直接写入输出,所以在我的视图中,我写下面的代码
@{ Html.ActionFromUrl(Url.Utils().UnhandledErrors().GetLatestErrors()); }
它首先渲染我的部分,所有的一切都在上面,然后是html的其余部分。 这不是我想要的结果,所以我必须找出将结果呈现为Html.Action的字符串的方式。我已经用dotPeek查看了源代码,但还没弄清楚如何将它完全混合。
我的问题是:我做错了什么?或者我如何编写Html.Action重载,以便它接受虚拟路径并返回MvcHtmlString?
答案 0 :(得分:0)