2014-12-15 3 views
9

У меня возникла проблема, когда пользователи на мобильных устройствах сталкиваются с ошибкой в ​​MVC, которая не возникает при просмотре сайта на обычном рабочем столе. Я могу последовательно воспроизвести ошибку с помощью инструментов разработчика Chrome и применения любых других UA, чем по умолчанию.User Agent вызывает MVC DisplayFor ArgumentException: Недопустимые символы в пути

Основополагающий исключение брошено является: 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)

Использование скрипача, единственное различие в запросах при сравнении удачную к необработанного запроса является User-Agent (и попойка кэша добавляется по JQuery как часть параметры строки запроса).

Почему только изменение UA вызывает это исключение и как я могу избежать этой проблемы без написания конкретной работы в системе для каждого места, где это и может произойти?

+0

Вы нашли решение на этом? –

+0

@RomanMik - я действительно нашел ту же работу, что и CSJ, ниже которой следует избегать использования блоков доходности в моих моделях просмотра. После того как я изменил код, чтобы материализовать этот список, вместо того, чтобы использовать доход, проблема была решена. Я до сих пор не совсем понимаю, почему это происходит в .NET с определенными пользовательскими агентами, но по крайней мере есть стандартный способ обойти его. – SignalRichard

+0

Я нашел другое решение, связанное с ASP.NET DisplayModeProvider, которое я поделил в связанной статье SO http://stackoverflow.com/questions/33694842/illegal-characters-in-path-depending-on-user-agent/40229384#40229384 –

ответ

9

У меня была такая же проблема и исправлена.

Моя проблема оказалась использование yield блока в моем ViewModel:

Контроллер:

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 

Необъяснимо, это работает для настольных компьютеров, но не для iPads и iPhones, ссылаясь на ту же самую стеклу. Аналогичные проблемы были сообщены here и here. Проблема была решена путем добавления .ToList() вызова, таким образом:

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

Предположительно класс, который компилятор генерирует для представления блока текучести включает в себя несколько символов, что некоторые агенты пользователя просто не нравятся. Включение вызова ToList() вместо этого использует список <>.

+0

'ToList()' исправил проблему и для меня. Просто использование 'Where (...)' похоже работает отлично (поэтому фактический тип, переданный в представление, является 'WhereListIterator '), но после применения 'OrderBy (...). Take (...)' (so конечный результат «Перечислимый. ...»), представление разбилось на мобильных устройствах. –

+0

Я думаю, проблема существует для нескольких типов IEnumerable ; Возможно, используя IList (и, таким образом, вы перестали забывать «ToList()')), модели просмотра должны быть «лучшей практикой» для создания защитной сетки времени компиляции? –

+0

У меня была такая же проблема. IEnumerable и выход, используемый конструктором viewmodel. Кто-нибудь знает, что именно вызывает проблему? Это пахнет ошибкой в ​​движке просмотра. –

Смежные вопросы