首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将FaultException<T>反序列化为FaultException

将FaultException<T>反序列化为FaultException
EN

Stack Overflow用户
提问于 2016-05-20 15:25:58
回答 1查看 981关注 0票数 0

在这个问题上,我把头撞到了墙上,并且检查了所有其他类似的问题,但都没有结果。我有一个简单的FaultException,我把它放在WCF服务器上,并捕捉到客户端。

,这是合同:

代码语言:javascript
运行
复制
[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; }
}

引发异常的服务器代码:

代码语言:javascript
运行
复制
throw new FaultException<TDetail>(new TDetail("Test"), "My test fault.");

客户端接收的XML (由Fiddler提供):

我对此有点怀疑,因为我的课名为"TDetail",而不是“发件人”。

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

获取异常的客户端代码:

代码语言:javascript
运行
复制
catch (FaultException<TDetail> ex)
{
    // I expect this
}
catch (FaultException ex)
{
    // But get this D:
}

和客户端接收的异常:

代码语言:javascript
运行
复制
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时指定名称/名称空间。

代码语言:javascript
运行
复制
[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));

我还没有百分之百地知道为什么要这样,但至少它是有效的!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-20 17:21:10

我自己试了一下,也发现了同样的问题。然后,我尝试添加名称和名称空间,然后就成功了。

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

永远记得正确地指定你的合同,孩子;-)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37350312

复制
相关文章

相似问题

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