代码之家  ›  专栏  ›  技术社区  ›  Dennis C

我可以运行ASPX并grep结果而不发出HTTP请求吗?

  •  4
  • Dennis C  · 技术社区  · 16 年前

    如何在没有URL和HTTP的情况下对一个简单的ASP.NET文件进行函数调用,并捕获它生成的字节流?

    更多背景信息,

    我需要一个某种类型的模板可以放一点逻辑里面,呈现一些类似INI的文本文件。我放弃了那些从Java移植来的库,提出了一个使用ASP.NET作为模板引擎的解决方案(我不是用它来建立一个网站,甚至不是一个HTML。)

    我编写了一个ASP.NET页面(没有WebForm,没有MVC),它接受一个XML POST,并根据一组简单但不太简单的规则生成一个长文本文件。

    我从DB对象生成XML,提交到ASP页面,对结果进行grep,效果很好。然而,问题是我们想作为一个库使用,由一个WCF使用。因此,我无法使用相对路径,我必须将ASP的URL存储在配置中的某个位置,我不想这样做。

    它将托管在IIS服务器上,但不会从任何前端ASP调用(至少不会直接调用),也不会从最终用户调用。

    另外,我最初是在为C#寻找一个简单的模板引擎,但是 they 它们太旧,不再需要维护,文档质量差,缺少集成的编辑器/调试器,太简单,而且它们可能会说不同的语言。

    2 回复  |  直到 9 年前
        1
  •  6
  •   Cheeso    16 年前

    例子:

    public class MyAspNetHost : System.MarshalByRefObject
    {
        public void ProcessRequest(string page)
        {
            var request = new System.Web.Hosting.SimpleWorkerRequest
                (page,               // the page being requested
                 null,               // query - none in this case
                 System.Console.Out  // output - any TextWriter will do
                );
    
            // this will emit the page output to Console.Out
            System.Web.HttpRuntime.ProcessRequest(request);
        }
    
        public AppDomain GetAppDomain()
        {
            return System.Threading.Thread.GetDomain();
        }
    }
    
    
    public class Example
    {   
        public void Run(IEnumerable<String> pages)
        {
            // ASPNET looks for assemblies - including the assembbly
            // that contains any custom ASPNET host - in the bin\
            // subdirectory of the physical directory that backs the
            // ASPNET Host.  Because we are going to use the current
            // working directory as the physical backing directory for
            // the ASPNET host, we need to ensure there's a bin
            // subdirectory present.
    
            bool cleanBin = false;
            if (!Directory.Exists("bin"))
            {
                cleanBin = true;
                Directory.CreateDirectory("bin");
            }
    
            // Now, ensure that the assembly containing the custom host is
            // present in that bin directory.  The assembly containing the
            // custom host is actually *this* assembly.  
    
            var a = System.Reflection.Assembly.GetExecutingAssembly();
            string destfile= Path.Combine("bin", Path.GetFileName(a.Location));
            File.Copy(a.Location, destfile, true); 
    
            host =
                (MyAspNetHost) System.Web.Hosting.ApplicationHost.CreateApplicationHost
                ( typeof(MyAspNetHost),
                  "/foo",   // virtual dir - can be anything
                  System.IO.Directory.GetCurrentDirectory() // physical dir
                  );
    
            // process each page
            foreach (string page in pages)
                host.ProcessRequest(page);
        }
    }
    

    如果要清理bin目录,必须先卸载AppDomain。你可以这样做:

        private ManualResetEvent aspNetHostIsUnloaded;
    
        private void HostedDomainHasBeenUnloaded(object source, System.EventArgs e)
        {
            // cannot clean bin dir here.  The AppDomain is not yet gone.
            aspNetHostIsUnloaded.Set();
        }
    
        private Run(IEnumerable<String> pages)
        {
            try 
            {
                ....code from above ....
            }
            finally
            {
                if (host!= null)
                {
                    aspNetHostIsUnloaded = new ManualResetEvent(false);
    
                    host.GetAppDomain().DomainUnload += this.HostedDomainHasBeenUnloaded;
    
                    AppDomain.Unload(host.GetAppDomain());
    
                    // wait for it to unload
                    aspNetHostIsUnloaded.WaitOne();
    
                    // optionally remove the bin directory
                    if (cleanBin)
                    {
                        Directory.Delete("bin", true);
                    }
    
                    aspNetHostIsUnloaded.Close();
                }
            }
        }
    

    在您的情况下,您可能希望修改自定义主机,以便每个页面的输出转到 StringWriter 而不是Console.Out,然后您可以执行Grep(或者更可能是使用 Regex )在那个输出上。您可能还想修改它,将所有输入数据作为querystring接受。要做到这一点,您需要格式化页面请求。

    a good article on MSDN Magazine on this technique of hosting the ASPNET runtime


    编辑2 :有一种更简单的方法来管理bin目录。只需创建一个名为bin的符号链接,指向“.”。然后,可以在调用AppDomain.Unload()之后删除符号链接,而无需等待。看起来像这样:

        public void Run(string[] pages)
        {
            bool cleanBin = false;
            MyAspNetHost host = null;
            try
            {
                // This creates a symlink.
                // ASPNET always looks for a bin\ directory for the privateBinPath of the AppDomain.
                // This will create the bin dir, pointing to the current dir.
                if (!Directory.Exists("bin"))
                {
                    cleanBin = true;
                    CreateSymbolicLink("bin", ".", 1);
                }
    
                host =
                    (MyAspNetHost) System.Web.Hosting.ApplicationHost.CreateApplicationHost
                    ( typeof(MyAspNetHost),
                      "/foo",   // virtual dir - can be anything
                      System.IO.Directory.GetCurrentDirectory() // physical dir
                      );
    
                foreach (string page in pages)
                    host.ProcessRequest(page);
            }
            finally
            {
                // tell the host to unload
                if (host!= null)
                {
                    AppDomain.Unload(host.GetAppDomain());
    
                    if (cleanBin)
                    {
                        // remove symlink - can do without waiting for AppDomain unload
                        Directory.Delete("bin");
                    }
                }
            }
        } 
    

    这样就不需要ManualResetEvent、复制文件、同步等。它假定自定义ASPNet主机的程序集以及运行的ASPX页所需的所有程序集都包含在当前工作目录中。

        2
  •  0
  •   Community Mohan Dere    9 年前

    这听起来像是一个非常类似的问题,即在服务器上生成HTML电子邮件。这里有一些答案可以做到这一点(对于MVC):

    ASP.NET MVC: How to send an html email using a controller?