{"Повідомлення" WebApi: "сталася помилка"} на IIS7, а не в IIS Express


171

Я працюю з ASP.NET MVC 4 WebApi і мені дуже весело, запускаючи його на своєму локальному комп’ютері в IIS Express. Я налаштував IIS Express також для обслуговування віддалених машин, тому інші в моїй компанії використовують мій комп'ютер як наш веб-сервер.

Вирішивши, що це не менш оптимальне рішення, ми вирішили поставити WebApi на віддалений сервер після встановлення .NET 4.5. Коли я використовую fiddler і надсилаю POST до контролера на своїй локальній машині, він повертає правильну відповідь, але коли я змінюю домен на веб-сервер під управлінням IIS7, той же POST повертає криптовалюту

{"message": "сталася помилка"}

повідомлення. Хтось має уявлення про те, що може бути?


2
Який код статусу HTTP у відповіді на помилку? Якщо це 500, дуже ймовірно, що конфігурація веб-сайту / програми недійсна для віддаленої машини з IIS 7. Створіть простий HTML-файл на віддаленій машині, перегляньте його на віддаленій машині, якщо можливо, щоб переконатися, що його можна переглянути, а потім спробуйте натисніть його зі своєї машини, щоб побачити, успішний він чи ні.
Шестко Саез

Це 500-помилка. Дякуємо за пропозицію, але сторінка index.html за замовчуванням, яку надає WebApi, працює. Також слід додати, що деякі веб-сервіси API працюють, а інші - ні, тоді як усі вони працюють на моїй локальній машині.
nsg

2
Вам потрібно буде включити трасування запитів IIS, щоб отримати більш детальну інформацію, коли ви бачите помилку 500. Помилка 500 зазвичай виникає перед початком маршрутизації Web API, але я думаю, що це можливо спровокувати її чимось, що робить ваш код. Подивіться на запис протоколу IIS і переконайтеся, що це пропонує підказки.
Шестко Саез

1
Ви можете отримати сервер, щоб надати більше детальної інформації про помилку у своїй відповіді, ініціювавши запит із браузера на самій серверній машині (наприклад, за допомогою сеансу віддаленого робочого столу).
Джон Шнайдер

Відповіді:


268

Проблема полягала у відсутності залежності, яка не була на сервері, але була на моїй локальній машині. У нашому випадку це був dll Devart.Data.Linq.

Щоб дійти до цієї відповіді, я включив трасування IIS на 500 помилок. Це дало трохи інформації, але справді корисна річ полягала в налаштуванні web.config <system.web><customErrors mode="Off"/></system.web>Це вказувало на відсутність динамічно завантаженої залежності. Додавши цю залежність і сказавши, що вона буде скопійована локально, сервер почав працювати.


33
Схоже, що WebAPI замінить {"message": "сталася помилка"} реальною відповіддю кожного разу, коли код відповіді HTTP становить 500 і вмикаються спеціальні помилки. Дякуємо за вказівник.
Пол Суарт

4
Чудова пропозиція щодо налаштування режиму customErrors. Я здивований, що зміни, які вплинули на вихід подібних помилок.
Дьюї Різ

1
ви також можете встановити його, mode="RemoteOnly"і якщо ви запустите сторінку на веб-браузері на сервері, ви також побачите помилки, не порушуючи безпеку, якщо решта сайту доступна зовні
Simon_Weaver

Будь-які поради щодо отримання подібної інформації про помилки при зміні цього параметра неможливі (наприклад, помилки вимкнено на машинному рівні, оскільки частина API розміщується на сервері, сумісному з PCI)? Я спробував налаштувати Elmah, але, на жаль, це нічого не записує.
RubyHaus

Це найкращий підхід, дає достатньо інформації про такий загальний метод.
DanielV

97

В основному:

Використовуйте IncludeErrorDetailPolicyнатомість, якщо CustomErrorsце не вирішує для вас (наприклад, якщо стек ASP.NET є> 2012):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Примітка. Будьте уважні, повертаючи детальну інформацію про помилки, може виявити конфіденційну інформацію для "хакерів". Дивіться коментар Саймона до цієї відповіді нижче.

Версія TL; DR

Для мене CustomErrorsне дуже допомогло. Це вже було налаштовано Off, але я все-таки отримав лише потворне an error has occurredповідомлення. Я здогадуюсь, що прийнята відповідь є від 3 років тому, що є давнім часом у веб-слова сьогодні. Я використовую Web API 2 та ASP.NET 5 (MVC 5), і Microsoft відійшла від стратегії, яка використовується лише для IIS, поки CustomErrorsє старою II- програмою skool;).

У всякому разі, у мене виникли проблеми з виробництвом, яких у мене не було на місцях. А потім виявив, що я не міг бачити помилки на вкладці «Мережа Chrome», як на моїй машині розробки Врешті-решт мені вдалося вирішити це, встановивши Chrome на своєму виробничому сервері, а потім переглянувши програму там на самому сервері (наприклад, на "localhost"). Потім з'явилися більш детальні помилки зі слідами стека і все.

Лише згодом я знайшов цю статтю від Джиммі Богара (Примітка: Джиммі - це містер AutoMapper! ). Найсмішніше, що його стаття також з 2012 року, але в ній він уже пояснює, що CustomErrorsце вже не допомагає, але ви МОЖЕТЕ змінити " IncludeErrorDetailPolicyДеталі про помилку", встановивши іншу в глобальній конфігурації WebApi (наприклад WebApiConfig.cs):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

