首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从服务契约的RealProxy引发WCF错误异常

从服务契约的RealProxy引发WCF错误异常
EN

Stack Overflow用户
提问于 2017-02-07 22:54:13
回答 1查看 1K关注 0票数 2

我有一个具有WCF后端和UWP前端的C#应用程序。我有一个实现我的服务合同的服务。如果我捕获服务上的异常,并将它们作为错误异常重新抛出,那么一切都会按预期进行。

现在,我试图通过使用RealProxy实例包装服务调用并从代理抛出错误异常来清理我的服务代码。不幸的是,现在当在服务上抛出异常时,我的客户端收到一个异常,并显示以下消息:

服务器未提供有意义的回复;这可能是由于约定不匹配、会话过早关闭或内部服务器错误造成的。

我有以下服务合同:

代码语言:javascript
复制
[ServiceContract(Namespace = @"blah/blah/blah", SessionModel = SessionMode.Required)
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(Exception))]
    bool DoSomething(Setting setting);
}

使用以下实现:

代码语言:javascript
复制
[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服务主机具有以下配置,在客户端具有相应的配置。

代码语言:javascript
复制
<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>

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

代码语言:javascript
复制
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的想法。)

Dynamically creating a proxy class

我使用代理作为我的服务:

代码语言:javascript
复制
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();
     }
  }
}

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

服务器未提供有意义的回复;这可能是由于约定不匹配、会话过早关闭或内部服务器错误造成的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-16 04:58:57

问题似乎出在定义FaultContract的方式上。

试着按照这些思路做点什么,看看是否有帮助:

代码语言:javascript
复制
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。你这是在自找麻烦。考虑这样做:

代码语言:javascript
复制
        ServiceHost host = new ServiceHost(proxy);
        host.Open();
        Console.WriteLine("Running...");
        Console.ReadLine();

        try
        {
            host.Close();
        }
        catch
        {
            host.Abort();
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42092955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档