在渲染之前,将MVC控制器中的视图路径进行修改。
在渲染之前,将MVC控制器中的视图路径进行修改。
在我的MVC 4控制器中,我想要重写View()方法,以便可以操作动作方法渲染的视图。为了做到这一点,我希望能够获取视图文件的物理路径。我尝试了以下方法:
string viewName = this.ControllerContext.RouteData.Route
.GetVirtualPath(this.ControllerContext.RequestContext, null)
.VirtualPath;
例如,这可能返回"/Errors/MissingParameters",但我希望它返回类似以下的内容:
"~/Views/Errors/MissingParameters" 或者更好的是 "~/Views/Errors/MissingParameters.cshtml"
另外,我还需要它能够处理区域(Areas),所以如果我在名为"Surveys"的区域中运行相同的示例,我希望它返回类似以下的内容:
"~/Areas/Surveys/Views/Errors/MissingParameters"
我希望这样做的原因是我正在尝试使用视图进行全球化,所以我可能有两个视图:
"~/Views/Errors/MissingParameters.cshtml" // 默认视图(en-GB)
"~/Views/Errors/MissingParameters_de-DE.cshtml" // 德语视图(de-DE)
我希望能够在引用视图之前检查当前语言/文化是否存在该视图。
非常感谢您的建议。
问题的原因是想要在MVC控制器渲染视图之前修改视图路径。解决方法是使用一个操作过滤器,在执行结果之前可以对结果进行修改。可以实现一个结果过滤器,并在其中实现IResultFilter.onResultExecuting方法,并在该方法中更改结果。此方法可以访问ResultExecutingContext.Result属性,该属性将包含视图。可以将其转换为System.Web.Mvc.ViewResultBase,并可以访问ViewName并进行更改。可以通过注册自定义视图引擎来修改模板路径,继承正在使用的视图引擎并在FindView方法中修改路径。还需要在global.asax的Application_Start事件中更改注册的引擎列表。
问题出现的原因是,注册了区域但不想在url中包含区域名,同时也不想在每个操作方法中返回视图时添加硬编码的视图路径。
解决方法是创建一个结果过滤器,并重写OnResultExecuting函数。在该函数中,判断结果类型是否为ViewResult或PartialViewResult,如果是,则根据控制器和视图名称构造新的视图路径,并将其赋值给viewResult.ViewName。然后使用ViewEngines.Engines.FindView方法查找视图,如果找不到,则将视图路径设置为在Shared文件夹中查找。
具体代码如下:
public override void OnResultExecuting(ResultExecutingContext filterContext) { string areaName = AreaNameAreaRegistration.PropoertyName; if (filterContext.Result.GetType() == typeof(ViewResult) || filterContext.Result.GetType() == typeof(PartialViewResult)) { dynamic viewResult = filterContext.Result; string viewname = string.IsNullOrEmpty(viewResult.ViewName) ? Convert.ToString(filterContext.RouteData.Values["action"]) : viewResult.ViewName; string folder = Convert.ToString(filterContext.RouteData.Values["controller"]); string lateralHireAreaViewPath = $"~/Areas/{areaName}/Views/"; string extension = viewname.Contains(".cshtml") ? "" : ".cshtml"; viewResult.ViewName = string.Concat(lateralHireAreaViewPath, folder, "/", viewname, extension); ViewEngineResult result = ViewEngines.Engines.FindView(filterContext.Controller.ControllerContext, viewResult.ViewName, null); if (result.View == null) { //searched in shared folder lateralHireAreaViewPath = string.Concat(lateralHireAreaViewPath, "Shared/"); viewResult.ViewName = string.Concat(lateralHireAreaViewPath, "/", viewname, extension); } } }
这样,就可以在返回视图时自动修改视图路径,而不需要在每个操作方法中手动添加硬编码的视图路径。
问题的原因是需要在MVC控制器中修改视图路径。解决方法是使用ViewContext.View属性来获取视图名称,并将其转换为WebFormView类型。另外,还可以使用扩展方法来实现相同的功能。
以下是完整的
在MVC控制器中修改视图路径的方法
在ASP.NET MVC中,有时候我们需要在控制器中修改视图的路径。这篇文章将介绍如何解决这个问题。
首先,我们可以使用ViewContext.View属性来获取视图名称。以下是一个示例代码:
var viewPath = ((WebFormView)ViewContext.View).ViewPath;
上述代码将获取到视图的路径,并将其赋值给viewPath变量。
为了使代码更加整洁,我们可以使用扩展方法来实现相同的功能。以下是一个示例扩展方法的代码:
public static class IViewExtensions { public static string GetWebFormViewName(this IView view) { if (view is WebFormView) { string viewUrl = ((WebFormView)view).ViewPath; string viewFileName = viewUrl.Substring(viewUrl.LastIndexOf('/')); string viewFileNameWithoutExtension = Path.GetFileNameWithoutExtension(viewFileName); return (viewFileNameWithoutExtension); } else { throw (new InvalidOperationException("This view is not a WebFormView")); } } }
上述代码将扩展了IView接口,并添加了一个名为GetWebFormViewName的方法。该方法将获取到视图的名称,并返回。
除了上述方法外,还有另一种解决方法。以下是一个示例代码:
((System.Web.Mvc.RazorView)htmlHelper.ViewContext.View).ViewPath
上述代码将获取到视图的路径。
本文介绍了在MVC控制器中修改视图路径的两种方法。第一种方法是使用ViewContext.View属性来获取视图的路径,并将其转换为WebFormView类型。第二种方法是使用扩展方法来实现相同的功能。无论选择哪种方法,都可以实现在控制器中修改视图路径的需求。
希望本文对你有所帮助!如有任何疑问,请在评论中留言。