none
WCF中的FaultException客户端无法捕获? RRS feed

  • 问题

  • 大家好,我在WCF(宿主在ASP.NET中)中写了个FaultException异常(由于简单异常,所以没有用FaultException<T>泛型):

    // 接口
    public interface IClientService
    {
        [OperationContract]
        int Add(int a, int b);
    }
    
    // 实现
    public class ClientService : IClientService
    {
        public int Add(int a, int b)
        {
            throw new FaultException("hello world");
        }
    }

    客户端是WPF,在开发环境下,调用Add方法可以正常捕获到异常,异常类型为FaultException,

    然后我部署到服务器A上,OK,没问题,异常也能正常捕获,

    但我部署到服务器B上,异常无法正常捕获,客户端调用Add方法后,一直没有响应,也不报错,一直到请求超时才报请求超时的错,

    以下是我多次实验的结果:
    1.将WPF客户端拷贝到服务器B上,可以正常捕获异常,但在服务器之外却无法正常捕获异常,WCF地址配置也是正确的,即:异常无法在远程捕获,
    2.我按照【https://www.cnblogs.com/GISerYang/archive/2012/09/10/2679340.html】网址上配置IIS却无效,异常仍然无法在远程客户端捕获,
    3.我也配置了WCF的【includeExceptionDetailInFaults=true】也无效,
    4.我在网站上建立了一个WebForm1.aspx,然后在此页面上直接throw new Exception,远程无法查看错误信息,服务器上可以查看到,
    5.WCF不管是【throw new FaultException】还是【throw new Exception】都无法捕获,但本地开发环境都可以捕获,

    为此我已经提出了两个问题贴,大家可以看看:
    https://social.msdn.microsoft.com/Forums/zh-CN/4ea0ded3-829c-45e5-b799-14a21cbc4426/iis-?forum=2212
    https://social.msdn.microsoft.com/Forums/zh-CN/b6d7ec51-9cd7-457e-b0d4-0279c50c55b8/-wcf-?forum=wcfzhchs

    到底为什么无法捕获到异常?


    • 已编辑 jesse hao 2017年11月17日 11:46
    2017年11月17日 11:07

答案

  • Hi jesse,

    >>如何不让VPN重定向IIS的错误?

    如果想避免IIS返回的Response状态是500,我们可以在WCF里面设置ReponseHttpStatusCode,我建议你尝试下面的代码看看是否可以解决问题

            public string GetData(int value)
            {           
                WebOperationContext ctx = WebOperationContext.Current;
                ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
                throw new FaultException("Server Exception");
                return string.Format("You entered: {0}", value);
            }
    

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 jesse hao 2017年11月23日 3:25
    2017年11月20日 1:58
    版主

全部回复

  • 大家好,我们的后台适用asp.net + WCF部署的WCF服务,客户端使用的是WPF,

    我们后台一直适用throw new Exception的方式将错误提示抛出到客户端,客户端通过MessageBox或其他的方式处理,

    之前我们将asp.net的WCF部署到iis的80端口上,没问题!

    但后来换了台服务器,这台服务器只开放一个端口(例如8080),然后这一个端口还被另外一个网站(网站A)占用,无奈之下我们的WCF只能部署到8080网站下属的虚拟应用程序中,我们的WCF服务的根目录自然就成了:
    http://192.168.1.1:8080/MyWCF

    然后部署上去没问题,客户端wcf也正常运行,但发现:
    凡是后台throw new Exception的错误,客户端都无法捕获到!当后台抛出错误,客户端毫无响应,就好像http协议没有响应一样,客户端的进度条一直转到超时!!

    奇怪的是,我将WPF客户端拷贝到服务端运行就没有问题,错误可以正常捕获到,

    我猜测可能的原因:

    1.错误只能在本机查看,却不能远程查看,我设置了<customErrors mode="On/Off"/>(分别设置了On和Off)都不起作用,

    2.由于我们的WCF是网站A的虚拟应用程序,所以可能是网站A并不允许WCF错误通过http协议暴露出去,但我们在网站A的webconfig中配置【includeExceptionDetailInFaults=true】并没解决问题,代码如下:

      <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding name="" maxBufferPoolSize="2147483647" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
            </binding>
          </basicHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
      </system.serviceModel>

    那么我们如何将错误抛出到客户端呢?





    2017年11月16日 10:38
  • Hi jesse,

    根据你的描述,你是将WCF 服务端的异常直接暴露给客户端,再由客户端来处里异常,我觉得这不是友善处理WCF异常的方式,一般,我们都是通过服务端捕获异常,返回一个友好的FaultContract, 然后再在客户端去捕获FaultException

    你可以参照下面的链接去实现简单的FaultContract(没有找到对应的中文链接,可以翻译一下)

    #Fault Contract

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/fault-contract

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月17日 2:14
    版主
  • 我知道问题所在了,是VPN搞的鬼,因为链接服务器需要链接VPN,而在局域网房屋服务器可以正常捕获500错误,而VPN检测到500错误又重定向了500错误,

    现在的问题是,如何不让VPN重定向IIS的错误?

    2017年11月17日 12:04
  • Hi jesse,

    >>如何不让VPN重定向IIS的错误?

    如果想避免IIS返回的Response状态是500,我们可以在WCF里面设置ReponseHttpStatusCode,我建议你尝试下面的代码看看是否可以解决问题

            public string GetData(int value)
            {           
                WebOperationContext ctx = WebOperationContext.Current;
                ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
                throw new FaultException("Server Exception");
                return string.Format("You entered: {0}", value);
            }
    

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 jesse hao 2017年11月23日 3:25
    2017年11月20日 1:58
    版主