在这个问题上,我把头撞到了墙上,并且检查了所有其他类似的问题,但都没有结果。我有一个简单的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",而不是“发件人”。
<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时指定名称/名称空间。
[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));我还没有百分之百地知道为什么要这样,但至少它是有效的!
发布于 2016-05-20 17:21:10
我自己试了一下,也发现了同样的问题。然后,我尝试添加名称和名称空间,然后就成功了。
[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; }
}我认为,当您在不同的程序集上承载相同的代码时,它将接受该程序集的命名空间,因此在客户端连接到服务时不匹配,因此需要至少在数据契约上指定namespace。
永远记得正确地指定你的合同,孩子;-)
https://stackoverflow.com/questions/37350312
复制相似问题