Веб-API в решении MVC в отдельном проекте


88

Я создаю новый проект MVC4, и исследования заставили меня поверить в то, что связь с javascript на стороне сервера теперь лучше достигается через структуру веб-API, а не действия контроллера. Я правильно понимаю это?

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

Когда я настраиваю приложения, мне нравится разделять компоненты на проекты. Я планировал создать проект MVC и проект веб-API. Но я столкнулся с проблемами. Например, у меня осталось 2 приложения как таковых, отдельная настройка маршрутизации и т. Д.

Итак, мой вопрос: в приложении MVC должна ли структура веб-API находиться в одном проекте или же веб-API должен быть выделен в отдельный проект и работать над решением проблем?

Ответы:


110

К сожалению, вы ошибаетесь в этом - я предполагаю, что могу делиться всеми своими атрибутами и т. Д. Между контроллерами web api и mvc, так что на первый взгляд это не кажется мне серьезным изменением.

Многие концепции, используемые веб-API и MVC, хотя на первый взгляд похожи, на самом деле несовместимы. Например, атрибуты веб-API и атрибуты System.Web.Http.Filters.FilterMVC System.Web.Mvc.Filterне являются взаимозаменяемыми.

То же самое относится и ко многим другим концепциям - привязке модели (совершенно разные механизмы), маршрутам (веб-API использует HTTPRoutes, а не Routes, хотя они оба работают с одной и той же базовой таблицей RouteTable), преобразователю зависимостей (несовместимо) и многому другому - хотя они похожи на поверхности, на практике сильно отличаются. Более того, у веб-API нет понятия областей.

В конечном счете, если все, что вы пытаетесь достичь, - это иметь «новый, модный» способ обслуживания JSON-контента - подумайте дважды, прежде чем идти по этому пути. Я бы, конечно, не рекомендовал рефакторинг любого существующего кода, если вы действительно не собираетесь использовать HTTP и создавать свое приложение в стиле RESTful.

Все действительно зависит от того, что вы строите. Если вы начинаете новый проект, и все, что вам нужно, это предоставить JSON для облегчения работы вашего веб-приложения - при условии, что вы готовы жить с потенциально дублирующимся кодом (например, материал, который я упомянул выше), веб-API можно легко разместить внутри тот же проект, что и ASP.NET MVC.

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


2
+1 Отличный ответ. Сначала я думал, что и MVC, и WebAPI могут использовать часть кода, особенно в случае фильтров, привязки модели и т. Д., Но они совершенно разные.
VJAI

5
Да, в таком сценарии просто запустите новый проект MVC4 в Visual Studio, а при появлении запроса на шаблон проекта (второй экран) просто выберите Web API. Это установит веб-API из Nuget, и в описанном вами случае все будет в порядке. Вы получаете отдельный файл конфигурации веб-API, подключенный к Global.asax. Кроме того, вы можете разделить контроллеры API в отдельную папку (по умолчанию они находятся вместе с контроллерами MVC). Наконец, очевидно, что маршруты по умолчанию настроены отдельно и не мешают друг другу
Filip W

9
Я бы хотел, чтобы мой руководитель прочитал этот пост до того, как разработал наш текущий проект.
Billdr 03

2
@FilipW Спасибо за хорошие объяснения. У меня также есть приложение MVC, и я буду использовать WebAPI2 для использования службы для приложений Android. С другой стороны, как говорит Дэвид Педен ниже, безопасность, обслуживание и развертывание также очень важны при принятии решения о создании нового отдельного проекта для WebAPI. Что бы вы посоветовали в таком случае, имея в виду их? Чтобы создать новый отдельный проект для WebAPI или использовать текущий проект MVC? Заранее спасибо.
Джек

1
Очень хорошо «Я бы выделил веб-API в отдельный проект только в том случае, если вы собираетесь создать надлежащий API для своей онлайн-службы - возможно, для использования внешними клиентами или различными устройствами - например, для поддержки ваших мобильных приложений». ударил гвоздь по голове и позволяет легко определить, как это сделать.
ozzy432836 07

27

ИМО, безопасность и развертывание должны определять ваше решение. Например, если ваше приложение MVC использует проверку подлинности с помощью форм, но вы заинтересованы в использовании базовой проверки подлинности (с SSL) для своего API, отдельные проекты сделают вашу жизнь проще. Если вы хотите разместить свой сайт по адресу www.example.com, но разместить свой API как api.example.com (а не www.example.com/api), отдельные проекты упростят вашу жизнь. Если вы разделяете свои проекты и соответственно их субдомены и намереваетесь использовать собственный API из своего приложения MVC, вам нужно будет выяснить, как справиться с проблемой той же политики происхождения для клиентских вызовов вашего API. Распространенным решением этой проблемы является использование jsonp или CORS (желательно, если вы можете).

Обновление (26.03.2013): приближается официальная поддержка CORS: http://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API


Я пытаюсь разобраться в вопросах, связанных с решением интегрировать веб-API с моим приложением MVC или сделать его отдельным проектом. Мне удалось успешно развернуть приложение HelloWorld для веб-API в субдомене на моем веб-хосте. В этом отдельном проекте я, скорее всего, буду использовать модель из своего веб-приложения MVC и вызывающий код в этом отдельном проекте. Кажется, что было бы проще пойти по этому пути отдельного проекта, но с какими проблемами, по вашему мнению, я мог бы столкнуться при таком подходе?
Киаран Галлахер

2
Лично я бы не стал использовать вашу модель представления в качестве DTO для вашего API. Я ожидал, что это решение вызовет у вас серьезные проблемы в будущем, поскольку ваши модели представления и подписи API расходятся. SoC ( en.wikipedia.org/wiki/Separation_of_concerns ) очень важен.
Дэвид Педен,

