0

当我从 /Content 目录向用户提供 javascript 文件时,我想string用一个值替换该文件中的令牌,以便当用户请求给定文件时,它具有他们期望的所有自定义。

我认为这意味着我需要以某种方式代理对 /Content 目录的请求,执行动态插入,并将文件提供给用户。

  • 我有兴趣将此插入作为stream内存文件或内存文件执行。我更喜欢使用流,因为它可能更有效的内存。

如何让 ASP.NET 代理此目录?

我尝试过

  1. 使用路由指向控制器

  2. WCF 代理 URL

但它们对我来说似乎都很“丑陋”,我想让这个插入/替换在他的项目中尽可能透明。

有没有更清洁的方法?

4

2 回答 2

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 是您请求的文件的名称。

不用担心 url,如果需要,您可以通过创建另一个路由来自定义它

于 2013-03-28T03:10:13.633 回答
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>

这允许您在输出流到达客户端之前对其进行修改

于 2013-03-28T03:39:33.663 回答