C# 在WCF中序列化集合要使用什么属性?
我有一个类,它的泛型集合是我正在用WCF序列化的属性:C# 在WCF中序列化集合要使用什么属性?,c#,wcf,C#,Wcf,我有一个类,它的泛型集合是我正在用WCF序列化的属性: [ServiceContract] public interface IService1 { [OperationContract] TestObject Load(); } [DataContract] public class TestObject { [DataMember] public Collection<object> Properties = new Collection<
[ServiceContract]
public interface IService1
{
[OperationContract]
TestObject Load();
}
[DataContract]
public class TestObject
{
[DataMember]
public Collection<object> Properties = new Collection<object>();
}
[服务合同]
公共接口IService1
{
[经营合同]
testobjectload();
}
[数据合同]
公共类测试对象
{
[数据成员]
公共集合属性=新集合();
}
在我将另一个集合添加为集合中的项目之前,它工作正常(由“坏行”注释指示)
公共类服务1:IService1
{
公共测试对象加载()
{
var obj=新的TestObject();
//坏线
添加(新集合());
返回obj;
}
}
我得到了一个例外:
System.ServiceModel.CommunicationException:远程服务器返回错误:NotFound
如果我删除TestObject类并只返回一个集合,那么将另一个集合添加到该集合中就足够好了:
[ServiceContract]
public interface IService1
{
[OperationContract]
Collection<object> Load();
}
public class Service1 : IService1
{
public Collection<object> Load()
{
Collection<object> coll = new Collection<object>();
coll.Add(DateTime.Now);
coll.Add(new Collection<object>() { DateTime.Now, new Collection<object>() });
coll.Add("sdf");
coll.Add(99);
return coll;
}
}
[服务合同]
公共接口IService1
{
[经营合同]
收集负载();
}
公共类服务1:IService1
{
公众收集量()
{
Collection coll=新集合();
coll.Add(DateTime.Now);
coll.Add(new Collection(){DateTime.Now,new Collection()});
coll.Add(“sdf”);
coll.Add(99);
返回coll;
}
}
我尝试用列表或ArrayList替换集合。我已尝试从集合创建自己的派生类。我尝试过使用DataContract、KnownType、ServiceKnownType和CollectionDataContract属性的组合,但我要么使用错误,要么遇到了另一个问题
那么,在第一个示例中,有没有方法通过应用属性或使用派生类将集合添加到我的集合中?或者有什么方法可以做到这一点吗?第一个示例的问题是
集合
相当于object[]——一个任意值的数组。您需要告诉WCF集合可以包含哪些类型的值(通过在数据协定上使用[KnownTypeAttribute],或在服务协定上使用[ServiceKnownTypeAttribute]),即使此类值是集合
。当我在数据合同上添加[KnownType(Collection)]时,下面的代码起作用
public class StackOverflow_5189844_751090
{
[ServiceContract]
public interface IService1
{
[OperationContract]
TestObject Load();
}
[DataContract]
[KnownType(typeof(Collection<object>))]
public class TestObject
{
[DataMember]
public Collection<object> Properties = new Collection<object>();
}
public class Service1 : IService1
{
public TestObject Load()
{
var obj = new TestObject();
// bad line
obj.Properties.Add(new Collection<object>());
return obj;
}
}
static Binding GetBinding()
{
BasicHttpBinding result = new BasicHttpBinding();
//Change binding settings here
return result;
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service1), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IService1), GetBinding(), "");
host.Open();
Console.WriteLine("Host opened");
var factory = new ChannelFactory<IService1>(GetBinding(), new EndpointAddress(baseAddress));
var proxy = factory.CreateChannel();
Console.WriteLine(proxy.Load());
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
公共类堆栈溢出\u 5189844\u 751090
{
[服务合同]
公共接口IService1
{
[经营合同]
testobjectload();
}
[数据合同]
[知识类型(类型(集合))]
公共类测试对象
{
[数据成员]
公共集合属性=新集合();
}
公共类服务1:IService1
{
公共测试对象加载()
{
var obj=新的TestObject();
//坏线
添加(新集合());
返回obj;
}
}
静态绑定GetBinding()
{
BasicHttpBinding结果=新的BasicHttpBinding();
//在此处更改绑定设置
返回结果;
}
公共静态无效测试()
{
string baseAddress=“http://“+Environment.MachineName+”:8000/服务”;
ServiceHost主机=新ServiceHost(类型为(Service1),新Uri(基地址));
AddServiceEndpoint(typeof(IService1),GetBinding(),“”);
host.Open();
Console.WriteLine(“主机已打开”);
var factory=newchannelfactory(GetBinding(),newendpointaddress(baseAddress));
var proxy=factory.CreateChannel();
Console.WriteLine(proxy.Load());
((IClientChannel)代理).Close();
工厂关闭();
控制台。写入(“按ENTER键关闭主机”);
Console.ReadLine();
host.Close();
}
}
在第二种情况下,由于集合是操作契约的一部分,因此它被视为该操作的已知类型的一部分,因此不需要显式添加。原语类型(字符串、数字、日期时间)也不需要显式声明,它们已经被WCF“知道”了。记不起我以前到底做了什么;刚从集合中创建了一个派生类,并在派生类上添加了“Serializable”属性,不确定是否包含成员,但可能也需要。
public class StackOverflow_5189844_751090
{
[ServiceContract]
public interface IService1
{
[OperationContract]
TestObject Load();
}
[DataContract]
[KnownType(typeof(Collection<object>))]
public class TestObject
{
[DataMember]
public Collection<object> Properties = new Collection<object>();
}
public class Service1 : IService1
{
public TestObject Load()
{
var obj = new TestObject();
// bad line
obj.Properties.Add(new Collection<object>());
return obj;
}
}
static Binding GetBinding()
{
BasicHttpBinding result = new BasicHttpBinding();
//Change binding settings here
return result;
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service1), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IService1), GetBinding(), "");
host.Open();
Console.WriteLine("Host opened");
var factory = new ChannelFactory<IService1>(GetBinding(), new EndpointAddress(baseAddress));
var proxy = factory.CreateChannel();
Console.WriteLine(proxy.Load());
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}