【问题标题】:WCF WebFaultException details not sent to clientWCF WebFaultException 详细信息未发送到客户端
【发布时间】:2015-05-23 14:24:50
【问题描述】:

好的,所以..

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

当我在本地机器和 GoDaddy 上托管服务时,这一切都按预期工作(如下所示:链接已删除)。 但是当使用 Arvixe 托管时,我收到的只是“错误请求”响应(如下所示:链接已删除

分析响应标头,我的本地机器 GoDaddy 和 Arvixe 似乎都使用相同的 .NET 版本。但是,我的本地机器运行的是 IIS 8.0,GoDaddy 运行的是 IIS 7.0,而 Arvixe 运行的是 IIS 8.5。

那么,造成这种差异的原因是什么? IIS 8.5 处理 WebFaultException 的方式不同吗?我在互联网上找到的任何东西都没有表明它确实如此。或者是否需要将 IIS 配置为返回 WebFaultExceptions?同样,我读到的所有内容都说它完全在 ASP Web.config 中配置。

还有其他建议吗?

** 编辑 **

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

无论如何,这里有一些 sn-ps:

我试图返回的错误对象

    [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>();
    }
}

尝试通过以下方式将其返回给客户端:

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>

最后我激活了 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)));
      }

    }

【问题讨论】:

  • 可能与 svc 处理程序映射 (IIS 8.x) stackoverflow.com/questions/11116134/… 有关
  • 嗯.. 这似乎是一个不同的问题。我的服务运行正常,当我将它们抛出错误请求时,它不会返回自定义 WebFaultException 详细信息(有效请求正确返回 json 响应)。
  • 显示一些重现问题的示例代码?

标签: c# asp.net .net wcf iis


【解决方案1】:

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

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

奇怪的是,考虑到“我的详细 ASP.NET 错误”没有发送给客户端,Arvixe 支持团队不会立即将我指示到这里。

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 2015-08-05
    • 2011-04-24
    • 2017-08-04
    • 2017-10-02
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多