我有一個帶有WCF後端和UWP前端的C#應用程序。我有一個實施我的服務合同的服務。如果我在服務上捕獲異常並將它們重新拋出爲Fault Exceptions,那麼一切都按預期工作。從服務合同的RealProxy中拋出WCF錯誤異常
現在我試圖通過使用RealProxy實例包裝服務調用來清理我的服務代碼,並從代理中拋出我的Fault Exceptions。不幸的是,現在,當服務發生異常時,我的客戶端會收到一個異常,並顯示以下消息:
「服務器沒有提供有意義的回覆;這可能是由於合同不匹配,過早會話關閉或內部服務器錯誤「。
我有以下的服務合同:
[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>
,我創建了一個代理:(感謝@bradmo的想法)
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);
}
}
}
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();
}
}
}
在沒有代理的情況下拋出錯誤異常工作正常,代理在沒有例外的情況下工作正常,但是當我使用代理打包異常時,客戶端出現以下錯誤:
「服務器沒有提供有意義的答覆;這可能是由合同的不匹配,過早的會話關閉或內部服務器錯誤引起的。」
感謝您的回答。爲什麼在'using'中包裝服務主機不好? –
網絡上有很多文檔。以下是一些解釋原因的文章:https://philmunro.wordpress.com/2011/03/07/wcf-using-gotcha/ && https://msdn.microsoft.com/en-us/library/aa355056( v = vs.110).aspx –
這就完成了。謝謝。 –