【问题标题】:WCF call with Param List<T> fails when passing a List<MyType>传递 List<MyType> 时,使用 Param List<T> 调用 WCF 失败
【发布时间】:2011-12-02 06:30:27
【问题描述】:

WCF 服务接口

[ServiceContract]
public interface ITest
{
    [OperationContract]
    int TestCall(GenericType<MyType> x);

    [OperationContract]
    int TestAnotherCall(GenericType<MyOtherType> x);

}

[DataContract(Name = "GenericType")]
[KnownType(typeof(List<MyType>))]
[KnownType(typeof(List<MyOtherType>))]
public class GenericType<T>
{
    [DataMember]
    public List<T> Data
    {
        get { return data; }
        set { data = value; }
    }
}

WCF 服务实现

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Test : ITest
{
    public int TestCall(GenericType<MyType> x)
    {
        return x.Data.Count; 
    }

    public int TestAnotherCall(GenericType<MyOtherType> x)
    {
        return x.Data.Count; 
    }
}

客户

List<MyType> list = from a in ctx.Table
                    select new MyType (a.Field1, a.Field2, a.Field3).ToList(); 

GenericType gt = new GenericType();
gt.Data = list;

using(WCFClient client = new WCFClient())
{
   client.TestCall(gt);
   client.Close();
}

错误:
远程服务器返回了意外响应:(400) Bad Request。

如果我将 NULL 传递给“gt.Data”......它工作正常。

注意:

当我将鼠标放在 gt.Data ...提示显示为 MyType[]
不确定这是否符合预期。

经过一番审查,我注意到客户服务只知道
第一个 [KnownType] 声明,在我的情况下是列表。 不知道 List ....
当您在 WCF 接口上放置各种 [KnownType] 时,这是预期的吗?

【问题讨论】:

    标签: c# wcf generics


    【解决方案1】:

    你需要用KnownType() 属性来装饰你的泛型

    [DataContract(Name = "GenericType")]
    [KnownType(typeof(MyType))]
    public class GenericType<T>
    {
        [DataMember]
        public List<T> Data
        {
            get { return data; }
            set { data = value; }
        }
    }
    

    快速工作示例:

    服务

    [OperationContract]
    GenericType<MyType> GetDataUsingDataContract(GenericType<MyType> composite);
    
    public class Service1 : IService1
    {
        public GenericType<MyType> GetDataUsingDataContract(GenericType<MyType> composite)
        {
            composite.Data.First().Stuff = "Test";
            return composite;
        }
    }
    

    型号

    [DataContract(Name = "GenericType")]
    [KnownType(typeof (MyType))]
    public class GenericType<T>
    {
        [DataMember]
        public List<T> Data { get; set; }
    }
    
    public class MyType
    {
        public string Stuff { get; set; }
    }
    

    客户

    var client = new Service1Client();
    
    var genericType = new GenericType
                            {
                                Data = new[]
                                            {
                                                new MyType(),
                                            }
                            };
    var result = client.GetDataUsingDataContract(genericType);
    client.Close();
    
    Console.WriteLine(result.Data.First().Stuff);
    
    Console.ReadLine();
    

    此示例是通过添加服务引用而不是使用共享程序集生成的

    【讨论】:

    • 这是否意味着如果我有 10 种不同的类型可以通过客户端的 GenericType 使用...我将不得不声明 10 个不同的服务器类,每个类都有一个 KnownType(typeof(XXX)) ?
    • 只是确认一下,“GetKnownType”是从哪里来的?
    • 好吧,来自msdn的示例复制错误...
    • 修正了错字。是的,您需要列出 KnownType 的每种类型。这允许反序列化正常工作。
    • 2 "typeof" 一个接一个?
    【解决方案2】:

    您需要使用KnownType 属性为它可以包含的每个类赋予GenericType 属性。

    例如:

    [KnownType(typeof(List<MyType>)]
    public class GenericType<T>
    

    【讨论】:

    • @Developer:抱歉,我试图将我的 vb 语法转换为 c# 并找到 MSDN 文档链接。更新了答案
    • 抱歉,更新了答案以显示位置(就在 generictype 类上方)
    • 应用了更改...仍然是同样的问题
    • 你能试试 [KnownType(typeof(MyType)] 吗?
    【解决方案3】:

    问题可能是您在实例化它时没有在GenericType 中为T 提供类型。试试这个:

    GenericType<MyType> gt = new GenericType<MyType>();
    

    代替

    GenericType gt = new GenericType();
    

    这与实例化任何其他泛型类时的语法相同。例如,要声明一个字符串列表,(List as in List&lt;T&gt;...see here)你会说:

    List<String> myStrings = new List<String>();
    

    【讨论】:

    • 我试过了,我得到一个编译错误:非泛型类型 'MyNamespace.GenericType' 不能与类型参数一起使用
    • @Developer - 好的,现在你让我很困惑。你是说你的示例代码不诚实吗?
    • ??我的意思是,如果我应用建议的更改,我会收到以下错误。
    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多