WCF,接口返回类型和KnownTypes [英] WCF, Interface return type and KnownTypes

查看:114
本文介绍了WCF,接口返回类型和KnownTypes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个WCF服务,我有很多的麻烦与一些序列化的问题。也许,只是1的方式来做到这一点,但我想确认
下面是我的示例code:

I'm creating a WCF service, and I'm having a lot of trouble with some Serialization issues. Perhaps there's just 1 way to do it, but i'd like to confirm it Here's my sample code :

合同

public interface IAtm
    {
        [DataMember]
        double Latitude { get; set; }

        [DataMember]
        double Longitude { get; set; }
    }

[ServiceContract]
    public interface IAtmFinderService
    {

        [OperationContract]
        ICollection<IAtm> GetAtms();

    }

服务实现:

[KnownType(typeof(Atm))]
[KnownType(typeof(List<Atm>))]
[ServiceKnownType(typeof(Atm))]
[ServiceKnownType(typeof(List<Atm>))]
public class AtmFinderService : IAtmFinderService
{
    public ICollection<IAtm> GetAtms()
    {
        return new List<IAtm>()
            {
                new Atm() { Latitude = 1, Longitude = 1 }, 
                new Atm() { Latitude = 2, Longitude = 2 } 
            };
    }
}

我添加了所有KnownType和ServiceKnownType属性,因为我觉得有东西丢失有..
所以,现在,我一直在做一些测试。我试图创建一个控制台应用程序,使用添加服务引用的方法,使VS自动创建代理。这样一来,我得到这样

I added all of the KnownType and ServiceKnownType attributes because i thought that there was something missing there.. So now, i've been doing some tests. I tried creating a console app, using the "add service reference" method to make VS create automatically the proxy. This way, I get a function like

object[] GetAtms();

当试图调用它,我得到这个错误:

When trying to call it, i get this error :

设置InnerException消息是'类型
  WCFTest.Atm'数据合同名称
  大气压:HTTP://schemas.datacontract.org/2004/07/WCFTest
  预计不会。考虑使用
  DataContractResolver或添加任何类型
  不是静态已知的列表
  已知类型 - 例如,通过使用
  在KnownTypeAttribute属性或者
  它们添加到已知类型的列表
  传递给DataContractSerializer的。

The InnerException message was 'Type 'WCFTest.Atm' with data contract name 'Atm:http://schemas.datacontract.org/2004/07/WCFTest' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.

非常好...那么,我认为,VS的自动生成的code是废话。我做了我的服务提出了以下变化(和所有相关类和实现):

Very nice... So then, I think that VS's autogenerated code is crap. I did the following change in my service (and all the related classes and implementations) :

[OperationContract]
        ICollection<Atm> GetAtms();

所以,现在,我要回一个具体类型。更新服务引用后,它会创建ATM类的副本,其成员和东西。
调用该服务后,调用成功。
我认为这是关系到自动生成的code一些不好的行为,所以我试图创建一个非常简单的主机/客户端应用程序。我开始控制台主机监听某个端口上,然后创建一个使用ClientBase类,使该服务的调用客户端。相同的行为......如果服务实现返回一个接口类型,它失败。如果我改变它返回的具体类型,它的工作原理。我认为,我有一些问题与KnownType属性,我一定是失去了一些东西,该串行无法处理。但我不知道是什么。

So now, i'm returning a concrete type. After updating the service reference, it creates a copy of the Atm class, with its members and stuff. After calling the service, the call succeeds. I thought that this was some bad behaviour related to the autogenerated code, so i tried creating a very simple host/client app. I started a console host listening on some port, then created a client that uses the ClientBase class to make a call to the service. Same behaviour... if the service is implemented returning an interface type, it fails. If i change it to return the concrete type, it works. I think that i have some problem with the KnownType attributes, i must be missing something that the serializer can't process. but i don't know what.

推荐答案

好吧,我设法解决它
这个问题,在我看来,是这样的。

Ok, i managed to fix it The problem, as I see it, was this

由于我返回一个接口,而不是一个具体的类,WCF不知道会在另一端的东西。因此,它可以是任何东西。当他得到一个清单,他的困惑。
正确的方法做到这一点是添加的属性KnownType在需要的地方。

谁需要知道那些类型?服务实现,序列化和反序列化正确它们。但是,客户端与服务的接口会谈,不与实现本身。这就是为什么在服务实现增加theKnownType属性没有工作

这里的问题是,接口不允许KnownType属性,但它们确实允许ServiceKnownType属性。这个问题的解决办法是在服务接口的合同加上预计的类型,瞧,一切工作正常,并使用接口

Since I'm returning an interface and not a concrete class, WCF doesn't know what to expect on the other end. So, it can be anything. When he gets a List, he's confused.
The correct way to do it was to add the KnownType attributes where needed.
Who needs to know those types? the service implementation, to serialize and deserialize them correctly. However, the client talks with the interface of the service, not with the implementation itself. That's why adding theKnownType attribute in the service implementation didn't work
The problem here is that, interfaces don't allow KnownType attributes, but they do allow ServiceKnownType attributes. The solution to the problem was to add the expected type in the service interface contract, and voila, everything works ok and using interfaces

    [ServiceContract]
    [ServiceKnownType(typeof(Atm))]
    [ServiceKnownType(typeof(List<Atm>))]
    public interface IAtmFinderService
    {

        [OperationContract]
        ICollection<IAtm> GetAtms();

    }

这篇关于WCF,接口返回类型和KnownTypes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