tutorial net mvc form example español create asp asp.net-mvc asp.net-mvc-5 routing viewengine

asp.net-mvc - form - sql server asp net mvc



Busque archivos de visualización en una ubicación personalizada solo para el área especificada en MVC 5 (2)

Estoy buscando anular el ''ViewEngine'' para MVC5 de una manera que primero encuentre mis páginas ... que ya he fallado.

Segundo, solo opera en una sola área {root} / {area} / {controller} / {action} / {etc.}

en cuanto lo busqué en Google, encontré varios temas y respuestas, pero no se ajustaban a mi necesidad. así que prefiero preguntarlo aquí, tal vez estoy equivocado con algo ...

public class CustomAreaViewEngine:RazorViewEngine { public CustomAreaViewEngine() { var viewLocations = new[] { "~/App/pages/{1}/{0}.cshtml", "~/App/pages/{1}/{0}.vbhtml" }; AreaMasterLocationFormats = viewLocations; AreaPartialViewLocationFormats = viewLocations; AreaViewLocationFormats = viewLocations; } public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) { var viewEngineResult = base.FindPartialView(controllerContext, partialViewName, useCache); return viewEngineResult; } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { controllerContext.RouteData.Values["controller"] = controllerContext.RouteData.Values["controller"].ToString().ToLower(); var viewEngineResult = base.FindView(controllerContext, viewName, masterName, useCache); return viewEngineResult; } }

El método ''FindView'' devuelve vacío [primer problema]

Configuración global:

AreaRegistration.RegisterAllAreas(); ViewEngines.Engines.Add(new CustomAreaViewEngine()); // Look View Inside App/Pages/{1}/{0}.cshtml/.vbhtml

Mi jerarquía

Root --/App --/--/pages --/--/shared (but not that shared) --/... --/Area --/--/View --/--/--/Controller --/--/--/View(MVC BASED HIERARCHY, I Don''t want to use in most case, and redirect to App) --/--/--/... --/--/... --/Controller --/View --/--/...(MVC BASED HIERARCHY) --/...

EDICIONES:

EDIT1:

Cambios que hice debido a respuestas de @James Ellis-Jones:

Imágenes: Mi configuración de ruta: Área proporcionada Configuración de ruta: Configuración global: Mi motor de visualización:

aún cuando uso http://localhost:1422/view/home/index recibo un error, que existe en mi otro hogar (View, relacionado con el controlador principal, no el controlador de área). Trae un archivo incorrecto.

Otro problema que descubrí, que tampoco funcionó

Mis espacios de nombres estaban mal en la última edición, y los cambié, pero tampoco funcionó.

namespaces: new[] { "RavisHSB.Areas.View.Controllers" }

EDIT2:

Cambios que hice debido a @ CarlosFernández responde:

Añado ViewEngines.Engines.Clear(); de alguna manera fue un paso adelante. pero todavía no funciona.

New Global.aspx: Y me enfrento a este nuevo error:


Pruebe esto: en RouteConfig.cs, donde está configurando la ruta que enlaza con un controlador en el que desea encontrar la ubicación de vista personalizada, agregue esto:

var route = routes.MapRoute(<route params here>); route.DataTokens["area"] = "AreaName";

Esto le indicará a MVC que cuando sigas esta ruta, irás al área ''AreaName''. Luego, buscará puntos de vista en esa área. Su ViewEngine personalizado solo afectará las ubicaciones de visualización cuando MVC las busque en algún área. De lo contrario, no tendrá ningún efecto, ya que las listas de formato de ubicación para las áreas son las únicas que anula.


Intenta personalizar este código para tu motor

Actualización # 1