@DavidPeden Вы предлагаете создать новый отдельный проект для WebAPI. Это правда? С другой стороны, я создам новый отдельный проект для WebAPI (в настоящее время у меня есть UI Layer (MVC) и Data Layer (Class Library) в моем приложении. Итак, я также использую DI, но мне интересно, могу ли я использовать те же классы Entities, Repositories, Interfaces и Abstract на уровне данных для вновь созданного проекта WebAPI, и единственное, что мне нужно сделать, это создать контроллеры WebAPI? Или я также могу создать их все (Entities, Repositories, Interfaces и Abstract классы) снова для WebAPI? Любая помощь, пожалуйста?
Джек,

1
@ H.Johnson Трудно дать общий совет, который имеет смысл, но похоже, что вы выиграете от наличия уровня службы приложения, который инкапсулирует ваши объекты и репозитории, которые могут использоваться обоими вашими пользовательскими интерфейсами (MVC и API).
Дэвид Педен,

9

После некоторого опыта (создание API для приложений и для mvc). Я в основном делаю и то, и другое.

Я создаю отдельный проект для вызовов api, которые поступают от других клиентов или других устройств (приложений Android / IOS). Одна из причин заключается в том, что аутентификация отличается, она основана на токене (чтобы сохранить ее без состояния). Я не хочу смешивать это в моем приложении MVC.

Для моих вызовов javascript / jquery api к моему приложению mvc я предпочитаю простоту, поэтому я включаю веб-api в свое приложение MVC. Я не собираюсь использовать аутентификацию на основе токенов с моими вызовами javascript api, потому что это в том же приложении. Я могу просто использовать [authorize]атрибут в конечной точке API, когда пользователь не вошел в систему, он не получит данные.

Кроме того, когда вы имеете дело с тележками для покупок, и вы хотите сохранить корзину покупок пользователей в сеансе (пока не вошли в систему), вам также необходимо иметь это в своем API, если вы добавляете / удаляете продукты через свой код javascript. Это наверняка сделает ваш API отслеживаемым, но также уменьшит сложность вашего MVC-API.


4
Что ж, @Dimi, это бесполезное редактирование, чтобы получить несколько голосов ... Как я могу их отклонить?
CularBytes

Делай что хочешь. Я редактирую не голосами, а, полагаю, для лучшего вида. Преуспевать.
DmitryBoyko

3
@CularBytes. Вы не можете отклонить изменения, но вы можете отредактировать его снова и откатить изменения. Для этого требуется рецензирование менее 2000 человек, но у вас достаточно репутации, чтобы сделать это мгновенно. Я согласен с тем, что изменение не добавило ценности, и откатил его для вас.
Дэн


5

Недавно я сделал почти то же самое: я начал с нового проекта веб-приложения MVC 4, выбрав шаблон веб-API в VS2012.

Это создаст веб-API, размещенный в том же приложении, что и MVC.

Я хотел переместить ApiControllers в отдельный проект библиотеки классов. Это было довольно просто, но решение было немного скрыто.

В AssemblyInfo.cs проекта MVC 4 добавьте аналогичную строку кода

[assembly: PreApplicationStartMethod(typeof(LibraryRegistrator), "Register")]

Теперь вам нужен класс LibraryRegistrator (не стесняйтесь называть его как угодно)

public class LibraryRegistrator
    {
        public static void Register()
        {
            BuildManager.AddReferencedAssembly(Assembly.LoadFrom(HostingEnvironment.MapPath("~/bin/yourown.dll")));
        }
    }

В проекте MVC 4 также добавьте ссылку на библиотеку Api.

Теперь вы можете добавлять контроллеры Api в свою отдельную библиотеку классов (yourown.dll).


2

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

Я хотел бы сохранить пространство имен system.web изолированным на одном «уровне представления». Несмотря на то, что webapi не является презентационным, он по-прежнему является частью интерфейса вашего приложения. Пока вы сохраняете логику в своем домене, а не в контроллерах, у вас не должно возникнуть слишком много проблем. Кроме того, не забывайте использовать области.


1
Моя основная причина, по которой я хочу отдельные проекты, заключается в том, что API на самом деле не является интерфейсом. Это средний уровень.
lordcheeto

6
«Новичку будет сложно понять» - не лучшая причина выбирать один подход другому. По возможности сохраняйте простоту, но сложные потребности часто требуют сложных решений. Вместо того, чтобы писать глупый код для новичков, мы должны обучать новичков понимать и писать умный код.
Дэн

0

В дополнение к настройке отдельной DLL для Web.Api.

Просто предложение:

  1. Создать проект
  2. Самородок WebActivatorEx
  3. Создайте метод класса, который будет вызываться при app_start

    [сборка: WebActivatorEx.PostApplicationStartMethod (typeof (API.AppWebActivator), «Пуск»)]

    [сборка: WebActivatorEx.ApplicationShutdownMethod (typeof (API.AppWebActivator), «Завершение работы»)]

  4. Зарегистрируйте маршруты web.api внутри метода запуска

    общедоступная статическая пустота Start () {GlobalConfiguration.Configure (WebApiConfig.Register); }

  5. Ссылка проекта на веб-проект. для активации метода запуска.

Надеюсь это поможет.


0

Я попытался разделить контроллеры API в новый проект. Все, что я сделал, - это создал новый проект библиотеки, переместив контроллеры в папку с именем API. Затем добавили ссылку на проект библиотеки в проект MVC.

Конфигурация webAPI остается в самом проекте MVC. Работает нормально.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.