WCF WebFaultException 详细信息未发送到客户端

WCF WebFaultException details not sent to client

好的,所以..

我有一个 WCF 服务 抛出 一个 WebFaultException<Error>(Error, HttpStatusCode.BadRequest) 其中 Error 是我的自定义,可序列化 object.

当我在本地计算机和 GoDaddy 上托管服务时,这一切都按预期工作(如此处所示:link 已删除)。 但是当使用 Arvixe 托管时,我收到的只是 'Bad Request' 响应(如此处所示:link 已删除

分析响应 headers,看来我的本地计算机、GoDaddy 和 Arvixe 都使用相同的 .NET 版本。但是,我的本地机器是 运行 IIS 8.0,GoDaddy 是 运行 IIS 7.0,而 Arvixe 是 运行 IIS 8.5.

那么,是什么导致了差异? IIS 8.5 是否以不同方式处理 WebFaultException?我在互联网上找不到的任何内容都表明它确实如此。还是IIS需要配置成return WebFaultExceptions?同样,我读到的所有内容都说它完全在 ASP Web.config 中配置。

还有其他建议吗?

** 编辑 **

考虑到它在我的本地计算机 (IIS8) 和 GoDaddy (IIS7) 上运行良好,但在 Arvixe (IIS8.5) 上运行良好,我相当确定这与 IIS 有关,而不是我的代码

无论如何,这里有一些片段:

错误 object 我正在尝试 return

    [DataContract]
public class Error {

    [DataMember]
    public int Code { get; set; }

    [DataMember]
    public string Message { get; set; }

    [DataMember]
    public string Display { get; set; }

    [DataMember]
    public List<Error> Details { get; set; }

    public Error(int code, string message, List<Error> details = null, string display = null) {
        this.Code = code;
        this.Message = message;
        this.Display = display;
        this.Details = details ?? new List<Error>();
    }
}

尝试通过以下方式return将其发送给客户端:

throw new WebFaultException<Error>(new Error(802, "games/asdf"), HttpStatusCode.BadRequest);

我试图抛出 WebFaultException 的方法来自:

    [OperationContract]
    [WebInvoke(
        Method = "GET", 
        UriTemplate = "/games/{game}/scores"
    )]
    List<Score> GetScores(string game);

我试过向该方法添加 [FaultContract(typeof(Error))] 属性,但没有效果。

这是 Web.config 注册我的服务

<?xml version="1.0"?>
<configuration>

<appSettings>
</appSettings>

<connectionStrings>
  <!-- DEV -->
  <add name="App" connectionString="XXX" />
  <add name="Log" connectionString="XXX" />
</connectionStrings>  

<system.web>

  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />

  <webServices>
    <protocols>
      <clear />
      <add name="HttpGet"/>
      <add name="HttpPost" />
      <add name="HttpPostLocalhost" />
    </protocols>
  </webServices>

  <pages>
    <namespaces>
      <add namespace="System.Web.Optimization" />
    </namespaces>
  </pages>

</system.web>

<system.serviceModel>

  <behaviors>

    <serviceBehaviors>

    <!--old-->
    <behavior name="OldService">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>

    <!--new-->
    <behavior name="V3">
      <serviceAuthorization serviceAuthorizationManagerType="ScoresWs.V3.Auth, ScoresWs"/>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />          
    </behavior>

  </serviceBehaviors>

  <endpointBehaviors>
    <behavior name="REST">
      <!--faultExceptionEnabled needs to be false or else we return .net exceptions as xml instead of our custom WebFaultException-->
      <webHttp 
        helpEnabled="true"
        faultExceptionEnabled="false" 
        automaticFormatSelectionEnabled="false" 
        defaultOutgoingResponseFormat="Json" />
    </behavior>
  </endpointBehaviors>

</behaviors>

<bindings>
  <webHttpBinding>
    <binding name="defaultBinding" maxReceivedMessageSize="2097152">
      <security mode="None" />
    </binding>
  </webHttpBinding>
</bindings>

<services>

  <service name="ScoresWs.WebServiceV2" behaviorConfiguration="OldService">
    <endpoint 
      address="" 
      binding="webHttpBinding" 
      behaviorConfiguration="REST" 
      bindingConfiguration="defaultBinding" 
      contract="ScoresWs.IWebServiceV2" />
  </service>

  <service name="ScoresWs.V3.Api" behaviorConfiguration="V3">
    <endpoint
      address=""
      binding="webHttpBinding"
      behaviorConfiguration="REST"
      bindingConfiguration="defaultBinding"
      contract="ScoresWs.V3.IApi"/>
  </service>

</services>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

</system.serviceModel>

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
  <directoryBrowse enabled="false" />
</system.webServer>

<runtime>

  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31ad335" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
        </dependentAssembly>
      </assemblyBinding>

  </runtime>  

</configuration>

Annnnnnd 最后,我在 Global.asax:

中激活了网络服务
    public class Global : System.Web.HttpApplication {

      protected void Application_Start(object sender, EventArgs e) {
        RouteTable.Routes.Add(new ServiceRoute("api/v2", new WebServiceHostFactory(), typeof(ScoresWs.WebServiceV2)));
        RouteTable.Routes.Add(new ServiceRoute("api/v3", new WebServiceHostFactory(), typeof(ScoresWs.V3.Api)));
      }

    }

解决了!就像我怀疑的那样,它与我的代码无关。

在 Arvixe 托管面板中,我必须启用“Show detailed ASP.NET errors in browser”(网站->错误->ASP.NET)。但是,我不确定这对安全性有什么影响,因为 Web.config 没有改变而且我看不到 IIS 配置。

奇怪的是,考虑到 'my detailed ASP.NET errors' 没有发送给客户,Arvixe 支持团队不会立即将我引导到这里。