Префикс глобального маршрута Api 2 для атрибутов маршрута?

Я хотел бы разоблачить компанию api двумя способами:

  • api.company.com (чистый веб-сайт WebApi)

  • company.com/api (добавьте WebApi на существующий сайт компании MVC5)

Итак, я поместил модели/контроллеры в отдельную сборку и ссылаюсь на нее с обоих веб-сайтов.

Кроме того, я использую атрибуты маршрута:

[RoutePrefix("products")]
public class ProductsController : ApiController

Теперь к контроллеру, указанному выше, можно получить доступ:

  • api.company.com/products, который хорош

  • company.com/products, который я хотел бы изменить на company.com/api/products

Есть ли способ сохранить атрибуты маршрута и настроить проект MVC, чтобы он добавлял "api" для всех маршрутов?

Ответ 1

Так что это, вероятно, не единственный способ, которым вы могли бы это сделать, но я бы это сделал:

  • Создайте свой собственный атрибут, который наследуется от RoutePrefixAttribute
  • Переопределите свойство префикса и добавьте в него некоторую логику для добавления api к префиксу, если он запущен на нужном сервере.
  • Основываясь на настройке в вашем web.config, добавьте маршрут или нет.

    public class CustomRoutePrefixAttribute : RoutePrefixAttribute
    {
    
      public CustomRoutePrefixAttribute(string prefix) : base(prefix)
      {
      }
    
      public override string Prefix
      {
        get
        {
            if (Configuration.PrependApi)
            {
                return "api/" + base.Prefix;
            }
    
            return base.Prefix;
        }
      }
    }
    

ИЗМЕНИТЬ (Этот параметр больше не поддерживается в Web API 2.2)

В качестве альтернативы вы также можете указать несколько префикса маршрута:

[RoutePrefix("api/products")]
[RoutePrefix("products")]
public class ProductsController : ApiController

Ответ 2

Вы можете использовать Map on IAppBuilder

Итак, класс Startup будет выглядеть примерно так.

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Map("/api", map =>
        {
            HttpConfiguration config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            map.UseWebApi(config);
        });

    }
}

Ответ 3

Другим вариантом будет пересылка трафика с одного сайта на ваш веб-API. Вы настроены на размещение двух экземпляров? Если нет, вы можете разместить только один экземпляр в api.company.com/products. На веб-сайте MVC внедрите HttpHandler, чтобы перенаправить все сопоставление трафика /api/ * на api.company.com:

а. Создайте обработчик в вашем приложении MVC:

public class WebApiHandler : IHttpHandler
{
  public void ProcessRequest(HttpContext context)
  {
    string url = "api.company.com" + context.Request.RawUrl.Replace("/api","");

    //Create new request with context.Request headers and content
    //Write the new response headers and content to context.Response    
  }
}

б. Зарегистрируйте обработчик в вашем web.config:

<configuration>
  <system.web>
    <httpHandlers>
      <add verb="*" path="api/*" type="Name.Space.WebApiHandler" validate="false" />
    </httpHandlers>
  </system.web>
</configuration>

с. Включите CORS в своем веб-API, если вы этого еще не сделали.

Ответ 4

Вы можете просто реализовать свою службу api как www.mycompany.com/api.

Затем используйте UrlRewrite для сопоставления api.mycompany.com на www.mycompany.com/api

Мы даже поддерживаем этот метод UrlRewrite в генерации ссылок, поэтому, если вы создаете ссылки с api.mycompany.com, ваши ссылки будут указывать на api.mycompany.com/controller/id.

Обратите внимание, что это единственная форма перезаписи URL, которая корректно работает для генерации ссылок MVC (api.xxx.yyy → www.xxx.yyy/api)