1

服务器端:

服务详情:

[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 消息是“元素” http://tempuri.org/:myCustomObject包含来自映射到名称“ http://tempuri.org/:Customer ”的类型的数据。反序列化器不知道映射到此名称的任何类型。考虑使用 DataContractResolver 或将与“客户”对应​​的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。有关更多详细信息,请参阅 InnerException。

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

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

谢谢你的时间。

4

0 回答 0