2014-12-15 3 views
9

휴대 기기 사용자가 일반 데스크톱에서 사이트를 볼 때 발생하지 않는 MVC 오류가 발생하는 문제가 있습니다. Chrome의 개발자 도구를 사용하고 기본값 이외의 다른 UA를 적용하여 일관되게 오류를 재현 할 수 있습니다.사용자 에이전트가 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)

, 실패한 요청에 대한 성공적인 비교 요청의 유일한 차이점은 사용자 에이전트 (과의 일환으로 jQuery를에 의해 추가 된 캐시 버스터입니다 쿼리 문자열 매개 변수).

이 예외의 원인이되는 UA 만 변경하는 이유는 무엇이며 발생 가능한 모든 장소에 대해 특정 작업을 시스템에 작성하지 않고이 문제를 방지하려면 어떻게해야합니까?

+0

해결 방법을 찾으셨습니까? –

+0

@RomanMik - 실제로 내 뷰 모델에서 수율 블록을 사용하지 않는 CSJ와 동일한 해결 방법을 발견했습니다. yield를 사용하는 대신 목록을 구체화하도록 코드를 변경 한 후 문제가 해결되었습니다. 여전히 .NET에서 특정 사용자 에이전트를 사용하는 이유를 완전히 이해하지 못하고 있지만 최소한이를 해결할 수있는 표준 방법이 있습니다. – SignalRichard

+0

관련 SO 기사에서 공유 한 ASP.NET DisplayModeProvider와 관련된 다른 해결책을 찾았습니다. http://stackoverflow.com/questions/33694842/illegal-characters-in-path-depending-on-user-agent/40229384#40229384 –

답변

9

나는 똑같은 문제가있어서 그것을 고쳤다.

내 문제는 내 뷰 모델에 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 

불가해이 데스크톱 위해 일했지만 실패 iPads와 iPhones의 경우 정확히 동일한 스택 추적을 인용합니다. 비슷한 문제가 herehere으로보고되었습니다. 문제는 따라서, .ToList() 전화를 추가함으로써 해결되었다 :

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

는 아마도 컴파일러가 항복 블록을 표현하기 위해 생성하는 클래스는 일부 사용자 에이전트 그냥 좋아하지 않아 일부 문자가 포함되어 있습니다. ToList() 호출을 포함하면 목록 <>이 대신 사용됩니다.

+0

ToList()는 나를 위해 문제도 해결했습니다. 'Where (...)'를 사용하는 것만으로도 잘 동작하는 것처럼 보입니다. (뷰에 전달 된 실제 타입은'WhereListIterator '입니다.)'OrderBy (...). Take (...)'를 적용한 후에 최종 결과는'Enumerable. ...'), 뷰가 모바일 장치에서 추락합니다. –

+0

IEnumerable 형식 중 일부에 대한 문제가 있다고 생각합니다. 어쩌면 뷰 모델에서 IList 을 사용하여 (따라서 ToList()를 잊어 버리는 것을 막음) 컴파일 타임 안전망을 만드는 것이 "우수 사례"여야 하는가? –

+0

방금 ​​전 똑같은 문제가있었습니다. IEnumerable 및 뷰 모델 작성자가 사용하는 출력. 정확히 누구가 문제를 일으키는 지 아는 사람이 있습니까? 이것은 뷰 엔진의 버그와 같은 냄새가납니다. –