ASP.NET MVC에서 "보기 검색"을 위한 사용자 지정 위치를 지정할 수 있습니까?
저는 제 mvc 프로젝트를 위해 다음과 같은 레이아웃을 가지고 있습니다.
- /컨트롤러
- /데모
- /Demo/DemoArea1 컨트롤러
- /Demo/DemoArea2 컨트롤러
- 기타...
- /보기
- /데모
- /Demo/DemoArea1/Index.aspx
- /Demo/DemoArea2/Index.aspx
하지만, 제가 이것을 가지고 있을 때.DemoArea1Controller
:
public class DemoArea1Controller : Controller
{
public ActionResult Index()
{
return View();
}
}
일반적인 검색 위치와 함께 "보기 '색인' 또는 마스터를 찾을 수 없음" 오류가 발생합니다.
"Demo" 보기 하위 폴더에서 "Demo" 네임스페이스 검색의 컨트롤러를 지정하려면 어떻게 해야 합니까?
WebFormViewEngine을 쉽게 확장하여 검색할 모든 위치를 지정할 수 있습니다.
public class CustomViewEngine : WebFormViewEngine
{
public CustomViewEngine()
{
var viewLocations = new[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx",
"~/AnotherPath/Views/{0}.ascx"
// etc
};
this.PartialViewLocationFormats = viewLocations;
this.ViewLocationFormats = viewLocations;
}
}
Global.asax.cs 에서 Application_Start 메서드를 수정하여 뷰 엔진을 등록해야 합니다.
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
}
이제 MVC 6에서IViewLocationExpander
뷰 엔진을 조작하지 않고 인터페이스를 조작할 수 있습니다.
public class MyViewLocationExpander : IViewLocationExpander
{
public void PopulateValues(ViewLocationExpanderContext context) {}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
return new[]
{
"/AnotherPath/Views/{1}/{0}.cshtml",
"/AnotherPath/Views/Shared/{0}.cshtml"
}; // add `.Union(viewLocations)` to add default locations
}
}
어디에{0}
대상 뷰 이름입니다.{1}
컨트롤러 이름 및{2}
지역명
사용자 자신의 위치 목록을 반환하고 기본값과 병합할 수 있습니다.viewLocations
(.Union(viewLocations)
) 또는 그냥 변경(viewLocations.Select(path => "/AnotherPath" + path)
).
MVC에 사용자 정의 뷰 위치 확장기를 등록하려면 다음 행을 추가합니다.ConfigureServices
의 방법.Startup.cs
파일:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new MyViewLocationExpander());
});
}
실제로 생성자에게 경로를 하드 코딩하는 것보다 훨씬 쉬운 방법이 있습니다.다음은 레이저 엔진을 확장하여 새 경로를 추가한 예입니다.여기에 추가한 경로가 캐시되는지 여부에 대해서는 잘 모르겠습니다.
public class ExtendedRazorViewEngine : RazorViewEngine
{
public void AddViewLocationFormat(string paths)
{
List<string> existingPaths = new List<string>(ViewLocationFormats);
existingPaths.Add(paths);
ViewLocationFormats = existingPaths.ToArray();
}
public void AddPartialViewLocationFormat(string paths)
{
List<string> existingPaths = new List<string>(PartialViewLocationFormats);
existingPaths.Add(paths);
PartialViewLocationFormats = existingPaths.ToArray();
}
}
그리고 당신의 Global.asax.cs .
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ExtendedRazorViewEngine engine = new ExtendedRazorViewEngine();
engine.AddViewLocationFormat("~/MyThemes/{1}/{0}.cshtml");
engine.AddViewLocationFormat("~/MyThemes/{1}/{0}.vbhtml");
// Add a shared location too, as the lines above are controller specific
engine.AddPartialViewLocationFormat("~/MyThemes/{0}.cshtml");
engine.AddPartialViewLocationFormat("~/MyThemes/{0}.vbhtml");
ViewEngines.Engines.Add(engine);
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
한 가지 주의할 점은 사용자 지정 위치의 루트에 ViewStart.cshtml 파일이 필요하다는 것입니다.
새 경로만 추가하려면 기본 뷰 엔진에 추가하고 다음 코드 줄을 사용할 수 있습니다.
ViewEngines.Engines.Clear();
var razorEngine = new RazorViewEngine();
razorEngine.MasterLocationFormats = razorEngine.MasterLocationFormats
.Concat(new[] {
"~/custom/path/{0}.cshtml"
}).ToArray();
razorEngine.PartialViewLocationFormats = razorEngine.PartialViewLocationFormats
.Concat(new[] {
"~/custom/path/{1}/{0}.cshtml", // {1} = controller name
"~/custom/path/Shared/{0}.cshtml"
}).ToArray();
ViewEngines.Engines.Add(razorEngine);
동일하게 적용됩니다.WebFormEngine
RazorViewEngine을 하위 분류하거나 완전히 교체하는 대신 기존 RazorViewEngine의 PartialViewLocationFormats 속성을 변경할 수 있습니다.이 코드는 Application_Start:
System.Web.Mvc.RazorViewEngine rve = (RazorViewEngine)ViewEngines.Engines
.Where(e=>e.GetType()==typeof(RazorViewEngine))
.FirstOrDefault();
string[] additionalPartialViewLocations = new[] {
"~/Views/[YourCustomPathHere]"
};
if(rve!=null)
{
rve.PartialViewLocationFormats = rve.PartialViewLocationFormats
.Union( additionalPartialViewLocations )
.ToArray();
}
마지막으로 확인한 바로는 View Engine을 직접 구축해야 합니다.RC1에서 쉽게 만들었는지는 모르겠지만요.
첫 번째 RC 이전에 제가 사용한 기본적인 접근 방식은 저만의 ViewEngine에서 컨트롤러의 네임스페이스를 분할하고 부품과 일치하는 폴더를 찾는 것이었습니다.
편집:
돌아가서 코드를 찾았습니다.일반적인 생각은 이렇습니다.
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
{
string ns = controllerContext.Controller.GetType().Namespace;
string controller = controllerContext.Controller.GetType().Name.Replace("Controller", "");
//try to find the view
string rel = "~/Views/" +
(
ns == baseControllerNamespace ? "" :
ns.Substring(baseControllerNamespace.Length + 1).Replace(".", "/") + "/"
)
+ controller;
string[] pathsToSearch = new string[]{
rel+"/"+viewName+".aspx",
rel+"/"+viewName+".ascx"
};
string viewPath = null;
foreach (var path in pathsToSearch)
{
if (this.VirtualPathProvider.FileExists(path))
{
viewPath = path;
break;
}
}
if (viewPath != null)
{
string masterPath = null;
//try find the master
if (!string.IsNullOrEmpty(masterName))
{
string[] masterPathsToSearch = new string[]{
rel+"/"+masterName+".master",
"~/Views/"+ controller +"/"+ masterName+".master",
"~/Views/Shared/"+ masterName+".master"
};
foreach (var path in masterPathsToSearch)
{
if (this.VirtualPathProvider.FileExists(path))
{
masterPath = path;
break;
}
}
}
if (string.IsNullOrEmpty(masterName) || masterPath != null)
{
return new ViewEngineResult(
this.CreateView(controllerContext, viewPath, masterPath), this);
}
}
//try default implementation
var result = base.FindView(controllerContext, viewName, masterName);
if (result.View == null)
{
//add the location searched
return new ViewEngineResult(pathsToSearch);
}
return result;
}
다음과 같은 방법을 사용해 보십시오.
private static void RegisterViewEngines(ICollection<IViewEngine> engines)
{
engines.Add(new WebFormViewEngine
{
MasterLocationFormats = new[] {"~/App/Views/Admin/{0}.master"},
PartialViewLocationFormats = new[] {"~/App/Views/Admin//{1}/{0}.ascx"},
ViewLocationFormats = new[] {"~/App/Views/Admin//{1}/{0}.aspx"}
});
}
protected void Application_Start()
{
RegisterViewEngines(ViewEngines.Engines);
}
참고: ASP.NET MVC 2의 경우 '영역'에서 보기를 위해 설정해야 하는 추가 위치 경로가 있습니다.
AreaViewLocationFormats
AreaPartialViewLocationFormats
AreaMasterLocationFormats
영역에 대한 뷰 엔진 작성은 Phil의 블로그에 설명되어 있습니다.
참고: 이 버전은 미리 보기 릴리스 1용이므로 변경될 수 있습니다.
여기에 있는 대부분의 답변은 전화로 기존 위치를 지웁니다.ViewEngines.Engines.Clear()
▁there다 이렇게 할 .이렇게 할 필요가 없습니다.
아래와 같이 새 위치를 기존 위치에 간단히 추가할 수 있습니다.
// note that the base class is RazorViewEngine, NOT WebFormViewEngine
public class ExpandedViewEngine : RazorViewEngine
{
public ExpandedViewEngine()
{
var customViewSubfolders = new[]
{
// {1} is conroller name, {0} is action name
"~/Areas/AreaName/Views/Subfolder1/{1}/{0}.cshtml",
"~/Areas/AreaName/Views/Subfolder1/Shared/{0}.cshtml"
};
var customPartialViewSubfolders = new[]
{
"~/Areas/MyAreaName/Views/Subfolder1/{1}/Partials/{0}.cshtml",
"~/Areas/MyAreaName/Views/Subfolder1/Shared/Partials/{0}.cshtml"
};
ViewLocationFormats = ViewLocationFormats.Union(customViewSubfolders).ToArray();
PartialViewLocationFormats = PartialViewLocationFormats.Union(customPartialViewSubfolders).ToArray();
// use the following if you want to extend the master locations
// MasterLocationFormats = MasterLocationFormats.Union(new[] { "new master location" }).ToArray();
}
}
의 이제위내사록프도구있을 할 수 .RazorViewEngine
Global.asax:
protected void Application_Start()
{
ViewEngines.Engines.Add(new ExpandedViewEngine());
// more configurations
}
MVC 5에서 이렇게 했어요.기본 위치를 지우고 싶지 않았습니다.
도우미 클래스:
namespace ConKit.Helpers
{
public static class AppStartHelper
{
public static void AddConKitViewLocations()
{
// get engine
RazorViewEngine engine = ViewEngines.Engines.OfType<RazorViewEngine>().FirstOrDefault();
if (engine == null)
{
return;
}
// extend view locations
engine.ViewLocationFormats =
engine.ViewLocationFormats.Concat(new string[] {
"~/Views/ConKit/{1}/{0}.cshtml",
"~/Views/ConKit/{0}.cshtml"
}).ToArray();
// extend partial view locations
engine.PartialViewLocationFormats =
engine.PartialViewLocationFormats.Concat(new string[] {
"~/Views/ConKit/{0}.cshtml"
}).ToArray();
}
}
}
Application_Start에서 다음을 수행합니다.
// Add ConKit View locations
ConKit.Helpers.AppStartHelper.AddConKitViewLocations();
언급URL : https://stackoverflow.com/questions/632964/can-i-specify-a-custom-location-to-search-for-views-in-asp-net-mvc
'programing' 카테고리의 다른 글
Xcode에서 Prefix.pch 파일은 무엇입니까? (0) | 2023.05.29 |
---|---|
iPhone 방향이 세로에서 가로로 변경될 때 HTML 글꼴 크기 유지 (0) | 2023.05.29 |
콘솔의 차이점은 무엇입니까?WriteLine() 대 Debug.줄 쓰기()? (0) | 2023.05.29 |
JSON 스키마 검증 (0) | 2023.03.06 |
jq: 중첩된 개체, 최상위 ID를 추출하고 내부 개체에서 값을 들어 올립니다. (0) | 2023.03.06 |