Может ли ASP.NET Web API работать по тому же URL-адресу, что и MVC? - PullRequest
7 голосов
/ 04 марта 2012

Могу ли я иметь одинаковые URL для запросов ASP.NET MVC, возвращающих HTML, и для ASP.NET Web API, возвращающих JSON?

В примерах я вижу такие маршруты: "api/{id}" но можно ли избавиться от этого api/ part и использовать этот адрес также в MVC (не в Web API)?

С одной стороны это должно быть возможно, поскольку у нас есть согласование контента. Но в этом случае мне нужны два маршрута с одинаковым адресом, так что это не имеет смысла, верно?

Другими словами: могу ли я иметь Controller и ApiController с одинаковым URL? Или я должен использовать ApiController также для HTML?

Ответы [ 7 ]

5 голосов
/ 05 марта 2012

Как указано в предыдущем ответе, вы не можете делать такие вещи, и я действительно не вижу смысла, почему вы хотели бы сделать что-то подобное.

Но я не согласен с тем, что вы должны придерживаться одной вещи в одном проекте, если вы хотите чистый API, тогда я бы выбрал webapi и использовал бы MVC для размещения своих страниц, и в этот момент у меня был бы API в отдельной папке плюс под отдельным маршрутом.

3 голосов
/ 30 марта 2012

Я, возможно, играю здесь адвоката дьяволов, но я понимаю, почему кто-то захочет сделать что-то подобное.

Часто приятно иметь HTML-представление API на том же URL-адресе. Этот подход позволяет пользователям переключаться между приложениями и изучать 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 (который я тоже пробовал);)

2 голосов
/ 27 марта 2013

WebAPI позволяет вам определять пользовательские ограничения маршрута путем реализации System.Web.Http.Routing.IHttpRouteConstraint .

В обычном ASP.NET MVC вы можете сделать то же самое, внедрив System.Web.Routing.IRouteConstraint .

Таким образом, вы можете создавать маршруты, которые активны только для определенного заголовка HTTP Accept, например "application / json" или "text / html".

1 голос
/ 05 марта 2012

Теоретически вы можете использовать web api и создать провайдер контента, который будет возвращать html (возможно, из бритвы), когда клиент запрашивает text \ html и json, когда клиент запрашивает приложение \ json

1 голос
/ 05 марта 2012

Предыдущие ответы объяснили ситуацию. Следует добавить, что в ASP.NET MVC или веб-API все маршруты собраны в одном списке.

Например, в шаблоне проекта по умолчанию, если вы зарегистрируете маршрут ASP.NET MVC до маршрута Web API, вы увидите, что запросы по пути /api принимаются маршрутом ASP.NET MVC.

1 голос
/ 05 марта 2012

Нет, у вас не может быть одного URL-маршрута к двум разным классам.Если нескольким маршрутам соответствует входящий запрос, будет использован первый из них.

Я не уверен, почему вам нужно смешивать два в одном проекте, по крайней мере, по какой-либо практической причине.,ApiController может возвращать HTML, а MVC Controller может возвращать JSON, поэтому просто выберите один и используйте его.

0 голосов
/ 05 марта 2012

Поскольку веб-API использует ту же систему маршрутизации, что и MVC, если у вас есть какой-то способ дифференциации маршрутов, вы можете использовать один и тот же базовый URL для обоих.Вам понадобится какое-то ограничение маршрута, чтобы сопоставить вызовы API с API.Это может быть параметр строки запроса, например.

Если ваш URL-адрес точно такой же, даже вплоть до строки запроса, то нет.Тебе не повезло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...