2013-03-28 174 views
0

當我從/ Content目錄向用戶提供JavaScript文件時,我想用該值替換該文件中的string標記,以便當用戶請求給定文件時,它具有所需的所有自定義設置。如何動態更改ASP.NET MVC中/ Content目錄中的文件?

我認爲這意味着我需要以某種方式將請求代理到/ Content目錄,執行動態插入並將文件提供給用戶。

  • 我有興趣將此插入作爲stream或作爲內存中的文件執行。我寧願使用流,因爲它可能更有效的記憶方式。

如何讓ASP.NET代理此目錄?

我已經嘗試

  1. 使用路由指向控制器

  2. WCF代理一個URL

但他們看起來是 「醜陋」 我和我我希望在項目中儘可能使這種插入/替換儘可能透明。

有沒有更清潔的方法?

回答

1

最簡單的方法是在控制器上創建一個動作。

public class JavascriptController : Controller 
{ 
    public ActionResult Load(string file) 
    { 
     var content = System.IO.File.ReadAllText(Server.MapPath(string.Format("~/Content/{0}", file))); 

     //make replacements io content here 

     return this.Content(content, "application/javascript"); 
    } 
} 

然後,您可以像這樣訪問的JavaScript(假設你有缺省路由):

http://localhost:53287/Javascript/Load?file=file.js 

其中file.js是您所請求的文件的名稱。

不要擔心的網址,你可以通過創建另一個途徑,如果必要

+0

謝謝。如果我還想要向供應商(Telerik)動態JavaScript文件發送請求,該怎麼辦?這不是在較低的水平上運作嗎? – LamonteCristo 2013-03-28 03:13:43

+0

你可以改變從文件中讀取所有文本的行,通過http請求文件內容..這是一個非常簡單的解決方案,但更多的開銷(每個請求,實際上會被處理兩次) – 2013-03-28 03:40:37

1

下面是幾種可能的答案我上面張貼的答案,同時考慮到有關動態JavaScript您的評論定製的。

首先,我不知道的方式做到這一點特別是使用兩種MVC或WCF ..只有我知道該怎麼做,這是一個低級別的HttpModule方式

看看的下面的代碼:

public class JavascriptReplacementModule : IHttpModule 
{ 
    public class ResponseFilter : MemoryStream 
    { 
     private Stream outputStream = null; 

     public ResponseFilter(Stream output) 
     { 
      outputStream = output; 
     } 

     public override void Flush() 
     { 
      base.Flush(); 
      this.Seek(0, SeekOrigin.Begin); 
      var sr = new StreamReader(this); 

      string contentInBuffer = sr.ReadToEnd(); 

      //Do replacements here 

      outputStream.Write(UTF8Encoding.UTF8.GetBytes(contentInBuffer), 0, UTF8Encoding.UTF8.GetByteCount(contentInBuffer)); 

      outputStream.Flush(); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      outputStream.Dispose(); 
      base.Dispose(disposing); 
     } 
    } 

    public void Dispose() { } 

    public void Init(HttpApplication context) 
    { 
     context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute); 
    } 

    void context_PostRequestHandlerExecute(object sender, EventArgs e) 
    { 

     var context = (HttpApplication)sender; 
     if (context.Request.Url.AbsolutePath.StartsWith("/Content") && context.Request.Url.AbsolutePath.EndsWith(".js")) 
     { 
      HttpContext.Current.Response.Filter = new ResponseFilter(HttpContext.Current.Response.Filter); 
     } 
    } 
} 

而且這樣註冊模塊(確保你把type屬性的全部類型):

<system.webServer> 
    <modules> 
    <add name="JavascriptReplacementModule" type="JavascriptReplacementModule"/> 
    </modules> 
</system.webServer> 

這讓之前修改的輸出流它得到客戶端

+0

謝謝!如果您想知道我使用的是與CORS和AJAX POST相關的安全解決方案:http://security.stackexchange.com/q/17036/396如果您願意,我會很好奇聽到您的想法有想到的東西:) – LamonteCristo 2013-03-28 04:35:49

+0

哎呦 - 錯誤的鏈接http://security.stackexchange.com/q/33200/396 – LamonteCristo 2013-03-28 05:11:08