【问题标题】:Can ASP.NET Web API work on same url as MVC?ASP.NET Web API 可以在与 MVC 相同的 url 上工作吗?
【发布时间】:2012-03-22 10:00:07
【问题描述】:

对于返回 HTML 的 ASP.NET MVC 请求和返回 JSON 的 ASP.NET Web API 是否可以使用相同的 url?

我在这样的示例路由中看到:"api/{id}",但我可以去掉这个api/ 部分在 MVC(不是 Web API)中使用这个地址吗?

一方面这应该是可能的,因为我们有内容协商。但是这种方式我需要两条具有相同地址的路由,所以这没有意义,对吧?

换句话说:我可以让ControllerApiController 具有相同的网址吗?还是应该将ApiController 也用于 HTML?

【问题讨论】:

    标签: .net asp.net-mvc rest asp.net-mvc-4 asp.net-web-api


    【解决方案1】:

    WebAPI 允许您通过实现System.Web.Http.Routing.IHttpRouteConstraint 来定义自定义路由约束。

    在常规 ASP.NET MVC 中,您可以通过实现 System.Web.Routing.IRouteConstraint 来做同样的事情。

    这样,您可以创建仅对某个 HTTP Accept 标头有效的路由,例如“应用程序/json”或“文本/html”。

    【讨论】:

      【解决方案2】:

      我可能在这里扮演魔鬼代言人,但我可以理解为什么有人想要做这样的事情。

      通常在同一个 URL 上有一个 API 的 HTML 表示是很好的。这种方法允许用户在浏览器中点击并探索 API。

      我通过使用自定义消息处理程序在 WebAPI 中解决了这个问题,该处理程序 302 重定向到 MVC 路由。

      public class HtmlMessageHandler : DelegatingHandler
      {
          private List<string> contentTypes = new List<string> { "text/html", "application/html", "application/xhtml+xml" };
      
          protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
          {
              if (request.Method == HttpMethod.Get && request.Headers.Accept.Any(h => contentTypes.Contains(h.ToString())))
              {
                  HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Redirect);
      
                  var htmlUri = new Uri(String.Format("{0}/html",request.RequestUri.AbsoluteUri));
      
                  response.Headers.Location = htmlUri;
      
                  return Task.Factory.StartNew<HttpResponseMessage>(()=> response);
              }
              else 
              {
                  return base.SendAsync(request, cancellationToken);
              }
          }
      }
      

      可能有点小技巧,但它确实可以完成工作,我个人更喜欢它而不是自定义 HTML MediaTypeFormatter(我也尝试过);)

      【讨论】:

      【解决方案3】:

      理论上,您可以使用 web api 并构建一个内容提供程序,当客户端请求 text\html 时将返回 html(可能来自 razor),当客户端请求 application\json 时将返回 json

      【讨论】:

        【解决方案4】:

        由于 Web API 使用与 MVC 相同的路由系统,如果您有一些方法来区分路由,那么您可以为两者使用相同的基本 url。您需要某种路由约束来将 api 调用映射到 api。例如,这可能是查询字符串参数。

        如果你的 url 完全一样,甚至是查询字符串,那么没有。你运气不好。

        【讨论】:

          【解决方案5】:

          以前的答案已经解释了这种情况。要添加的一件事是,ASP.NET MVC 或 Web API,您的所有路由都收集在同一个列表下。

          例如,在默认项目模板上,如果您在 Web API 之前注册 ASP.NET MVC 路由,您将看到 /api 路径下的请求被 ASP.NET MVC 路由拾取。

          【讨论】:

            【解决方案6】:

            如上一个答案所述,你不能做这样的事情,我真的不明白你为什么想做这样的事情。

            但我不同意你应该在单个项目中坚持一件事,如果你想要一个干净的 API,那么我会选择 webapi 并使用 MVC 来托管我的页面,那时我将拥有 API在单独的文件夹中加上单独的路由。

            【讨论】:

            • 没错,保持它们是单独的项目
            • @Rick.Anderson-at-Microsoft.com,我并不是说您应该将它们保存在单独的项目中,这取决于 api 和站点的大小。如果它是一个小型应用程序,我认为您可以在同一个项目中同时拥有 API 和站点,如果可能的话,只需将 API 放在一个区域中即可将它们分开。
            【解决方案7】:

            不,你不能有一个 URL 路由到两个不同的类。如果多个路由匹配传入请求,将使用第一个匹配的路由。

            我不确定您为什么需要将两者混合在一个项目中,至少没有任何实际原因。 ApiController 可以返回 HTML,MVC Controller 可以返回 JSON,所以只需选择一个并使用它。

            【讨论】:

              猜你喜欢
              • 2013-03-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多