为什么XmlInclude在我的项目中不起作用?

时间:2019-09-22 08:18:57

标签: c# asp.net-core .net-core

我重写序列化以删除XML的所有属性前缀:

这是startup.cs:

services.AddMvc(options =>
            {
                options.OutputFormatters.Add(new Classes.XmlSerializerOutputFormatterNamespace());
            })

这是覆盖序列化的代码:

public class XmlSerializerOutputFormatterNamespace : XmlSerializerOutputFormatter

{
    protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
    {
        //applying "empty" namespace will produce no namespaces
        var emptyNamespaces = new XmlSerializerNamespaces();
        emptyNamespaces.Add("", "any-non-empty-string");
        xmlSerializer.Serialize(xmlWriter, value, emptyNamespaces);
    }
}

这是控制器的代码:

[HttpPost]
[Produces("application/xml")]
public async Task<BaseMsg> mp([FromBody]TextMsg XmlData)
{
    TextMsg ReturnXmlData = new TextMsg() { ToUserName = XmlData.FromUserName, FromUserName = XmlData.ToUserName ,CreateTime= XmlData.CreateTime, MsgType= "text", Content ="你好呀"};
    return ReturnXmlData;
}
[XmlInclude(typeof(BaseMsg))]
[XmlRoot("xml")]
public class BaseMsg {
    public string ToUserName { get; set; }
    public string FromUserName { get; set; }
    public string CreateTime { get; set; }
    public string MsgType { get; set; }
    public string MsgId { get; set; }
}
[XmlInclude(typeof(TextMsg))]
[XmlRoot("xml")]
public class TextMsg:BaseMsg {

    public string Content { get; set; }
}

运行程序并发送帖子后,Visual Studio在覆盖序列化中报告错误:

System.InvalidOperationException: 'There was an error generating the XML document.'

InvalidOperationException: The type Demo.Controllers.CallbackController+TextMsg was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

似乎报告了此错误,因为我没有使用XmlInclude。但是,如您所见,我还添加了它,为什么我还没有工作?

我发现,如果我不继承BaseMsg类,则它可以正常工作而没有任何错误。

你能帮我吗?谢谢。

2 个答案:

答案 0 :(得分:2)

尝试将基本消息的属性更改为此:

[XmlInclude(typeof(TextMsg))]

并从短信中删除[XmlInclude(typeof(TextMsg))]属性

答案 1 :(得分:1)

要解决该异常,请参见this answer。虽然我不知道如何在序列化期间删除其他属性,但我可以建议您采用一种简单(但效率不高)的解决方法

public class XmlSerializerOutputFormatterNamespace : XmlSerializerOutputFormatter
{
    protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
    {
        var memoryStream = new MemoryStream();
        xmlSerializer.Serialize(memoryStream, value);
        memoryStream.Seek(0, SeekOrigin.Begin);

        //requires using System.Xml.Linq;
        XDocument document = XDocument.Load(memoryStream);
        document.Root.RemoveAttributes();
        document.WriteTo(xmlWriter);
    }
}