WCF 不能传输 IList? 解决方案
好久没有上来写点东西了, 一直都比较忙, 而在公司的时候又禁止写Blog,今天开始给自己放长假,可以常来写写东西了。。。。
在我做毕业设计 的过程中, 遇到的一个问题就是通过 WCF, Client端不能从Server端取得IList数据(放在IList当中的是自定义类型), 后来花了九牛二虎之力才找到讲这个问题的文章:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1460184&SiteID=1
发现原因是我没有在ServiceContact 上加一个Attribute: ServiceKnownType.
下面代码引自那篇文章:
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;
public interface IPerson
{
string Name { get; }
}
[DataContract]
public class Person : IPerson
{
string n;
[DataMember]
public string Name
{
get { return this.n; }
set { this.n = value; }
}
}
[DataContract]
public class Foo
{
[DataMember]
public IList<IPerson> a;
}
[ServiceContract]
[ServiceKnownType(typeof(Person))]
public interface IMyContract
{
[OperationContract]
Foo echo(Foo s);
}
public class MyService : IMyContract
{
public Foo echo(Foo s) { return s; }
}
public class Repro
{
public static void Main()
{
Uri address = new Uri("http://localhost:8004/Service");
Binding binding = new BasicHttpBinding();
ServiceHost service = new ServiceHost(typeof(MyService), address);
service.AddServiceEndpoint(typeof(IMyContract), binding, address);
service.Open();
ChannelFactory<IMyContract> cf = new ChannelFactory<IMyContract>(binding, new EndpointAddress(address));
IMyContract proxy = cf.CreateChannel();
Person p = new Person();
p.Name = "John";
Foo foo = new Foo();
foo.a = new Person[] { p };
Console.WriteLine(proxy.echo(foo).a[0].Name);
((IClientChannel)proxy).Close();
service.Close();
Console.WriteLine("Done, press a key");
Console.ReadKey();
}
}
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;
public interface IPerson
{
string Name { get; }
}
[DataContract]
public class Person : IPerson
{
string n;
[DataMember]
public string Name
{
get { return this.n; }
set { this.n = value; }
}
}
[DataContract]
public class Foo
{
[DataMember]
public IList<IPerson> a;
}
[ServiceContract]
[ServiceKnownType(typeof(Person))]
public interface IMyContract
{
[OperationContract]
Foo echo(Foo s);
}
public class MyService : IMyContract
{
public Foo echo(Foo s) { return s; }
}
public class Repro
{
public static void Main()
{
Uri address = new Uri("http://localhost:8004/Service");
Binding binding = new BasicHttpBinding();
ServiceHost service = new ServiceHost(typeof(MyService), address);
service.AddServiceEndpoint(typeof(IMyContract), binding, address);
service.Open();
ChannelFactory<IMyContract> cf = new ChannelFactory<IMyContract>(binding, new EndpointAddress(address));
IMyContract proxy = cf.CreateChannel();
Person p = new Person();
p.Name = "John";
Foo foo = new Foo();
foo.a = new Person[] { p };
Console.WriteLine(proxy.echo(foo).a[0].Name);
((IClientChannel)proxy).Close();
service.Close();
Console.WriteLine("Done, press a key");
Console.ReadKey();
}
}