【问题标题】:Am I reinventing the wheel with this ASP.NET Web API based webserver?我是否正在使用这个基于 ASP.NET Web API 的网络服务器重新发明轮子?
【发布时间】:2013-05-03 01:21:27
【问题描述】:

在独立(自托管)应用程序中,我希望有一个 httpserver,它在单个基本地址上可以提供简单的网页(没有任何服务器端动态/脚本,它只返回内容请求文件)或提供 RESTful 网络服务:

  • http://localhost:8070/{filePath}被请求时,它应该返回文件的内容(html、javascript、css、图像),就像一个普通的简单网络服务器一样
  • http://localhost:8070/api/ 后面的所有内容都应该充当普通的 RRESTful Web API

我当前的方法使用 ASP.NET Web API 来同时提供 html 页面和 REST API:

 var config = new HttpSelfHostConfiguration("http://localhost:8070/");
 config.Formatters.Add(new WebFormatter());
 config.Routes.MapHttpRoute(
   name: "Default Web",
   routeTemplate: "{fileName}",
   defaults: new { controller = "web", fileName = RouteParameter.Optional });
 config.Routes.MapHttpRoute(
   name: "Default API",
   routeTemplate: "api/{controller}/{id}",
   defaults: new { id = RouteParameter.Optional });

WebController 是使用此幼稚代码为网页提供服务的控制器:

public class WebController : ApiController
{
    public HttpResponseMessage Get(string fileName = null)
    {
        /// ...
        var filePath = Path.Combine(wwwRoot, fileName);
        if (File.Exists(filePath))
        {
            if (HasCssExtension(filePath))
            {
                return this.Request.CreateResponse(
                   HttpStatusCode.OK, 
                   GetFileContent(filePath), 
                   "text/css");
            }

            if (HasJavaScriptExtension(filePath))
            {
                return this.Request.CreateResponse(
                   HttpStatusCode.OK,
                   GetFileContent(filePath),
                   "application/javascript");
            }

            return this.Request.CreateResponse(
              HttpStatusCode.OK, 
              GetFileContent(filePath), 
              "text/html");
        }

        return this.Request.CreateResponse(
            HttpStatusCode.NotFound,
            this.GetFileContnet(Path.Combine(wwwRoot, "404.html")),
            "text/html");
    }
}

同样,对于 /api 背后的所有内容,都使用普通 REST API 的控制器。

我现在的问题是:我在正确的轨道上吗?我觉得我在这里重建一个网络服务器,重新发明轮子。而且我猜可能有很多 http 请求网络浏览器可能会让我在这里无法正确处理。

但是,如果我想通过同一个基地址自托管并同时服务器 REST Web API 和网页,我还有什么其他选择?

【问题讨论】:

    标签: web-services asp.net-web-api webserver


    【解决方案1】:

    看起来您正在尝试为自己的主机重新创建 asp.net FileHandler。不过有更好的解决方案。使用 Katana(一个 OWIN 主机)作为 Web API 的托管层。 OWIN 支持在同一个应用程序中托管多个 OWIN 框架。在您的情况下,您可以在同一个 OWIN 应用程序中同时托管 Web API 和文件处理程序。

    Filip 有一篇很好的博客文章可以帮助您入门 here。你可以使用这样的配置代码,

    public void Configuration(IAppBuilder appBuilder)
    {
        // configure your web api.
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute("default-api", "api/{controller}");
        appBuilder.UseWebApi(config);
    
        // configure your static file handler.
        appBuilder.UseStaticFiles();
    }
    

    【讨论】:

    • 还有没有办法在 Katana/OWIN 中集成 WCF REST 服务?
    • @bitbonk:我最近发现了这个:nuget.org/packages/Gate.Wcf(未测试)
    • 这仅在您可以运行 .net 4.5 时才有效。如果您像我一样被困在 .net 4.0 上,OP 的方法是最好的方法。
    【解决方案2】:

    IMO 你所做的并没有错。我使用自托管来交付文件、html 文档以及作为常规 API。在核心,自托管使用 HTTP.SYS,就像 IIS 一样。

    正如 RaghuRam 所提到的,有些 Owin 主机对提供静态文件进行了一些优化,但 WCF 自主机在提供文件方面非常有能力获得不错的性能。

    【讨论】:

    • 我的方法的问题在于,您在WebController.Get 中看到的所有代码都是通过反复试验找到的。我假设文件处理程序可能还有更多内容,它以所有浏览器期望的方式发送正确的 http 标头和内容以及正确的编码等?交付文件时如何处理?
    【解决方案3】:

    查看此链接,该链接使用更直接的方法

    Setting app a separate Web API project and ASP.NET app

    RouteTable.Routes.IgnoreRoute(".js"); RouteTable.Routes.IgnoreRoute(".html");

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      相关资源
      最近更新 更多