На щастя, він також пояснює, як налаштувати його, щоб webapi (2) слухав ваші CustomErrorsналаштування. Це досить розумний підхід, і це дозволяє вам повернутися до 2012 року: P.

Примітка. Значення за замовчуванням - "LocalOnly", яке пояснює, чому мені вдалося вирішити проблему так, як я описав, перш ніж знайти цю публікацію. Але я розумію, що далеко не кожен може просто віддалятися до виробництва та запускати браузер (я знаю, що я здебільшого не міг, поки не вирішив перейти на фрілансер AND DevOps).


2
Тепер це працює. Дякую! У мене є кілька тестів на інтеграцію пам’яті-Owin-роду, які виходять з ладу на сервері збірки, але не локально. Завдяки цьому налаштуванню в моєму стартовому класі я, можливо, маю шанс зрозуміти, чому.
Томас Ейд

Здається, що налаштування customError працює з WebApi 2, коли він розміщений в IIS через Microsoft.AspNet.WebApi.WebHost. Пакети версії 5.2.3, тому ASP.NET стек пройшов минулий 2012 рік. Встановивши його на Off, веб-api переходить від загальних помилок до більш детальних, що містять стек викликів тощо ...
Том

4
Будьте уважні, встановивши це, оскільки це може виявити конфіденційну інформацію для "хакерів". Я часто роблю швидкий злом щось подібне, if (DateTime.Now < new DateTime(2017, 6, 22)) { .... }щоб встановити такий варіант. Тоді я можу перевірити його на виробництві, і завтра воно магічно повернеться до нормальної поведінки, якщо я забуду його відключити.
Simon_Weaver

36

Жодна з інших відповідей не працювала на мене.

Це зробило: (у Startup.cs)

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        WebApiConfig.Register(config);

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}

(або ви можете розмістити його на WebApiConfig.cs):

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}

Так !, Це було єдиним робочим рішенням для Mono / Linux.
Роберт II

Це працювало для мене в продажі для внутрішньо обслуговуваного додатка на IIS та Windows Server.
Пол Карлтон

config.IncludeErrorDetailPolicy = ВключитиErrorDetailPolicy.Always; допоміг мені знайти, що я повертаю екземпляр суб'єкта, який не вдалося розібрати, тому що контекст був розміщений дякую
Jood jindy

12

Я завжди стикаюся з цим питанням, коли потрапляю на помилку в тестовому середовищі і пам'ятаю: "Я робив це раніше, але можу це зробити прямо в web.config, не змінюючи код і повторно розгортаючись до тестового середовища , але потрібно 2 зміни ... що це було знову? "

Для подальшого ознайомлення

<system.web>
   <customErrors mode="Off"></customErrors>
</system.web>

І

<system.webServer>
  <httpErrors errorMode="Detailed" existingResponse="PassThrough"></httpErrors>
</system.webServer>

11

У мене була подібна проблема під час публікації в кінцевій точці WebAPI. Повернувши CustomErrors = Off, я зміг побачити фактичну помилку, якої не було в одній з dll.


10

Якщо це допоможе комусь:

У мене була подібна проблема, і, слідуючи інструкціям Нейтса, я додав:

<system.web>
     <customErrors mode="Off"/>
 </system.web>

Це показало мені більше інформації про помилку:

"ExceptionMessage": "Не вдається завантажити вказаний ресурс метаданих.", "ExceptionType": "System.Data.Entity.Core.MetadataException", "StackTrace": "на System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderComer .LoadResources (...

Це коли я згадав, що я перемістив файл edmx в інше місце і забув змінити вузол з'єднання у конфігу (вузол connectionstrings був розміщений у окремому файлі за допомогою "configSource", але це вже інша історія).


Це трапилося зі мною, коли додавали OData та AutoMapper до веб-api на asp.net - сподіваємось, ці ключові слова допомагають комусь дійти до цієї публікації, і спробувати / зловити не вдалося в моєму випадку, тому мені довелося побачити вихідний результат
Ekus

0

Мій файл XML-файлу не розгорнуто в \ bin:

GlobalConfiguration.Configuration
  .EnableSwagger(c =>
  {
    c.SingleApiVersion("v1", "SwaggerDemoApi");
    c.IncludeXmlComments(string.Format(@"{0}\bin\SwaggerDemoApi.XML", 
                         System.AppDomain.CurrentDomain.BaseDirectory));
    c.DescribeAllEnumsAsStrings();
  })

http://wmpratt.com/swagger-and-asp-net-web-api-part-1/

введіть тут опис зображення

Це потрібно було встановити як у конфігурації випуску, так і в конфігурації налагодження.


0

Якщо у вас є <deployment retail="true"/>machine.config .NET Framework, ви не побачите детальних повідомлень про помилки. Переконайтеся, що налаштування невірно чи немає.


0

Тож я спробував усі запропоновані рішення безрезультатно. Все, що я робив, було встановити запуск програми з сервера, і вона відображала помилку в повному обсязі, це повинно спрацювати, коли я встановив режим customErrors на false, але він не став. У той момент, коли я переглянув API форми на сервері, я зміг побачити проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.