2013-05-09 2 views
1

У меня странная проблема с моим контроллером WebAPI.Почему WebAPI бросает ошибку «Нет MediaTypeFormatter»?

В моей среде разработки (Win7, IIS 7.5) вызывается метод на контроллере, и результат возвращается как ожидалось.

В моей среде интеграции (WIn Server 2003, IIS 6.0) Я развернул код, скопировав его из своей коробки разработки в окно интеграции. Метод на контроллере называется и возвращает следующее сообщение об ошибке:

"No MediaTypeFormatter is available to read an object of type "EmailQueueResult" from content with media type "text/html"."

То, что я не понимаю, почему я только получаю эту ошибку в моей среде интеграции, а не в моей среде разработки.

public HttpResponseMessage Post([FromBody]EmailQueueMessage email) 
    { 
     EmailQueueResult result; 

     if (email != null) 
     { 
      try 
      { 
       var emailQueueIdList = QueueEmails(email); 

       QueueAttachments(email, emailQueueIdList); 

       foreach(var emailQueueId in emailQueueIdList) 
       { 
        UpdateEmailQueueDateQueued(emailQueueId, DateTime.Now); 
       } 

       result = new EmailQueueResult(0, "Email added to queue.", "", null); 
      } 
      catch (Exception e) { 
       result = new EmailQueueResult(2, "Error occurred.", e.Message, null); 
      } 
     } 
     else 
     { 
      result = new EmailQueueResult(1, "Email passed in was null.", "", null); 
     } 

     return ControllerContext.Request.CreateResponse(HttpStatusCode.OK, result, "application/json"); 
    } 

WebApiConfig.cs:

namespace App_Start 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      config.Routes.MapHttpRoute(
       "ControllerWithBooleanParameter", 
       "api/{controller}/{showSentEmails}", 
       null, 
       new { boolConstraint = new IsBoolean() } 
      ); 
      config.Routes.MapHttpRoute(
       "ControllerWithIntegerParameter", 
       "api/{controller}/{id}", 
       null, 
       new { id = @"^\d+$" } 
      ); 
      config.Routes.MapHttpRoute(
       "Default", 
       "api/{controller}/{id}", 
       new { id = UrlParameter.Optional } 
      ); 
     } 
    } 
} 

Web.config:

<?xml version="1.0" encoding="utf-8"?> 
<!-- 
    For more information on how to configure your ASP.NET application, please visit 
    http://go.microsoft.com/fwlink/?LinkId=169433 
    --> 
<configuration> 
    <appSettings> 
     <add key="webpages:Version" value="2.0.0.0" /> 
     <add key="webpages:Enabled" value="false" /> 
     <add key="PreserveLoginUrl" value="true" /> 
     <add key="ClientValidationEnabled" value="true" /> 
     <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 
    </appSettings> 
    <system.net> 
     <settings> 
      <httpWebRequest useUnsafeHeaderParsing="true" /> 
     </settings> 
     <mailSettings> 
      <smtp from="[email protected]"> 
       <network host="smtp.server.com" port="25" /> 
      </smtp> 
     </mailSettings> 
    </system.net> 
    <system.web> 
     <compilation debug="true" targetFramework="4.0" /> 
     <authentication mode="None" /> 
     <pages> 
      <namespaces> 
       <add namespace="System.Web.Helpers" /> 
       <add namespace="System.Web.Mvc" /> 
       <add namespace="System.Web.Mvc.Ajax" /> 
       <add namespace="System.Web.Mvc.Html" /> 
       <add namespace="System.Web.Optimization" /> 
       <add namespace="System.Web.Routing" /> 
       <add namespace="System.Web.WebPages" /> 
      </namespaces> 
     </pages> 
    </system.web> 
    <system.webServer> 
     <validation validateIntegratedModeConfiguration="false" /> 
     <modules runAllManagedModulesForAllRequests="true" /> 
     <handlers> 
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> 
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> 
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> 
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> 
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
     </handlers> 
    </system.webServer> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
      <dependentAssembly> 
       <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> 
       <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> 
      </dependentAssembly> 
      <dependentAssembly> 
       <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> 
       <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> 
      </dependentAssembly> 
      <dependentAssembly> 
       <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> 
       <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> 
      </dependentAssembly> 
     </assemblyBinding> 
    </runtime> 
</configuration> 

Я также попытался имея этот метод просто возвращает прямую EmailQueueResult, и это дало мне одни и те же результаты.

EDIT: Вот еще несколько тестов, которые я пытался вместе с их результатами:

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

строка кода, который отправляет POST:

 EmailQueueResult result = PostToWebService<EmailQueueMessage, EmailQueueResult>(EmailQueueBaseAddress, "application/json", EmailQueueUrlToCall, emailQueueMessage); 

метод PostToWebService, что на самом деле делает вызов:

protected returnType PostToWebService<dataType, returnType>(string baseAddress, string mediaType, string urlToCall, dataType data) 
    { 
     HttpClient client = new HttpClient(); 
     client.BaseAddress = new Uri(baseAddress); 

     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(mediaType)); 

     MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter(); 

     HttpContent content = new ObjectContent<dataType>(data, jsonFormatter); 

     HttpResponseMessage response = client.PostAsync(urlToCall, content).Result; 

     returnType result = response.Content.ReadAsAsync<returnType>().Result; 

     return result; 
    } 

UPDATE: Я установил веб-сайта и веб-службы на сервер 2008 года. Единственная комбинация, которая терпит неудачу, похоже, когда веб-служба на поле 2003 вызывается с веб-сайта в окне 2003 (услуга 2003 сайта -> 2003). Остальные три комбинации (сайт 2008 года -> 2008, сайт 2008 года -> 2003, сайт 2003 года -> 2008), похоже, работают правильно.

+0

Вы пробовали использовать тип контента как 'application/json; charset = utf-8 ',? Используйте скрипач, чтобы выяснить точную проблему. – Rifaj

+0

Можете ли вы показать свою конфигурацию? Эта ошибка вообще не связана с этим кодом. У вас есть какие-либо фильтры MessageHandlers или глобальные фильтры действий?Кроме того, вы можете захотеть установить самородку трассировки веб-API, чтобы получить более подробную информацию. –

+0

@Rifaj. Тип контента ответа задан как «application/json». Я могу добавить часть charset = utf8 и посмотреть, поможет ли это. – nikeaa

ответ

0

Хорошо, получается, что это не НИЧЕГО было сделано с кодом, как некоторые из вас высказали выше. В принципе, мне пришлось изменить локальный loopback-адрес (127.0.0.1) в моем файле hosts в поле 2003 на фактический IP-адрес окна 2003 года, и все работает так, как показано в настоящий момент. Идите фигуру.

+2

На самом деле это произошло потому, что вызываемая веб-служба не отвечала, поэтому она возвращала ошибку 500, которая была отформатирована в формате HTML, и поскольку она не была настроена для распознавания HTML, возникла ошибка. Перехватывая неверные коды ответа HTTP и возвращенные в правильно отформатированном сообщении, эта проблема была решена. – nikeaa

+0

Ответ в комментариях был проблемой, с которой я столкнулся, когда меня изменил маршрут веб-API. – jmsb

Смежные вопросы