我有一个ASP.NET Web应用程序需要以JSON,XML和ProtoBuf的形式接受请求。为了让ProtoBuf工作,我需要使用[ProtoContract]注释DTO,但是一旦我这样做,XML就会停止工作。
我可以将问题与[ProtoContract]非常相似。我做了这个小测试应用程序:
class Program
{
static void Main(string[] args)
{
var ser = new XmlMediaTypeFormatter();
ser.UseXmlSerializer = true;
Console.WriteLine($"With ProtoContract: {ser.CanReadType(typeof(Foo))}");
Console.WriteLine($"Without ProtoContract: {ser.CanReadType(typeof(Foo1))}");
}
}
[ProtoContract]
public class Foo
{
[ProtoMember(0)]
public string Bar { get; set; }
}
public class Foo1
{
public string Bar1 { get; set; }
}
输出结果为:
With ProtoContract: False
Without ProtoContract: True
观察非常清楚,只要添加属性,XmlSerializer就不能再读取对象了。有人遇到过类似的行为吗?关于如何解决这个问题的任何想法?
答案 0 :(得分:0)
这很有意思 - 我不知道它是怎么做的,但今天晚上我会看着反射器!
但是,在这种情况下修复很简单:
[ProtoMember(1)]
public string Bar { get; set; }
奇怪的是,我知道检查这一点的原因是0
永远不是protobuf中的合法标签,但我非常感兴趣XmlMediaTypeFormatter
关心。
更新:原因是因为XmlSerializer
如何访问对象上的属性,但吞下异常意味着“不能,不能这样做”。它成为你实际问题的牺牲品;尝试:
new XmlSerializer(typeof(Foo));
您应该看到:
Unhandled Exception: System.InvalidOperationException: There was an error reflecting type 'Foo'. ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: tag
at ProtoBuf.ProtoMemberAttribute..ctor(Int32 tag) in c:\Dev\protobuf-net\protobuf-net\ProtoMemberAttribute.cs:line 47
at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.CreateCaObject(RuntimeModule module, IRuntimeMethodInfo ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
等等,只是ProtoMembmerAttribute
抱怨非法标记。