具有特殊字符和 Child 操作的 MVC 路由参数
MVC Routing Parameters with Special Characters and Child Action
我有以下路线,它需要能够处理其中包含任何角色的游戏标题。我在我的 web.config 中适当地启用了一些东西以允许 URL 中的特殊字符,并且已经确认我的 URLS 在仅使用基本查询字符串而不是自定义 MVC 路由时工作。但是,一旦我通过 Html.Action 包含 child 动作加载,我就会得到下面的堆栈跟踪。
routes.MapRoute("Game", "Game/Game/{id}", new { controller = "Game", action = "Game", id = ""}, new { id = @"[^\.]*" });
这是我的控制器方法和视图(我把它们简化了很多,但错误仍然存在),它被路由调用,甚至视图本身内部的剃刀也被调用,但后来我得到了低于错误/堆栈跟踪。
控制器:
public ActionResult Game(string id)
{
{
Game currentGame = _ugdb.Games.FirstOrDefault(g => g.GameName.Equals(id));
return View(currentGame);
}
查看:
@model UltimateGameDB.Domain.Entities.Game
@Html.Action("SearchBar", "Search")
<span>@Model.GameName</span>
Child 动作控制器方法(未调用):
[ChildActionOnly]
public ActionResult SearchBar()
{
ViewBag.TotalGames = _ugdb.Game_Platform.Count() + _ugdb.Games.Count(g => g.Game_Platform.Count == 0);
return PartialView("_SearchBar");
}
以下是一些无效路由的示例:
http://localhost:58386/Game/Game/Sid%20Meier%27s%20Civilization%3a%20Beyond%20Earth
http://localhost:58386/Game/Game/Starcraft%20II%3a%20Heart%20of%20the%20Swarm
尽管我数据库中基本上所有具有特殊角色的游戏都会出现相同的错误。实际报错信息如下:
System.NotSupportedException: The given path's format is not supported.
at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path)
at System.Web.InternalSecurityPermissions.PathDiscovery(String path)
at System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping)
at System.Web.HttpRequest.MapPath(VirtualPath virtualPath)
at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage)
at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
at System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
at System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter)
at System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues)
at System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, Object routeValues)
at ASP._Page_Views_Game_Game_cshtml.Execute() in d:\TFS Workspace\UltimateGameDB\Dev\Source\ULTIMATEGAMEDB\UltimateGameDB.WebUI\Views\Game\Game.cshtml:line 257
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.StartPage.RunPage()
at System.Web.WebPages.StartPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList
1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList
1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)
我用谷歌搜索了很多,似乎无法弄清楚为什么这条路线行不通。
提前致谢!
尝试在 httpRuntime
元素中设置 relaxedUrlToFileSystemMapping="true"
。使用您已经添加的属性,它可能看起来像这样:
<httpRuntime targetFramework="4.5"
requestPathInvalidCharacters=""
requestValidationMode="2.0"
relaxedUrlToFileSystemMapping="true" />
来自 HttpRuntimeSection.RelaxedUrlToFileSystemMapping 属性 的文档:
Gets or sets a value that indicates whether the URL in an HTTP request
is required to be a valid Windows file path.
在 ASP.NET 运行时的深处,它会在处理请求之前尝试将请求的 url 转换为物理路径。如果物理路径无效,此设置似乎可以防止它爆炸。
我有以下路线,它需要能够处理其中包含任何角色的游戏标题。我在我的 web.config 中适当地启用了一些东西以允许 URL 中的特殊字符,并且已经确认我的 URLS 在仅使用基本查询字符串而不是自定义 MVC 路由时工作。但是,一旦我通过 Html.Action 包含 child 动作加载,我就会得到下面的堆栈跟踪。
routes.MapRoute("Game", "Game/Game/{id}", new { controller = "Game", action = "Game", id = ""}, new { id = @"[^\.]*" });
这是我的控制器方法和视图(我把它们简化了很多,但错误仍然存在),它被路由调用,甚至视图本身内部的剃刀也被调用,但后来我得到了低于错误/堆栈跟踪。
控制器:
public ActionResult Game(string id)
{
{
Game currentGame = _ugdb.Games.FirstOrDefault(g => g.GameName.Equals(id));
return View(currentGame);
}
查看:
@model UltimateGameDB.Domain.Entities.Game
@Html.Action("SearchBar", "Search")
<span>@Model.GameName</span>
Child 动作控制器方法(未调用):
[ChildActionOnly]
public ActionResult SearchBar()
{
ViewBag.TotalGames = _ugdb.Game_Platform.Count() + _ugdb.Games.Count(g => g.Game_Platform.Count == 0);
return PartialView("_SearchBar");
}
以下是一些无效路由的示例:
http://localhost:58386/Game/Game/Sid%20Meier%27s%20Civilization%3a%20Beyond%20Earth
http://localhost:58386/Game/Game/Starcraft%20II%3a%20Heart%20of%20the%20Swarm
尽管我数据库中基本上所有具有特殊角色的游戏都会出现相同的错误。实际报错信息如下:
System.NotSupportedException: The given path's format is not supported.
at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath) at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath) at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList) at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path) at System.Web.InternalSecurityPermissions.PathDiscovery(String path) at System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping) at System.Web.HttpRequest.MapPath(VirtualPath virtualPath) at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) at System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) at System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) at System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) at System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, Object routeValues) at ASP._Page_Views_Game_Game_cshtml.Execute() in d:\TFS Workspace\UltimateGameDB\Dev\Source\ULTIMATEGAMEDB\UltimateGameDB.WebUI\Views\Game\Game.cshtml:line 257 at System.Web.WebPages.WebPageBase.ExecutePageHierarchy() at System.Web.Mvc.WebViewPage.ExecutePageHierarchy() at System.Web.WebPages.StartPage.RunPage() at System.Web.WebPages.StartPage.ExecutePageHierarchy() at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList
1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList
1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList
1 filters, ActionResult actionResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.b__1c() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.b__1e(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End() at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) at System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End() at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) at System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End() at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End() at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)
我用谷歌搜索了很多,似乎无法弄清楚为什么这条路线行不通。
提前致谢!
尝试在 httpRuntime
元素中设置 relaxedUrlToFileSystemMapping="true"
。使用您已经添加的属性,它可能看起来像这样:
<httpRuntime targetFramework="4.5"
requestPathInvalidCharacters=""
requestValidationMode="2.0"
relaxedUrlToFileSystemMapping="true" />
来自 HttpRuntimeSection.RelaxedUrlToFileSystemMapping 属性 的文档:
Gets or sets a value that indicates whether the URL in an HTTP request is required to be a valid Windows file path.
在 ASP.NET 运行时的深处,它会在处理请求之前尝试将请求的 url 转换为物理路径。如果物理路径无效,此设置似乎可以防止它爆炸。