private static readonly List<string> EmptyLocations; public MyEngine() { ViewLocationFormats = new[] { "~/App/Pages/{1}/{0}.cshtml", "~/App/Pages/{1}/{0}.vbhtml" }; } protected override bool FileExists(ControllerContext controllerContext, string virtualPath) { try { return System.IO.File.Exists(controllerContext.HttpContext.Server.MapPath(virtualPath)); } catch (HttpException exception) { if (exception.GetHttpCode() != 0x194) { throw; } return false; } catch { return false; } } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { var strArray = new List<string>(); var strArray2 = new List<string>(); if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (string.IsNullOrEmpty(viewName)) { throw new ArgumentException("viewName must be specified.", "viewName"); } var controllerName = controllerContext.RouteData.GetRequiredString("controller"); var viewPath = ""; var viewLocation = ViewLocationFormats; var masterLocation = MasterLocationFormats; var area = ""; if (controllerContext.RouteData.DataTokens.Keys.Any(x => x.ToLower() == "area")) { area = controllerContext.RouteData.DataTokens.FirstOrDefault(x => x.Key.ToLower() == "area").Value.ToString(); viewLocation = AreaViewLocationFormats; masterLocation = AreaMasterLocationFormats; } viewPath = GetPath(controllerContext, viewLocation, area, viewName, controllerName, "TubaSite_View", useCache, strArray); var masterPath = GetPath(controllerContext, masterLocation, area, masterName, controllerName, "TubaSite_Master", useCache, strArray2); if (!string.IsNullOrEmpty(viewPath) && (!string.IsNullOrEmpty(masterPath) || string.IsNullOrEmpty(masterName))) { return new ViewEngineResult(this.CreateView(controllerContext, viewPath, masterPath), this); } if (string.IsNullOrEmpty(viewPath)) { throw new Exception(String.Format("Page Not Found - {0} {1}", masterName, masterPath)); } return new ViewEngineResult(strArray.Union<string>(strArray2)); } public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) { var strArray = new List<string>(); if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (string.IsNullOrEmpty(partialViewName)) { throw new ArgumentException("partialViewName must be specified.", "partialViewName"); } var requiredString = controllerContext.RouteData.GetRequiredString("controller"); var partialViewLocation = PartialViewLocationFormats; var area = ""; if (controllerContext.RouteData.DataTokens.Keys.Any(x => x.ToLower() == "area")) { area = controllerContext.RouteData.DataTokens.FirstOrDefault(x => x.Key.ToLower() == "area").Value.ToString(); partialViewLocation = AreaPartialViewLocationFormats.Union(PartialViewLocationFormats).ToArray(); } var partialViewPath = ""; partialViewPath = GetPath(controllerContext, partialViewLocation, area, partialViewName, requiredString, "TubaSite_Partial", false, strArray); return string.IsNullOrEmpty(partialViewPath) ? new ViewEngineResult(strArray) : new ViewEngineResult(CreatePartialView(controllerContext, partialViewPath), this); } private string GetPath(ControllerContext controllerContext, string[] locations, string area, string name, string controllerName, string cacheKeyPrefix, bool useCache, List<string> searchedLocations) { searchedLocations = EmptyLocations; if (string.IsNullOrEmpty(name)) { return string.Empty; } if ((locations == null) || (locations.Length == 0)) { throw new InvalidOperationException("Path not found."); } var flag = IsSpecificPath(name); var key = CreateCacheKey(cacheKeyPrefix, name, flag ? string.Empty : controllerName); if (useCache) { var viewLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, key); if (viewLocation != null) { return viewLocation; } } if (!flag) { return GetPathFromGeneralName(controllerContext, locations, area, name, controllerName, key, searchedLocations); } return GetPathFromSpecificName(controllerContext, name, key, searchedLocations); } private static bool IsSpecificPath(string name) { var ch = name[0]; if (ch != ''~'') { return (ch == ''/''); } return true; } private string CreateCacheKey(string prefix, string name, string controllerName) { return string.Format(CultureInfo.InvariantCulture, ":ViewCacheEntry:{0}:{1}:{2}:{3}", GetType().AssemblyQualifiedName, prefix, name, controllerName); } private string GetPathFromGeneralName(ControllerContext controllerContext, IEnumerable<string> locations, string area, string name, string controllerName, string cacheKey, List<string> searchedLocations) { if (locations == null) throw new ArgumentNullException("locations"); if (searchedLocations == null) searchedLocations = new List<string>(); var virtualPath = string.Empty; var locationData = locations.Select( t => string.Format(CultureInfo.InvariantCulture, t, new object[] { name, controllerName })).ToList(); foreach (var str2 in locationData) { if (FileExists(controllerContext, str2)) { virtualPath = str2; ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, cacheKey, virtualPath); return virtualPath; } searchedLocations.Add(str2); } return virtualPath; } private string GetPathFromSpecificName(ControllerContext controllerContext, string name, string cacheKey, List<string> searchedLocations) { var virtualPath = name; if (!FileExists(controllerContext, name)) { virtualPath = string.Empty; searchedLocations = new List<string>() { name }; } ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, cacheKey, virtualPath); return virtualPath; } }

y también para el último error que has obtenido, puedes usar esta configuración

<configSections> <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> </sectionGroup> </configSections> <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.Optimization" /> </namespaces> </pages> </system.web.webPages.razor>