Веб-API у рішенні MVC в окремому проекті


88

Я створюю новий проект MVC4, і дослідження привели мене до думки, що спілкування з javascript на сторону сервера зараз краще досягається за допомогою веб-API, а не через дії контролера. Чи правильно я розумію це?

Я припускаю, що можу ділитися всіма своїми атрибутами тощо між веб-інтерфейсами API та контролерами MVC, тому на перший погляд, це не здається для мене масовою зміною.

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

Отже, моє запитання полягає в тому, чи повинен у програмі MVC фреймворк веб-API знаходитись в одному проекті, чи веб-API повинен бути виділений у власний проект та обходити проблеми?

Відповіді:


110

На жаль, ви помиляєтесь із цим - я припускаю, що можу ділитися всіма своїми атрибутами тощо між веб-контролерами api та mvc, тому, на перший погляд, для мене це не здається масовою зміною.

Багато концепцій, що використовуються веб-API та MVC, хоча і схожі на перший погляд, насправді не сумісні. Наприклад, атрибути веб-API є, System.Web.Http.Filters.Filterа атрибути MVC -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). Нарешті, маршрути за замовчуванням очевидно налаштовані окремо і не заважають один одному
Філіп W

9
Я хотів би, щоб мій керівник прочитав цю публікацію до того, як він створив наш поточний проект.
Billdr

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

1
Дуже добре. "Я б виділив веб-API в окремий проект, лише якщо ви збираєтеся створити належний API для вашої онлайн-служби - можливо, для споживання зовнішніми клієнтами або різними пристроями - наприклад, для заправлення ваших мобільних додатків". вдарив цвях по голові і дозволяє легко визначити, яким способом це зробити.
ozzy432836

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 або як окремий проект. Я зміг успішно розгорнути програму Web API HelloWorld у піддомені на моєму веб-хості. З цього окремого проекту я, швидше за все, буду використовувати Модель з мого веб-додатку MVC та код виклику в цьому окремому проекті. Здається, може бути простіше піти цим шляхом окремого проекту, але на вашу думку, з якими проблемами я міг би зіткнутися при такому підході?
Ciaran Gallagher

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

@DavidPeden Ви пропонуєте створити новий окремий проект для WebAPI. Це правда? З іншого боку, я буду створювати новий окремий проект для WebAPI (зараз у моїй програмі є рівень інтерфейсу користувача (MVC) і рівень даних (бібліотека класів). Отже, я також використовую DI, але мені цікаво, чи можу я використовувати ті самі сутності, сховища, інтерфейси та абстрактні класи на рівні даних для нещодавно створеного проекту WebAPI, і єдине, що мені потрібно зробити, це створити контролери WebAPI? Або я також створюю всі з них (сутності, сховища, інтерфейси та реферат класів) знову для WebAPI? Будь-яка допомога, будь ласка?
Джек,

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

9

Після певного досвіду (створення API для додатків та для mvc). Я в основному роблю обидва.

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

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

Крім того, коли ви маєте справу з кошиками для покупок, і ви хочете зберігати кошик для покупок користувачів у сеансі (поки ви не ввійшли в систему), вам також потрібно мати це в своєму API, якщо ви додаєте / видаляєте товари за допомогою свого коду javascript. Це точно зробить ваш API станом, але також зменшить складність вашого MVC-API.


4
Ну @Dimi, це марне редагування, щоб набрати кілька голосів ... Як я можу їх відхилити?
CularBytes

Роби що хочеш. Я редагую не за допомогою голосів, але для найкращого зовнішнього вигляду, я вважаю. Вперед.
Дмитро Бойко

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. Створіть метод класу a, який буде викликаний при застосуванні app_start

    [збірка: WebActivatorEx.PostApplicationStartMethod (typeof (API.AppWebActivator), "Пуск")]

    [збірка: WebActivatorEx.ApplicationShutdownMethod (typeof (API.AppWebActivator), "Shutdown")]

  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.