RazorGenerator를 사용하여 사용자 정의 (파생 된) RazorViewEngine 및 프리 컴파일 된 뷰를 사용하려고합니다.사용자 정의 RazorViewEngine 및 RazorGenerator 프리 컴파일 된 뷰 사용
일부 컨텍스트 :
우리는 우리가 여러 클라이언트 구현에 사용하는 기본 제품이있다. 이를 통해 핵심 뷰 집합이 생깁니다. 대부분의 견해가 대부분의 경우에 효과적입니다. 지금 당장 우리는 각각의 새로운 솔루션에 대한 기존 뷰를 복사하고 필요에 따라 수정합니다. 이는 95 %의 조회수가 클라이언트간에 동일하고 5 %가 변경되는 결과를 가져옵니다.
기본 뷰 집합을 DLL로 컴파일하고 클라이언트 전체에서 다시 사용하고 싶습니다. 지금까지 나는 RazorGenerator를 사용하여 잘 작동하고 있습니다.
이제 다음 단계는보기의 사용자 지정 (재정의)을 허용하는 것입니다. 그래도주의 사항이 있습니다. 우리의 응용 프로그램에는 사용자가 속한 두 가지 "모드"가 있습니다.이 모드에는 다른보기가 필요할 수 있습니다.
RazorGeneratorView에서 파생 클래스를 만들었습니다. 이 뷰는 기본적으로 Autofac이 해결하는 UserProfile 객체에서 "OrderingMode"를 검사합니다. 모드에 따라 뷰 해결을 위해 경로 로케이터가 대체됩니다.
개별 클라이언트 응용 프로그램이라는 생각은 기존보기 폴더에서 먼저보기를 확인하려고 시도합니다. Views/{OrderingMode}/{Controller}/{View} .cshtml의 하위 디렉토리에만 추가합니다.
보기가 발견되지 않으면 컴파일 된 라이브러리 (핵심보기)를 볼 것입니다.
이렇게하면 클라이언트의 필요에 따라 개별보기/부분을 재정의 할 수 있습니다.
public PosViewEngine() : base()
{
//{0} = View Name
//{1} = ControllerName
//{2} = Area Name
AreaViewLocationFormats = new[]
{
//First look in the hosting application area folder/Views/ordering type
//Areas/{AreaName}/{OrderType}/{ControllerName}/{ViewName}.cshtml
"Areas/{2}/Views/%1/{1}/{0}.cshtml",
//Next look in the hosting application area folder/Views/ordering type/Shared
//Areas/{AreaName}/{OrderType}/{ControllerName}/{ViewName}.cshtml
"Areas/{2}/Views/%1/Shared/(0}.cshtml",
//Finally look in the IMS.POS.Web.Views.Core assembly
"Areas/{2}/Views/{1}/{0}.cshtml"
};
//Same format logic
AreaMasterLocationFormats = AreaViewLocationFormats;
AreaPartialViewLocationFormats = new[]
{
//First look in the hosting application area folder/Views/ordering type
//Areas/{AreaName}/{OrderType}/{ControllerName}/Partials/{PartialViewName}.cshtml
"Areas/{2}/Views/%1/{1}/Paritals/{0}.cshtml",
//Next look in the hosting application area folder/Views/ordering type/Shared
//Areas/{AreaName}/{OrderType}/{ControllerName}/{ViewName}.cshtml
"Areas/{2}/Views/%1/Shared/(0}.cshtml",
//Finally look in the IMS.POS.Web.Views.Core
"Areas/{2}/Views/{1}/{0}.cshtml"
};
ViewLocationFormats = new[]
{
"Views/%1/{1}/{0}.cshtml",
"Views/%1/Shared/{0}.cshtml",
"Views/{1}/{0}.cshtml",
"Views/Shared/{0}.cshtml"
};
MasterLocationFormats = ViewLocationFormats;
PartialViewLocationFormats = new[]
{
"Views/%1/{1}/Partials/{0}.cshtml",
"Views/%1/Shared/{0}.cshtml",
"Views/{1}/Partials/{0}.cshtml",
"Views/Shared/{0}.cshtml"
};
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return base.CreatePartialView(controllerContext, partialPath.ReplaceOrderType(CurrentOrderingMode()));
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
OrderType orderType = CurrentOrderingMode();
return base.CreateView(controllerContext, viewPath.ReplaceOrderType(orderType), masterPath.ReplaceOrderType(orderType));
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
return base.FileExists(controllerContext, virtualPath.Replace("%1/",string.Empty));
}
private OrderType CurrentOrderingMode()
{
OrderType result;
_profileService = DependencyResolver.Current.GetService<IUserProfileService>();
if (_profileService == null || _profileService.OrderingType == 0)
{
IApplicationSettingService settingService =
DependencyResolver.Current.GetService<IApplicationSettingService>();
result =
settingService.GetApplicationSetting(ApplicationSettings.DefaultOrderingMode)
.ToEnumTypeOf<OrderType>();
}
else
{
result = _profileService.OrderingType;
}
return result;
}
}
여기 RazorGenerator가 ViewEngine을 등록하는 데 사용하는 StartUp 클래스가 있습니다.
- 이 코드는 (필자는 PosViewEngine 등록 후) 마지막으로 실행되고, 이것이 제공되면 첫번째 해결됩니다 엔진 인 의미 (첫 번째 위치에서 엔진을 삽입합니다
public static class RazorGeneratorMvcStart { public static void Start() { var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) { UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal }; ViewEngines.Engines.Insert(0, engine); // StartPage lookups are done by WebPages. VirtualPathFactoryManager.RegisterVirtualPathFactory(engine); } }
문제는 응답). 이것은보기를 찾는 것을 끝내 - 그것은 핵심보기입니다.
내 사용자 지정보기 엔진 첫째 첫째 후 RazorGenerator 엔진
나는 FileExists에 예외로 끝날public static void Start() { var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) { UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal }; ViewEngines.Engines.Clear(); ViewEngines.Engines.Insert(0, new PosViewEngine()); ViewEngines.Engines.Insert(1, engine); // StartPage lookups are done by WebPages. VirtualPathFactoryManager.RegisterVirtualPathFactory(engine); }
(ControllerContext controllerContext, 문자열 virtualPath를 등록하려면 시작 프로그램의 코드를 변경하는 경우) 방법 - "상대 가상 경로 'Views/Account/LogOn.cshtml'은 허용되지 않습니다."
분명히 물리적 경로와 가상 경로가 함께 혼합되는 것과 관련이 있습니다.
누군가 다른 사람이 똑같은 짓을하려 한 것처럼 보입니다. here하지만 이것에 대한 대답은 없었습니다.
exiting 뷰에 맞춤 콘텐츠를 추가 할 수 있습니까? 나는 이것을 게시했다. http://stackoverflow.com/questions/38303160/how-to-use-razor-to-process-dynamic-templates-included-in-web-page – Andrus
이 접근법이 아니다. 이는 컨트롤러 액션에 기본 뷰 집합을 제공하고 필요에 따라 오버라이드하는 오버 법칙입니다. 귀하의 질문에 대한 귀하의 자신의 속성과 RazorEngine 같은 속성을 통해 내용을 주입 뭔가를 노출하는 사용자 정의 기본보기를 사용하고 있습니다. – JDBennett