6

I have the following route and it needs to be able to handle game titles with any character in them. I have things enabled appropriately in my web.config to allow special characters in the URL, and have confirmed that my URLS work when just using basic query strings rather than custom MVC Routes. However, as soon as I include a child action load via Html.Action I get the below stack trace.

routes.MapRoute("Game", "Game/Game/{id}", new { controller = "Game", action = "Game", id = ""}, new { id = @"[^\.]*" });

Here is my Controller method and view (I dumbed them down a lot, but the error still occurs), it gets called by the route, and even the razor inside of the view itself gets called but then I get the below error / stack trace.

Controller:

public ActionResult Game(string id)
  {
     {
        Game currentGame = _ugdb.Games.FirstOrDefault(g => g.GameName.Equals(id));
        return View(currentGame);

  }

View:

@model UltimateGameDB.Domain.Entities.Game
@Html.Action("SearchBar", "Search")
<span>@Model.GameName</span>

Child Action Controller Method (does not get called):

[ChildActionOnly]
  public ActionResult SearchBar()
  {
     ViewBag.TotalGames = _ugdb.Game_Platform.Count() + _ugdb.Games.Count(g => g.Game_Platform.Count == 0);
     return PartialView("_SearchBar");
  }

Here are some examples of a few routes that are not working:

http://localhost:58386/Game/Game/Sid%20Meier%27s%20Civilization%3a%20Beyond%20Earth

http://localhost:58386/Game/Game/Starcraft%20II%3a%20Heart%20of%20the%20Swarm

Although basically any game in my database that has a special character is giving the same error. The actual error message is as follows:

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(IList1 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, IList1 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.WrappedAsyncResultBase1.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.WrappedAsyncResultBase1.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.WrappedAsyncResultBase1.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.WrappedAsyncResultBase1.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)

I have googled this a bunch and cannot seem to figure out why this route would not work.

Thanks in advance!

Aaron Davis
  • 281
  • 1
  • 5
  • 22
  • 1
    Do you need the constraints parameter? Have you tried leaving that last parameter off? – drneel Sep 13 '15 at 00:10
  • 1
    Your route definition looks fine to me. Can you give an example of a url it's not matching against? – Peter Sep 13 '15 at 00:18
  • 1
    Please, provide more info. I've just tried to create sample mvc app and add your route. http://localhost/game/game/gameid works fine for me. – Vadim Sentiaev Sep 13 '15 at 00:26
  • Thanks to all 3 of you for responding and helping me look at this problem! I have updated the problem to include some sample URLs and the actual stack trace. – Aaron Davis Sep 13 '15 at 01:53
  • It's looks similar to http://stackoverflow.com/questions/4694760/asp-net-mvc-colon-in-url#answer-18742172 – Vadim Sentiaev Sep 13 '15 at 19:19
  • 1
    I've tried to add requestPathInvalidCharacters="" to system.web>httpRuntime and check urls you provided, it's working for me. – Vadim Sentiaev Sep 13 '15 at 19:20
  • I have the following under my System.Web in web.config and I am still getting that error: I also tried it without the requestValidationMode – Aaron Davis Sep 13 '15 at 23:11
  • Heres one more weird thing about this: It actually does call my controller method appropriately its only when it called the return View(model) that the error occurs – Aaron Davis Sep 13 '15 at 23:35
  • 1
    Yes - I was going to say, based on the stack trace you posted, that it looks like the problem is occurring in your view. Are you doing any sort of file access or IO in your view? Are you trying to access files that have special characters in their names? – Peter Sep 14 '15 at 00:30
  • For some reason it seems that MVC is trying to actually access the path instead of using the controller route, I have no idea why routing would do this though. In my elmah trace its saying Path_Translated is "D:\TFS Workspace\UltimateGameDB\Dev\Source\ULTIMATEGAMEDB\UltimateGameDB.WebUI\Game\Game\Soul Saga: Episode 1" which obviously does not exist it should be grabbing the view under Views/Game/Game.cshtml and applying the model. – Aaron Davis Sep 14 '15 at 01:30
  • Oh yeah and this is happening for all of my routes that contain special characters not just this one, could it be something is misconfigured with my MVC routing or something? I am not doing any type of file access in my controllers. – Aaron Davis Sep 14 '15 at 01:33
  • Ok, edited my post and included a dumbed down one of my views and controllers to the bare minimum and the error is still occurring. – Aaron Davis Sep 14 '15 at 02:52
  • Turns out the error only occurs when a child action is included somewhere in the rendered page, and the url includes special characters, updated my question to add the child action controller method I am calling. – Aaron Davis Sep 14 '15 at 04:28

1 Answers1

6

Try setting relaxedUrlToFileSystemMapping="true" in your httpRuntime element. With the attributes you've already added, it will probably look something like this:

<httpRuntime targetFramework="4.5" 
  requestPathInvalidCharacters="" 
  requestValidationMode="2.0" 
  relaxedUrlToFileSystemMapping="true" /> 

From the docs for the HttpRuntimeSection.RelaxedUrlToFileSystemMapping property:

Gets or sets a value that indicates whether the URL in an HTTP request is required to be a valid Windows file path.

Somewhere in the depths of the ASP.NET runtime it tries to translate the requested url into a physical path before handling the request. This setting seems to keep it from blowing up if the physical path is not valid.

Peter
  • 12,541
  • 3
  • 34
  • 39