用户代理导致 MVC 显示对于参数异常:路径中的字符非法
本文关键字:异常 路径 非法 字符 参数 MVC 显示 于参数 用户代理 | 更新日期: 2023-09-27 18:34:13
我遇到了一个问题,即移动设备上的用户在 MVC 中遇到错误,在常规桌面上查看网站时不会发生该错误。 我可以通过使用 Chrome 的开发人员工具并应用默认之外的任何其他 UA 来始终如一地重现错误。
引发的基础异常是: ArgumentException: Illegal characters in path.
at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
at System.IO.Path.GetExtension(String path)
at System.Web.WebPages.DefaultDisplayMode.TransformPath(String virtualPath, String suffix)
at System.Web.WebPages.DefaultDisplayMode.GetDisplayInfo(HttpContextBase httpContext, String virtualPath, Func'2 virtualPathExists)
at System.Web.WebPages.DisplayModeProvider.GetDisplayInfoForVirtualPath(String virtualPath, HttpContextBase httpContext, Func'2 virtualPathExists, IDisplayMode currentDisplayMode, Boolean requireConsistentDisplayMode)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromGeneralName(ControllerContext controllerContext, List'1 locations, String name, String controllerName, String areaName, String cacheKey, String[]& searchedLocations)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations)
at System.Web.Mvc.VirtualPathProviderViewEngine.FindPartialView(ControllerContext controllerContext, String partialViewName, Boolean useCache)
at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClass2.<FindPartialView>b__1(IViewEngine e)
at System.Web.Mvc.ViewEngineCollection.Find(Func'2 lookup, Boolean trackSearchedPaths)
at System.Web.Mvc.ViewEngineCollection.FindPartialView(ControllerContext controllerContext, String partialViewName)
at System.Web.Mvc.Html.TemplateHelpers.ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, String templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames, GetDefaultActionsDelegate getDefaultActions)
at System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData, ExecuteTemplateDelegate executeTemplate)
at System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData)
at System.Web.Mvc.Html.TemplateHelpers.TemplateFor[TContainer,TValue](HtmlHelper'1 html, Expression'1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData, TemplateHelperDelegate templateHelper)
at System.Web.Mvc.Html.TemplateHelpers.TemplateFor[TContainer,TValue](HtmlHelper'1 html, Expression'1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData)
at System.Web.Mvc.Html.DisplayExtensions.DisplayFor[TModel,TValue](HtmlHelper'1 html, Expression'1 expression)
使用 fiddler,将成功请求与失败请求进行比较时,请求的唯一区别是用户代理(以及 jQuery 作为查询字符串参数的一部分附加的缓存无效化程序)。
为什么只更改 UA 会导致此异常,我如何避免此问题,而无需为正在和可能发生的每个位置将特定的解决方法写入系统?
我遇到了完全相同的问题,并修复了它。
我的问题是在我的视图模型中使用了yield
块:
控制器:
var vm = new BigVM {
SmallVMs = BuildSmallOnes()
};
return View(vm);
private IEnumerable<SmallVM> BuildSmallOnes()
{
// complex logic
yield return new SmallVM(1);
yield return new SmallVM(2);
}
视图:
@model BigVM
@Html.DisplayFor(x => x.SmallVMs) <-- died
令人费解的是,这适用于台式机,但不适用于iPad和iPhone,引用完全相同的堆栈跟踪。 这里和这里都报告了类似的问题。通过添加.ToList()
调用解决了该问题,因此:
var vm = new BigVM {
SmallVMs = BuildSmallOnes().ToList()
};
据推测,编译器生成的用于表示收益块的类包含某些用户代理不喜欢的一些字符。 包含 ToList() 调用会改用 List<>。
我们遇到此问题的原因是引入了用于单独处理移动设备的多视图和显示模式提供程序。此代码仍在 .NET 4 中,但已弃用。
可以在此处找到完全禁用该功能的解决方案。路径中的非法字符取决于用户代理?