我在这个问题上碰到了我的头,并检查了所有其他类似的问题,但无济于事。我有一个简单的FaultException,我正在抛弃WCF服务器并捕获客户端。
这是合同:
[ServiceContract]
public interface MyContract
{
[OperationContract, FaultContract(typeof(TDetail))]
void ThrowException();
}
[DataContract]
public class TDetail
{
public TDetail(string test) {
Test = test;
}
[DataMember]
public string Test { get; set; }
}
抛出异常的服务器代码:
throw new FaultException<TDetail>(new TDetail("Test"), "My test fault.");
客户收到的XML(由Fiddler提供):
我对此有点怀疑,因为我的课程被命名为“TDetail”,而非“Sender”。
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-US">My test fault.</faultstring>
<detail>
<Sender xmlns:a="http://schemas.datacontract.org/2004/07/Sample.Namespace" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Test>MyTest</a:Test>
</Sender>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
获取例外的客户端代码:
catch (FaultException<TDetail> ex)
{
// I expect this
}
catch (FaultException ex)
{
// But get this D:
}
客户收到的例外:
System.ServiceModel.FaultException was caught
HResult=-2146233087
Message=My test fault.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Sample.Namespace.ThrowException()
InnerException:
对于我的生活,我无法弄清楚为什么TDetail显然被客户抛弃了。我确定客户端和服务器都引用了同一个类(我将DLL复制粘贴到正确的文件夹中),我的实现并不复杂。这甚至在去年工作正常,从那以后我找不到任何实质性的代码更改。
有任何帮助吗? :(
为什么我的问题与潜在的副本不一样: 副本的设置更加复杂。最明显的是,他们实际上是在实现自定义的ErrorHandler并创建自己的错误(问题出在哪里),我不是。他们的答案不适用于我的情况。
最终解决方案: 我最终必须在FaultContract和我抛出FaultException时指定Name / Namespace。
[ServiceContract(Namespace = "MyNamespace")]
public interface MyContract
{
[OperationContract]
[FaultContract(typeof(TDetail), Name = "TDetail"]
void ThrowException();
}
throw new FaultException<TDetail>(new TDetail("Test"),
"My test fault.",
new FaultCode("TDetail", "MyNamespace));
我还不是100%为什么必须这样,但至少它有效!
答案 0 :(得分:0)
我自己尝试了,发现了同样的问题。然后我尝试添加名称和命名空间然后它工作。
[ServiceContract(Name = "MyContract", Namespace = "MyNameSpace")]
public interface MyContract
{
[OperationContract, FaultContract(typeof(TDetail))]
void ThrowException();
}
[DataContract(Name = "TDetail", Namespace = "MyNameSpace")]
public class TDetail
{
public TDetail(string test)
{
Test = test;
}
[DataMember]
public string Test { get; set; }
}
我认为发生的事情是,当您在不同的程序集上托管相同的代码时,它会占用该程序集的命名空间,因此在客户端连接到服务时不匹配,因此需要指定命名空间至少在数据合同上。
始终记得正确指定孩子的合同; - )