Asp.net mvc 将物理文件和动态文件合并为一个文件
我需要把一堆文件合并成一个“文件”。但我也需要其中一些文件是动态的,所以我有返回动态资源的操作。例如Asp.net mvc 将物理文件和动态文件合并为一个文件,asp.net-mvc,asp.net-mvc-3,asp.net-mvc-2,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 3,Asp.net Mvc 2,Asp.net Mvc 4,我需要把一堆文件合并成一个“文件”。但我也需要其中一些文件是动态的,所以我有返回动态资源的操作。例如 [OutputCache(VaryByParam = "culture", Duration = 3600)] public ActionResult Settings(string culture) { CultureInfo cultureInfo; try { cultureInfo = new CultureInfo(culture); }
[OutputCache(VaryByParam = "culture", Duration = 3600)]
public ActionResult Settings(string culture)
{
CultureInfo cultureInfo;
try
{
cultureInfo = new CultureInfo(culture);
}
catch
{
cultureInfo = Configuration.Current.DefaultCulture;
}
var sb = new StringBuilder();
sb.AppendFormat("Cms.Settings.Language = '{0}';", cultureInfo.TwoLetterISOLanguageName);
sb.AppendFormat("Cms.Settings.DayNames = [{0}];", string.Join(",", cultureInfo.DateTimeFormat.DayNames.Select(d => "\"" + d + "\"")));
sb.AppendFormat("Cms.Settings.ShortDayNames = [{0}];", string.Join(",", cultureInfo.DateTimeFormat.AbbreviatedDayNames.Select(d => "\"" + d + "\"")));
sb.AppendFormat("Cms.Settings.FirstDay = {0};", (int)cultureInfo.DateTimeFormat.FirstDayOfWeek);
sb.AppendFormat("Cms.Settings.ShortMonthNames = [{0}];", string.Join(",", cultureInfo.DateTimeFormat.AbbreviatedMonthNames.Take(12).Select(m => "\"" + m + "\"")));
var languages = new[]{cultureInfo.TwoLetterISOLanguageName};
var keys = translator.GetKeys(languages[0]);
foreach (var key in keys)
{
sb.AppendFormat("Cms.Settings.Texts['{0}'] = '{1}';", key, translator.GetText(key, key, languages));
}
// TODO: from settings
sb.AppendFormat("Cms.Settings.IconDir = '{0}';", VirtualPathUtility.ToAbsolute("~/img/icons/"));
return JavaScript(sb.ToString());
}
我想做的是将这些物理文件和ActionResults合并成一个“文件”。我已经做了这个动作来进行合并,但是我不知道通过路径获得动作输出的简单方法
// files is like "jquery.js,/js/settings?culture=fi,jquery-ui.js,..."
[OutputCache(VaryByParam = "files", Duration=3600)]
public ActionResult Bundle(string files)
{
var paths = files.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var sb = new StringBuilder();
foreach (var path in paths)
{
appendFile(sb, path);
}
return JavaScript(sb.ToString());
}
private void appendFile(StringBuilder sb, string path)
{
if (/* path is file on disk */)
{
var filename = Server.MapPath(path);
if (!System.IO.File.Exists(filename))
{
return;
}
sb.Append(System.IO.File.ReadAllText(filename));
}
else if(/* is action */)
{
// how do I get the output?
var output = getActionOutput(path);
sb.Append(output);
}
}
我尝试的另一个选项是对动态文件使用VirtualPathProvider,但由于某些原因,没有对不在磁盘上的文件调用“GetFile”
public class JsVirtualPathProvider : VirtualPathProvider
{
public override bool FileExists(string virtualPath)
{
if (virtualPath == "~/js/settings/fi.js")
{
// this was called
return true;
}
return base.FileExists(virtualPath);
}
public override VirtualFile GetFile(string virtualPath)
{
// never called for this "file"?
if (virtualPath == "~/js/settings/fi.js")
{
return new JsFile(virtualPath, "Cms.Settings.Foo = 'Bar';");
}
return base.GetFile(virtualPath);
}
class JsFile : VirtualFile
{
private readonly string content;
public JsFile(string virtualPath, string content) : base(virtualPath)
{
this.content = content;
}
public override Stream Open()
{
return new MemoryStream(Encoding.UTF8.GetBytes(content), false);
}
}
}
将物理文件与动态/虚拟文件相结合的最简单方法是什么?我得到了一个带有以下代码的操作输出
else if(/* is action */)
{
// how do I get the output?
// You need to send an HTTP request (for example using WebClient)
// to fetch the result of the execution of this action
...
}
var url = string.Format("{0}://{1}", Request.Url.Scheme, Request.Url.Host);
if (Request.Url.Port != 80)
{
url += ":" + Request.Url.Port;
}
url += path;
var writer = new StringWriter(sb);
var httpContext = new HttpContext(new HttpRequest("", url, ""), new HttpResponse(writer));
HttpContextBase httpContextBase = new HttpContextWrapper(httpContext);
var routeData = System.Web.Routing.RouteTable.Routes.GetRouteData(httpContextBase);
var handler = RouteData.RouteHandler.GetHttpHandler(new RequestContext(httpContextBase,routeData));
handler.ProcessRequest(httpContext);
由于某种原因,被调用操作(设置)中的QueryStringValueProvider具有调用操作(捆绑)的值,因此我将路径更改为/js/Settings/{culture}
(以前的/js/Settings?culture={culture}
)