如何在 XML 序列化运行时更改 XML 元素的名称(ASP.Net WebApi)

How to change the name of an XML element during XML Serialization runtime (ASP.Net WebApi)

我正在构建对 WebAPI 服务调用的响应。默认的 XML Serializer 主要为我工作。我需要生成的是这样的:

<fooCollection>
  <fooMember>
    <fooType1>
      ...bunch of properties for the fooMember
    </fooType1>
  </fooMember>
  <fooMember>
    <fooType2>
      ...bunch of properties for the fooMember
    </fooType2>
  </fooMember>
</fooCollection

我遇到的问题是 <fooType> 元素当前是我模型中名为 fooType 的一个对象。响应中的元素名称需要具有不同的名称,具体取决于我的 fooMember 对象的类型 属性。这意味着使用 [DataContract][DataMember] 属性来给它一个对象名称以外的名称似乎不起作用,因为它们只设置一次,我找不到如何在运行时更改它.

我的模型代码如下所示:

  public partial class fooCollection {
    private fooCollectionMember[] memberField;

    [System.Xml.Serialization.XmlElementAttribute("fooMember")]
    public fooCollectionMember[] member { get; set;}
  }

  public partial class fooCollectionMember {
    private fooType fooTypeField;
    public fooType fooType { get; set }
  }

  public partial class fooType {
    private object fooProperty;
    // ... more properties
    public object fooProperty { get; set; }
    // ... more properties
  }

在 runtime/serialization 期间有没有办法设置我的元素名称将用于 <fooType> 元素?

或者,有没有一种方法可以重新排列我的模型,使 fooType 不是一个包含其余属性的对象,而是 [=17] 的 属性 =] 对象以及所有其他属性,但是当序列化时 <fooType> 元素被命名为 属性 的值并将其余属性封装在其中?

我原来的服务调用get方法是这样的:

    public FooCollection Get () {
      FooCollection foos = new FooCollection();
      // code to fill model
      return foos;
    }

我没有发现任何允许我在基于 属性 或 FooCollection 中的对象的响应中获取 XML 元素并在 XML 中更改该元素的名称的方法基于 property/object 值的响应。即我不能有 FooProperty 属性 其在 XML 响应中生成的元素对于每个集合项具有不同的元素名称。换句话说,如果我使用 return-a-model-object-and-let-the-serialization-happen,这个 属性 在整个 XML 文档中只能有一个元素名称- 自动接近。但是,我找到了一种解决方法,允许我更改元素名称,但我认为合适。

而不是让我的 Get() 服务方法 return 成为 FooCollection 类型的对象并在 return 之后自动序列化,而是 return正在处理一个 HttpResponseMessage 对象。这样我就可以手动序列化我的模型,随心所欲地操作它,然后 return 它作为 HttpResponseMessage.

所以现在我的获取服务方法可以更像这样来实现我的目标:

public HttpResponseMessage Get () {
  XmlSerializer xmlSerializer = new XmlSerializer(typeof(FooCollection));
  System.IO.StringWriter stringWriter = new System.IO.StringWriter();
  XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
  FooCollection foos = new FooCollection();
  // code to populate FooCollection model, assign namespaces, etc
  xmlSerializer.Serialize(stringWriter, foos, namespaces);
  // Now we can manipulate stringWriter value however is needed to replace the element names
  return new HttpResponseMessage() {
    Content = new StringContent(stringWriter.ToString(), Encoding.UTF8, "application/xml")
  };
}