【问题标题】:User Agent Causes MVC DisplayFor ArgumentException: Illegal characters in path用户代理导致 MVC DisplayFor ArgumentException:路径中有非法字符
【发布时间】:2014-12-15 15:09:07
【问题描述】:

我遇到了一个问题,即移动设备上的用户在 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,在比较成功请求和失败请求时,请求的唯一区别是 User-Agent(以及由 jQuery 作为查询字符串参数的一部分附加的缓存破坏器)。

为什么只更改 UA 会导致此异常,我如何避免此问题,而无需针对每个可能发生的位置在系统中编写特定的解决方法?

【问题讨论】:

  • 您找到解决方案了吗?
  • @RomanMik - 我实际上发现了与下面的 CSJ 相同的解决方法,即避免在我的视图模型中使用屈服块。在我更改代码以实现列表而不是使用 yield 后,问题得到了解决。我仍然不完全理解为什么在某些用户代理的 .NET 中会发生这种情况,但至少有一种标准的方法可以解决它。
  • 我找到了一个与 ASP.NET DisplayModeProvider 相关的不同解决方案,我在相关 SO 文章 stackoverflow.com/questions/33694842/…987654321@ 中分享了该解决方案

标签: c# asp.net asp.net-mvc user-agent


【解决方案1】:

我遇到了完全相同的问题,并解决了它。

我的问题原来是在我的视图模型中使用了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 上却失败了,理由是完全相同的堆栈跟踪。 herehere 报告了类似的问题。通过添加.ToList() 调用解决了这个问题,因此:

var vm = new BigVM {
    SmallVMs = BuildSmallOnes().ToList()
};

大概编译器生成的代表 yield 块的类包含一些用户代理不喜欢的字符。包括 ToList() 调用使用 List 代替。

【讨论】:

  • ToList() 也为我解决了这个问题。仅使用Where(...) 似乎可以正常工作(因此传递给视图的实际类型是WhereListIterator&lt;T&gt;),但是在应用OrderBy(...).Take(...) 之后(因此最终结果是Enumerable.&lt;TakeIterator&gt;...),视图在移动设备上崩溃了。跨度>
  • 我猜这个问题存在于几个 IEnumerable 类型;也许在视图模型中使用 IList(从而防止您忘记ToList())应该是创建编译时安全网的“最佳实践”?
  • 我刚刚遇到了同样的问题。视图模型构建器使用的 IEnumerable 和产量。有谁知道究竟是什么导致了这个问题?这闻起来像视图引擎中的错误。
  • 救命稻草。我不知道类名最终成为路径。这有点疯狂。
【解决方案2】:

我认为我们遇到此问题的原因是为分别处理移动设备而引入的 MultipleViews 和 DisplayMode 提供程序。这是仍在 .NET 4 中但已被弃用的代码。

可以在此处找到完全禁用该功能的解决方案。 Illegal characters in path depending on User-Agent?

【讨论】:

  • 欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.
  • 当然。真的是想作为一个有用的评论,但把它作为答案,因为这里没有真正活跃,也不需要代表分数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多