我已搜索过两者(谷歌和此处的SO),问题在于大多数问题确实与序列化使用属性(XML属性或DataContract)有关,而不是自定义属性的实际序列化。请参阅下面的几个相似的问题
我们正处于某个项目的计划阶段。
其中一项要求促使我们在可能的情况下提出问题,并建议序列化(针对WCF)自定义属性。
如果是这样,我们是否还需要KnownType属性来装饰服务合同?
例如,我们有自定义属性,在我们的DTO对象中使用:
[DataContract] // <- is this allowed/adviseable
[AttributeUsage(AttributeTargets.Property)]
public class DtoPropertyAttribute : Attribute
{
[DataMember] // <- this too
public int MaximumLength { get; set; }
public DtoPropertyAttribute(int maximumLength)
{
this.MaximumLength = maximumLength;
}
}
在某些时候我们会使用......
Object[] GetCustomAttributes(bool inherit);
...来自命名空间:
System.Reflection.MemberInfo
...如下(WCF服务端):
//property is of type System.Reflection.ProperInfo
var attributes property.GetCustomAttributes(false);
然后我们检查属性是否具有属性
//..
//some logic here that iterates/gets a single attribute 'attribute'
//...
if(attribute is DtoPropertyAttribute
{
//do stuff
}
我们注意到属性是可序列化的:
namespace System {
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System {
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Diagnostics.Contracts;
using System.Security;
using System.Security.Permissions;
[Serializable] //<--- See me please!!
[AttributeUsageAttribute(AttributeTargets.All, Inherited = true, AllowMultiple=false)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Attribute))]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class Attribute : _Attribute
{
//...
}
脚注:类似的问题没有回答我的问题:
答案 0 :(得分:2)
写了一个小概念证明,并且可以愉快地得出结论:属性(和它们的值)可以被序列化而没有问题!
答案是可以的!自定义属性上的 DataContract 和 DataMember 装饰就足够了。无需 KnownType 或 ServiceKnownType 装饰。
我们将使用它,并希望这样做没有陷阱。
接口,DataContract和属性:
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace ServiceTest
{
[ServiceContract]
public interface IService
{
[OperationContract]
string TestMethod(ServiceDto dto);
}
[DataContract]
public class ServiceDto
{
[DataMember]
[DtoProperty(10)]
public string DtoField { get; set; }
}
[DataContract]
[AttributeUsage(AttributeTargets.Property)]
public class DtoPropertyAttribute : Attribute
{
[DataMember]
public int MaximumLength { get; set; }
public DtoPropertyAttribute(int maximumLength)
{
MaximumLength = maximumLength;
}
}
}
服务实施:
using System;
namespace ServiceTest
{
public class Service : IService
{
public string TestMethod(ServiceDto dto)
{
if (dto == null)
throw new ArgumentNullException("dto");
var properties = typeof(ServiceDto).GetProperties();
foreach (var property in properties)
{
var attributes = property.GetCustomAttributes(true);
foreach (var attribute in attributes)
{
var dtoPropAtt = attribute as DtoPropertyAttribute;
if (dtoPropAtt != null)
{
return string.Format("Maximum Length is: '{0}'!" ,dtoPropAtt.MaximumLength);
}
}
}
return "Attribute Serialization Test Failed";
}
}
}
测试控制台应用程序,其服务引用指向Web服务主机(AttributeWcfTest)
using System;
using AttributeWcfTest.ServiceRef;
namespace AttributeWcfTest
{
class Program
{
static void Main(string[] args)
{
var client = new ServiceRef.ServiceClient();
var testDto = new ServiceDto()
{
DtoField = "Test Value"
};
var response = client.TestMethod(testDto);
Console.WriteLine(response);
Console.ReadLine();
}
}
}
<强>输出强>