服务器端:
服务详情:
[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。
可能是很长的帖子,希望你知道我在这里想要做什么:
- 在服务器端助手类中添加
Customer
和Account
类。ServiceKnownType
- 在客户端的加载事件中,尝试
KnownTypes
从存在的同一个程序集中注册。Customer
Account
- 然后创建
Customer
类型的实例,将其ID
属性设置为 111,将其发送OperationContract
为ChangeObjectProperty
. 成功执行后,它应该增加 ID。
谢谢你的时间。