2014-04-07 21 views
6

Ricevo un'eccezione imprevista quando il mio url contiene un carattere di citazione quando la mia vista contiene un'azione figlio.L'azione figlio MVC genera caratteri non validi nel percorso

http://mysite.info/home/index/"

Quando la vista per questa azione non contiene un tutto azione bambino funziona bene. Quando contiene un'azione figlio (ad es. @ Html.Action ("Menu")) ottengo l'eccezione "System.ArgumentException: caratteri non validi nel percorso" alla chiamata a Html.Action.

Guardando a this post il carattere di virgoletta doppia non è uno dei caratteri non validi di default. Mi sembra che un'azione con o senza un'azione da bambino dovrebbe comportarsi allo stesso modo. O una doppia citazione è valida o non lo è.

Inoltre, non sono sicuro del modo migliore per aggirare questo apparente doppio standard. Sono riluttante a cambiare l'elenco di caratteri non validi per contenere "(i valori predefiniti sono i valori predefiniti per una ragione) .Le azioni secondarie sono molto utili, quindi non voglio non usarle.

Non sto tentando attivamente di utilizzare le virgolette nei miei percorsi, ma se "non è nell'elenco di caratteri non validi, non dovrebbe risultare in un'eccezione, giusto?

Esempio

Controller:

public class HomeController : Controller 
{ 
    public ActionResult WithChildAction() // throws exception with quote in path 
    { 
     return View(); 
    } 

    public ActionResult WithoutChildAction() // works with quote in path 
    { 
     return View(); 
    } 

    public ActionResult ChildAction() 
    { 
     return View(); 
    } 
} 

WithChildAction.cshtml:

<h2>With Child Action</h2> 

@Html.Action("ChildAction") 

WithoutChildAction.cshtml:

<h2>Without Child Action</h2> 

ChildAction.cshtml:

<h2>Child Action</h2> 

Stack Trace

[ArgumentException: Illegal characters in path.] 
    System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional) +11113918 
    System.Security.Permissions.FileIOPermission.CheckIllegalCharacters(String[] str) +30 
    System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList) +97 
    System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path) +63 
    System.Web.InternalSecurityPermissions.PathDiscovery(String path) +29 
    System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping) +149 
    System.Web.HttpRequest.MapPath(VirtualPath virtualPath) +33 
    System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +44 
    System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28 
    System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +19 
    System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +461 
    System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +83 
    System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, Object routeValues) +29 
    ASP._Page_Areas_Site_Views_Content_File_cshtml.Execute() in c:\inetpub\Websites\MyWebsite\Source\Areas\Site\Views\Content\File.cshtml:22 
    System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +199 
    System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +104 
    System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +78 
    System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235 
    System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107 
    System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +291 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52 
    System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +173 
    System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100 
    System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 
    System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54 
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39 
    System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +28 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54 
    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29 
    System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 
    System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36 
    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54 
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9690164 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 
+0

Qual è la traccia dello stack? –

+0

@ErikFunkenbusch Aggiunta traccia dello stack. – jdehlin

+0

Come si può vedere dallo stack trace, l'errore proviene da MapPath e in effetti accade fuori da MVC. Questo è il codice nella base HttpHandler e questo dovrebbe essere lo stesso indipendentemente dal fatto che si tratti di un'azione regolare o di un figlio. –

risposta

1

Html.Action ha un controllo che elabora il percorso corrente per vedere se è in una zona. Questo processo restituisce gli accessi al percorso virtuale (file system). Le quotazioni non sono consentite nel Filesystem e quindi generano l'errore.

bool usingAreas; 
VirtualPathData vpd = htmlHelper.RouteCollection 
    .GetVirtualPathForArea(htmlHelper.ViewContext.RequestContext, null /* name */, routeValues, out usingAreas); 

Con il codice RouteCollection Estensioni qui:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/RouteCollectionExtensions.cs

si può essere in grado di gestire le RouteValues ​​e impostare il nome dell'area per evitare l'errore, ma non permettendo i caratteri del file system non validi nel il primo posto sarebbe l'ideale

+0

Guardando oltre, sta superando il controllo dell'area. In realtà sta cercando di eseguire, quindi qualcosa non viene ripulito come inizialmente. – neehouse

+0

Solo il pensiero che ho è che è codificato sulla richiesta del browser, viene decodificato e non codifica sulla richiesta di Azione Figlio. – neehouse

2

trovato uno potenziale soluzione impostando la seguente nel file web.config:

<httpRuntime relaxedUrlToFileSystemMapping="true"/> 

Questo sembra pericoloso, quindi sto solo andando a ignorare gli errori.

Problemi correlati