服务合同的RealProxy引发WCF错误异常

康奈尔·奥唐奈

我有一个带有WCF后端和UWP前端的C#应用​​程序。我有一项服务正在执行我的服务合同。如果我在服务上捕获到异常,然后将它们作为Fault Exception重新抛出,那么一切都会按预期进行。

现在,我试图通过使用RealProxy实例包装服务调用并从代理抛出我的Fault Exception来清理我的服务代码。不幸的是,现在在服务上引发异常时,我的客户端收到带有以下消息的异常:

“服务器未提供有意义的答复;这可能是由于合同不匹配,会话过早关闭或内部服务器错误引起的。”

我有以下服务合同:

[ServiceContract(Namespace = @"blah/blah/blah", SessionModel = SessionMode.Required)
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(Exception))]
    bool DoSomething(Setting setting);
}

通过以下实现:

[Export(typeof(IService1)]
[ServiceBehavior(InstanceContextMode = IntanceContextMode.Single,
    ConcurrencyMode = ConcurrencyModel.Single]
public class Service1 : IService1
{
    bool DoSomthing(Setting setting)
    {
        try
        {
            throw new ArgumentException("setting");
        }
        catch (Exception ex)
        {
            throw WrapException(ex);
        }
    } 

    private FaultException<Exception> WrapException(Exception ex)
    {
        string message = exception.GetBaseException().Message;
        Console.WriteLine(string.Format("Exception: {0}", message));
        return new FaultException<Exception>(exception, new FaultReason(message));
    }
}

我的WCF服务主机具有以下配置,并且在客户端具有相应的配置。

<system.serviceModel>
    <services>
      <service name="Host.Services.Service1">
        <endpoint address="net.tcp://localhost:8082/Service1" 
            binding="netTcpBinding" 
            contract="Host.Domain.IService1"/>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding maxReceivedMessageSize="1000000">
          <security mode="None"></security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

现在,我创建了一个代理:

public class ServiceProxy<T> : RealProxy
    {
        private readonly T _instance;

        private ServiceProxy(T instance)
        : base(typeof(T))
        {
            _instance = instance;
        }

        public static T Create(T instance)
        {
            return (T) new ServiceProxy<T>(instance).GetTransparentProxy();
        }

        public override IMessage Invoke(IMessage msg)
        {
            var methodCall = (IMethodCallMessage) msg;
            var method = (MethodInfo) methodCall.MethodBase;

            try
            {
                var result = method.Invoke(_instance, methodCall.InArgs);
                return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
            }
            catch (Exception ex)
            {
                string message = ex.GetBaseException().Message;
                Console.WriteLine(string.Format("Exception: {0}", message));
                var wrapped = new FaultException<Exception>(ex, new FaultReason(message));

                return new ReturnMessage(wrapped, msg as IMethodCallMessage);
            }
        }
    }

(感谢@bradmo提出这个想法。)

动态创建代理类

我正在使用代理作为服务:

static void Main(string[] args)
{
    try
    {
        var service = new Bootstrapper().Run().GetExport<IService1>().Value;
        IService1 proxy = ServiceProxy<IService1>.Create(service);

          using (var host = new ServiceHost(proxy))
          {
                host.Open();
                Console.WriteLine("Running...");
                Console.ReadLine();
          }
     }
     catch (Exception ex)
     {
          Console.WriteLine(string.Format("Exception: {0}", ex.GetBaseException().Message));
          Console.ReadLine();
     }
  }
}

在没有代理的情况下抛出Fault Exception可以很好地工作,并且在没有异常的情况下代理也可以正常工作,但是当我使用代理包装异常时,在客户端会出现以下错误:

“服务器未提供有意义的答复;这可能是由于合同不匹配,会话过早关闭或内部服务器错误引起的。”

豪尔赫·德尔·孔德

问题似乎与您定义FaultContract的方式有关。

尝试按照以下方式做一些事情,看看是否有帮助:

public interface IService
{
    [OperationContract]
    [FaultContract(typeof(WrappedExceptionFault))]
    bool DoSomething(string setting);
}

[DataContract]
public class WrappedExceptionFault
{
    [DataMember]
    public string Message { get; set; }
}

public class Service : IService
{
    public bool DoSomething(string setting)
    {
        try
        {
            throw new ArgumentException(setting);
        }
        catch (Exception ex)
        {
            throw WrapException(ex);
        }
    }

    private FaultException<WrappedExceptionFault> WrapException(Exception ex)
    {
        string message = ex.GetBaseException().Message;
        Console.WriteLine(string.Format("Exception: {0}", message));
        WrappedExceptionFault fault = new WrappedExceptionFault()
        {
            Message = message,
        };

        return new FaultException<WrappedExceptionFault>(fault, new FaultReason(message));
    }
}

另外:您不应该将serviceHost包装在“ using”子句的周围..您只是在问大麻烦。考虑做这样的事情:

        ServiceHost host = new ServiceHost(proxy);
        host.Open();
        Console.WriteLine("Running...");
        Console.ReadLine();

        try
        {
            host.Close();
        }
        catch
        {
            host.Abort();
        }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我应该如何处理WCF服务中引发的异常?

WCF服务引发内部服务器错误

调用外部合同会引发错误:处理事务时VM异常:恢复

WCF服务异常处理

WCF服务:响应对象中的故障异常与错误消息

确定哪个合同是称为WCF的WCF服务

WCF数据服务引发“操作可能破坏运行时的稳定性”异常

WCF服务引发异常:无法通过授权为SSL / TLS安全通道建立信任关系

WCF服务会引发异常,但客户端永远不会收到它

WCF引发服务器拒绝客户端凭据的异常,WCF中NetTCP的默认安全模式是什么

WCF RIA服务DomainService错误:ContractDescription的操作为零;合同必须至少进行一项操作

通过WCF引发异常的正确方法

如何更改不影响客户的WCF服务合同?

WCF 服务适用于 Server 2012 R2,但在 2016 上引发错误

引发异常错误“终止称为...”

WCF RESTful服务错误

WCF错误:服务太忙

WCF:客户端配置中的合同“ X”与服务合同中的名称不匹配

WCF服务-配置Web服务绑定异常

从WebApi调用WCF服务会引发MessageSecurityException

Netbeans和错误服务配置文件,或在构造Processor对象时引发的异常

DRF 异常“NotAuthenticated”引发 500 内部服务器错误代替 401/403

IIS上的WCF托管引发异常(没有权限和HTTP错误404.3-找不到)

如何检查内部服务是否引发异常?

服务验证:如果验证失败,则引发异常

WCF合同更改IsRequiredMessage

线程中的异常处理,联系WCF服务

WCF REST完整服务中的异常处理

WCF服务中的代码错误