2012-05-24 4 views
0

한 묶음의 파일을 하나의 "파일"에 결합해야합니다. 그러나 동적 인 파일도 필요하므로 동적 인 리소스를 반환하는 액션이 ​​있습니다. 예 :실제 파일과 동적 파일을 하나의 파일로 결합하십시오.

[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); 
     } 
    } 
} 

실제 파일을 동적/가상 파일과 결합하는 가장 쉬운 방법은 무엇입니까?

답변

0

다음 코드를 사용하여 작업 결과를 얻었습니다. 어떤 이유에서 호출 된 액션의 QueryStringValueProvider (설정)에 대한

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); 

는 호출 액션 (번들)의 값을 가지고 있었다 그래서 나는 (이전 /js/settings?culture={culture}) /js/settings/{culture}

을 경로 변경
-1
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 
    ... 
} 
관련 문제