2014-12-15 12 views
9

Mam problem z tym, że użytkownicy urządzeń mobilnych napotykają błąd w MVC, który nie występuje podczas przeglądania witryny na zwykłym pulpicie. Mogę konsekwentnie odtworzyć błąd za pomocą narzędzi programistycznych Chrome i stosując dowolną inną UA niż domyślną.Agent użytkownika powoduje wyświetlanie MVC ArgumentException: Niedozwolone znaki na ścieżce

Podstawowym wyjątek rzucony jest: 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)

Korzystanie Skrzypek, jedyną różnicą w żądaniach przy porównywaniu udanej jeden do nieudanej zamówienie jest User-Agent (a buster cache dołączany przez jQuery jako część parametry ciągu zapytania).

Dlaczego zmienia się tylko UU powodujące ten wyjątek i jak mogę uniknąć tego problemu bez pisania konkretnego zadania w systemie dla każdego miejsca, w którym jest i może wystąpić?

+0

Czy znalazłeś rozwiązanie tego problemu? –

+0

@RomanMik - Znalazłem tę samą pracę, co CSJ, poniżej której należy unikać bloków wydajności w moich modelach widoku. Po zmianie kodu w celu zmaterializowania listy zamiast wykorzystania wydajności problem został rozwiązany. Nadal nie do końca rozumiem, dlaczego tak się dzieje w .NET z niektórymi programami użytkownika, ale przynajmniej istnieje standardowy sposób obejścia tego. – SignalRichard

+0

Znalazłem inne rozwiązanie związane z ASP.NET DisplayModeProvider, które udostępniłem w pokrewnym artykule SO http://stackoverflow.com/questions/33694842/illegal-characters-in-path-depending-on-user-agent/40229384#40229384 –

Odpowiedz

9

Miałem dokładnie ten sam problem i naprawiłem go.

Moim problemem okazało się zastosowanie yield bloku w moim viewmodel:

Kontroler:

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); 
} 

Widok:

@model BigVM 
@Html.DisplayFor(x => x.SmallVMs) <-- died 

niewytłumaczalny sposób, to pracował dla komputerów stacjonarnych, ale nie na iPady i iPhone'y, powołując się na dokładnie ten sam stacktrace. Podobne problemy zgłaszano here i here. Problem został rozwiązany przez dodanie .ToList() połączenia, a więc:

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

Przypuszczalnie klasa że kompilator generuje do reprezentowania bloku plastyczności zawiera pewne znaki, że niektóre aplikacje klienckie po prostu nie lubię. W tym wywołaniu ToList() jest używana lista> <>.

+0

'ToList()' naprawiono problem dla mnie też. Samo użycie 'Where (...)' wydaje się działać poprawnie (więc rzeczywisty typ przekazany do widoku to 'WhereListIterator '), ale po zastosowaniu 'OrderBy (...). Take (...)' (so wynikiem końcowym jest "Enumerable. ...'), widok rozbił się na urządzeniach mobilnych. –

+0

Sądzę, że problem istnieje dla kilku typów IEnumerable ; Może przy użyciu IList (i tym samym zatrzymując się od zapomnienia 'ToList()') w widoku modeli powinna być "najlepsza praktyka", aby stworzyć sieć bezpieczeństwa czasu kompilacji? –

+0

Po prostu miałem ten sam problem. IEnumerable i wydajność używana przez konstruktora viewmodel. Czy ktoś wie, co dokładnie powoduje problem? To pachnie jak błąd w silniku widoku. –

Powiązane problemy