2013-03-28 175 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