Включение статического html-файла из ~/Content в представление ASP.NET MVC
У меня есть главная страница в моем проекте, которая содержит некоторую информацию об авторских правах на сайт и некоторые контактные данные. Я хотел бы вынуть его из главной страницы и поместить в статические файлы (по какой-то причине эти файлы должны быть помещены в папку ~/Content). Есть ли способ, которым я могу сказать, на мой взгляд, что-то вроде
<% Html.Include("~/Content/snippet.html") %> // not a real code
?
5 ответов
Вам лучше использовать частичное представление (даже если оно содержит только статический текст) и включить его в Html.Partial
помощник. Но если вы настаиваете:
<%= File.ReadAllText(Server.MapPath("~/Content/snippet.html")) %>
Если вы находитесь в.Net MVC 5 и хотите включить файл HTML в частичный файл без Razor, который его отображает:
@Html.Raw(File.ReadAllText(Server.MapPath("~/Views/Shared/ICanHaz.html")))
Используйте свой собственный движок просмотра
с помощью
@Html.Partial("_CommonHtmlHead")
как
/Views/Shared/_CommonHtmlHead.html
или же
/Views/MyArea/Shared/_CommonHtmlHead.htm
это лучшее для меня.
Создание собственного механизма просмотра для этого с использованием восходящего класса System.Web.Mvc.VirtualPathProviderViewEngine представляется относительно простым:
/// <summary>
/// Simple render engine to load static HTML files, supposing that view files has the html/htm extension, supporting replacing tilda paths (~/MyRelativePath) in the content
/// </summary>
public class HtmlStaticViewEngine : VirtualPathProviderViewEngine
{
private static readonly ILog _log = LogManager.GetLogger(typeof (HtmlStaticViewEngine));
protected readonly DateTime? AbsoluteTimeout;
protected readonly TimeSpan? SlidingTimeout;
protected readonly CacheItemPriority? Priority;
private readonly bool _useCache;
public HtmlStaticViewEngine(TimeSpan? slidingTimeout = null, DateTime? absoluteTimeout = null, CacheItemPriority? priority = null)
{
_useCache = absoluteTimeout.HasValue || slidingTimeout.HasValue || priority.HasValue;
SlidingTimeout = slidingTimeout;
AbsoluteTimeout = absoluteTimeout;
Priority = priority;
AreaViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.html",
"~/Areas/{2}/Views/{1}/{0}.htm",
"~/Areas/{2}/Views/Shared/{0}.html",
"~/Areas/{2}/Views/Shared/{0}.htm"
};
AreaMasterLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.html",
"~/Areas/{2}/Views/{1}/{0}.htm",
"~/Areas/{2}/Views/Shared/{0}.html",
"~/Areas/{2}/Views/Shared/{0}.htm"
};
AreaPartialViewLocationFormats = new[]
{
"~/Areas/{2}/Views/{1}/{0}.html",
"~/Areas/{2}/Views/{1}/{0}.htm",
"~/Areas/{2}/Views/Shared/{0}.html",
"~/Areas/{2}/Views/Shared/{0}.htm"
};
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.html",
"~/Views/{1}/{0}.htm",
"~/Views/Shared/{0}.html",
"~/Views/Shared/{0}.htm"
};
MasterLocationFormats = new[]
{
"~/Views/{1}/{0}.html",
"~/Views/{1}/{0}.htm",
"~/Views/Shared/{0}.html",
"~/Views/Shared/{0}.htm"
};
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.html",
"~/Views/{1}/{0}.htm",
"~/Views/Shared/{0}.html",
"~/Views/Shared/{0}.htm"
};
FileExtensions = new[]
{
"html",
"htm",
};
}
protected virtual string GetContent(string viewFilePath)
{
string result = null;
if (!string.IsNullOrWhiteSpace(viewFilePath))
{
if (_useCache)
{
result = TryCache(viewFilePath);
}
if (result == null)
{
using (StreamReader streamReader = File.OpenText(viewFilePath))
{
result = streamReader.ReadToEnd();
}
result = ParseContent(result);
if (_useCache)
{
CacheIt(viewFilePath, result);
}
}
}
return result;
}
static readonly Regex TildaRegularExpression = new Regex(@"~/", RegexOptions.Compiled);
/// <summary>
/// Finds all tilda paths in the content and replace it for current path
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
protected virtual string ParseContent(string content)
{
if (String.IsNullOrWhiteSpace(content))
{
return content;
}
string absolutePath = VirtualPathUtility.ToAbsolute("~/");
string result = TildaRegularExpression.Replace(content, absolutePath);
return result;
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
HttpContextBase httpContextBase = controllerContext.RequestContext.HttpContext;
string filePath = httpContextBase.Server.MapPath(partialPath);
string content = GetContent(filePath);
return new StaticView(content);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
HttpContextBase httpContextBase = controllerContext.RequestContext.HttpContext;
string result = null;
if (!string.IsNullOrWhiteSpace(masterPath))
{
string filePath = httpContextBase.Server.MapPath(masterPath);
result = GetContent(filePath);
}
string physicalViewPath = httpContextBase.Server.MapPath(viewPath);
result += GetContent(physicalViewPath);
return new StaticView(result);
}
protected virtual string TryCache(string filePath)
{
HttpContext httpContext = HttpContext.Current;
if (httpContext != null && httpContext.Cache != null)
{
string cacheKey = CacheKey(filePath);
return (string)httpContext.Cache[cacheKey];
}
return null;
}
protected virtual bool CacheIt(string filePath, string content)
{
HttpContext httpContext = HttpContext.Current;
if (httpContext != null && httpContext.Cache != null)
{
string cacheKey = CacheKey(filePath);
httpContext.Cache.Add(cacheKey, content, new CacheDependency(filePath), AbsoluteTimeout.GetValueOrDefault(Cache.NoAbsoluteExpiration), SlidingTimeout.GetValueOrDefault(Cache.NoSlidingExpiration), Priority.GetValueOrDefault(CacheItemPriority.AboveNormal), CacheItemRemovedCallback);
return true;
}
return false;
}
protected virtual string CacheKey(string serverPath)
{
return serverPath;
}
protected virtual void CacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason)
{
_log.InfoFormat("CacheItemRemovedCallback(string key='{0}', object value = ..., {1} reason={2})", key, reason.GetType().Name, reason);
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ViewEngines.Engines.Add(new HtmlStaticViewEngine(new TimeSpan(12,0,0,0)));
}
}
public class StaticView : IView
{
private readonly string _text;
public StaticView(string text)
{
_text = text;
}
public void Render(ViewContext viewContext, TextWriter writer)
{
if (! string.IsNullOrEmpty(_text))
{
writer.Write(_text);
}
}
}
ПРИМЕЧАНИЕ. Этот код протестирован только с простым использованием для рендеринга частичных представлений.
Есть ли причина, по которой вы держите содержимое в файле HTML, а не в частичном представлении?
Если вы создаете файл с именем snippet.ascx
в вашем Views/Shared
папка, которую вы можете импортировать содержимое этого snippet.ascx
файл в любом виде с помощью <% Html.RenderPartial("snippet"); %>
Включение статического html-файла в MVC View выглядит следующим образом:
<!-- #include virtual="~\Content\snippet.htm" -->
Для страницы ASP .NET Core 3.1 Razor это можно сделать следующим образом:
@Html.Raw(System.IO.File.ReadAllText("wwwroot/Content/snippet.html"));
См. Документацию по статическим файлам здесь:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-3.1