服务器端:
服务详情:
[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 了解更多详情。
可能是很长的帖子,希望你知道我在这里想做什么:
Customer
和Account
类添加到ServiceKnownType
。KnownTypes
和Customer
存在的同一程序集中注册Account
。Customer
类型的实例,将其ID
属性设置为111,发送OperationContract
名为ChangeObjectProperty
。成功执行后,它应该增加ID。感谢您的时间。