ServiceKnownType客户端问题

时间:2015-06-13 18:44:52

标签: c# wcf serviceknowntype

服务器端:

服务详情:

[ServiceKnownType("GetKnownTypes", typeof(Helper))]
[ServiceContract]
public interface IAppConfigurationManager
{
    [OperationContract]
    object ChangeObjectProperty(object myCustomObject);
}

实现:

public class AppConfigurationManager : IAppConfigurationManager
{
    public object ChangeObjectProperty(object myCustomObject)
    {
        foreach (Type type in Globals.MyCustomTypes)
        {
            if (type == myCustomObject.GetType())
            {
                foreach (PropertyInfo Property in myCustomObject.GetType().GetProperties())
                {
                    if(Property.Name == "ID")
                    {
                        int oldValue = Convert.ToInt32(Property.GetValue(myCustomObject));
                        Property.SetValue(myCustomObject, oldValue + 1);
                        break;
                    };
                };                    
            }
        }

        return myCustomObject;
    }
}

Helper类用于收集KnownTypes:

public static class Helper
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
    {
        Globals.MyCustomTypes = new List<Type>();

        System.Collections.Generic.List<System.Type> knownTypes =
            new System.Collections.Generic.List<System.Type>();

        Assembly assembly = Assembly.LoadFrom(@"D:\WCF\RuntimeManagement\bin\Debug\RuntimeManagement.dll");

        foreach (Type type in assembly.GetTypes())
        {
            if (type.Name.Contains("Customer") || type.Name.Contains("Account"))
            {
                knownTypes.Add(type);
                Globals.MyCustomTypes.Add(type);
            };
        };

        return knownTypes;
    }
}

类:

[DataContract]
public class Customer 
{
    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string Name { get; set; }
}

[DataContract]
public class Account
{
    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public Customer AccountOwner { get; set; }
}

客户方:

在调用服务之前,尝试在客户端注册KnownTypes:

private void fmMain_Load(object sender, EventArgs e)
{
    MyCustomTypes = new List<Type>();

    Assembly assembly = Assembly.LoadFrom(@"D:\WCF\RuntimeManagement\bin\Debug\RuntimeManagement.dll");

    foreach (Type type in assembly.GetTypes())
    {
        if (type.Name.Contains("Customer") || type.Name.Contains("Account"))
        {
            MyCustomTypes.Add(type);

            if (type.Name == "Customer")
            {
                CustomerType = type;
            };

            foreach (var operation in Globals.AppConfigMgrClient.Endpoint.Contract.Operations)
            {
                operation.KnownTypes.Add(type);
            };
        };
    };

    object myCustomerObject = Activator.CreateInstance(CustomerType);

    foreach (PropertyInfo Property in myCustomerObject.GetType().GetProperties())
    {
        if (Property.Name == "ID")
        {
            Property.SetValue(myCustomerObject, 111);
            break;
        };
    };

    myCustomerObject = Globals.AppConfigMgrClient.ChangeObjectProperty(myCustomerObject);

    foreach (PropertyInfo Property in myCustomerObject.GetType().GetProperties())
    {
        if (Property.Name == "ID")
        {
            Debug.WriteLine(Property.GetValue(myCustomerObject).ToString());
            break;
        };
    };
}

这里收到错误:

myCustomerObject = Globals.AppConfigMgrClient.ChangeObjectProperty((RuntimeManagement.CatalogManagement.Customer)myCustomerObject);
  

格式化程序在尝试反序列化时抛出异常   消息:尝试反序列化参数时出错   http://tempuri.org/:myCustomObject。 InnerException消息是   'Element'http://tempuri.org/:myCustomObject'包含来自a的数据   映射到名称“http://tempuri.org/:Customer”的类型。该   反序列化器不知道映射到此名称的任何类型。   考虑使用DataContractResolver或添加对应的类型   '客户'到已知类型列表 - 例如,通过使用   KnownTypeAttribute属性或通过将其添加到已知列表中   传递给DataContractSerializer的类型。'。请参阅InnerException   了解更多详情。

可能是很长的帖子,希望你知道我在这里想做什么:

  1. 在服务器端助手类中将CustomerAccount类添加到ServiceKnownType
  2. 在客户端加载事件时,尝试从KnownTypesCustomer存在的同一程序集中注册Account
  3. 然后创建Customer类型的实例,将其ID属性设置为111,发送OperationContract名为ChangeObjectProperty。成功执行后,它应该增加ID。
  4. 感谢您的时间。

0 个答案:

没有答案