我有一个具有WCF后端和UWP前端的C#应用程序。我有一个实现我的服务合同的服务。如果我捕获服务上的异常,并将它们作为错误异常重新抛出,那么一切都会按预期进行。
现在,我试图通过使用RealProxy实例包装服务调用并从代理抛出错误异常来清理我的服务代码。不幸的是,现在当在服务上抛出异常时,我的客户端收到一个异常,并显示以下消息:
服务器未提供有意义的回复;这可能是由于约定不匹配、会话过早关闭或内部服务器错误造成的。
我有以下服务合同:
[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的想法。)
Dynamically creating a proxy class
我使用代理作为我的服务:
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();
}
}
}在没有代理的情况下抛出错误异常可以很好地工作,当没有异常时,代理也可以正常工作,但是当我使用代理包装异常时,我在客户端得到以下错误:
服务器未提供有意义的回复;这可能是由于约定不匹配、会话过早关闭或内部服务器错误造成的。
发布于 2017-02-16 04:58:57
问题似乎出在定义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();
}https://stackoverflow.com/questions/42092955
复制相似问题