2013-05-09 105 views
1

我的WebAPI控制器出现了一个奇怪的问题。WebAPI为什么抛出'No 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,这给了我同样的结果。

编辑: 这里有一些更多的测试,我对自己的成绩试图沿:

  • 当我发送邮件使用它按预期工作的外部工具POST请求的Web服务我的本地机器上。
  • 当我执行使用我的本地代码副本调用Web服务的代码时,它按预期工作。
  • 当我使用外部工具向集成机器上的Web服务发送POST请求时,它会按预期工作。
  • 当我执行使用集成机器调用Web服务的代码时,出现上述错误。

的代码发送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; 
    } 

更新:我安装的网站和网络服务2008年服务器。从2003年的网站(2003网站 - > 2003服务)的网站调用2003盒子上的网络服务时,唯一出现故障的组合似乎是失败的。其他三种组合(2008年站点 - > 2008年服务,2008年站点 - > 2003年服务,2003年站点 - > 2008年服务)似乎都工作正常。

+0

您是否尝试过使用内容类型作为'application/json; charset = utf-8',? 使用提琴手找出确切的问题。 – Rifaj 2013-05-09 10:48:59

+0

你可以显示你的配置?该错误与该代码根本无关。您是否安装了任何MessageHandlers或全局操作筛选器?此外,您可能需要安装Web API跟踪块以获取更多详细信息 – 2013-05-09 11:23:58

+0

@Rifaj - 响应的内容类型设置为“application/json”。我可以添加“charset = utf8”部分,看看是否有帮助。 – nikeaa 2013-05-09 13:08:20

回答

0

好吧,事实证明,这与代码无关,正如你们中的一些人所表达的那样。基本上,我必须将2003盒子上的hosts文件中的本地环回地址(127.0.0.1)更改为2003盒子的实际IP地址,现在所有的工作都可以像现在这样进行。去搞清楚。

+2

实际上,这是因为被调用的Web服务没有响应,所以它返回了一个500错误,它是HTML格式的,并且因为它没有被设置为识别HTML,所以错误出现了。通过拦截无效的HTTP响应代码并以正确格式化的消息返回,此问题已得到解决。 – nikeaa 2013-08-02 20:38:15

+0

评论中的答案是我在Web API路由发生变化时遇到的问题。 – jmsb 2015-09-21 18:55:15