Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WCF中序列化集合要使用什么属性?_C#_Wcf - Fatal编程技术网

C# 在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<

我有一个类,它的泛型集合是我正在用WCF序列化的属性:

[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();
    }
}