简体   繁体   English

HttpResponseMessage 序列化为 xml

[英]HttpResponseMessage serialize to xml

In our application we're having a REST-Api with several controllers like UsersController or UserGroupsController and many more.在我们的应用程序中,我们有一个带有多个控制器的 REST-Api,如UsersControllerUserGroupsController等等。 All calls (get, put, push, delete) on every REST-Endpoint always return a HttpResponseMessage which is always an object of the following type:每个 REST-Endpoint 上的所有调用(get、put、push、delete)始终返回一个HttpResponseMessage ,它始终是以下类型的对象:

public class ComRestResult<T> where T : class
{
   public T Data { get; set; }

   public ValidationItem[] ValidationItems { get; set; }
}

And the ValidationItem -class looks like: ValidationItem -class 看起来像:

[DataContract]
[Serializable]
public class ValidationItem
{
   [DataMember]
   public string[] ErrorParameters { get; set; }

   [DataMember]
   public ValidationSeverity Severity { get; set; }

   private ValidationId validationId;

   [IgnoreDataMember]
   [XmlIgnore]
   public ValidationId ValidationId
   {
      get { return validationId; }
      set
      {
         validationId = value;
         if(validationId != ValidationId.UnresolvedError)
         {
            legacyValidationId = validationId.ToString();
         }
      }
   }

   private string legacyValidationId;

   [DataMember(Name = "ValidationId")]
   [XmlElement("ValidationId")]
   public string LegacyValidationId
   {
      get { return legacyValidationId; }
      set
      {
         legacyValidationId = value;
         validationId = ValidationId.UnresolvedError;
         ValidationId parsedValidationId;
         if(!string.IsNullOrEmpty(legacyValidationId) && Enum.TryParse(legacyValidationId, out parsedValidationId))
         {
            validationId = parsedValidationId;
         }
      }

ValidationId and Severity are enums. ValidationIdSeverity是枚举。

The Get-Method of the UsersController for example looks like:例如,UsersController 的 Get-Method 如下所示:

[HttpGet]
[Route("")] 
public HttpResponseMessage Get()
{
    RequestHandler handler = new RequestHandler(Request);
    HttpResponseMessage responseMessage = handler.ProcessRequest<User[]>(PersonsAccess.GetAllPersons);
    return responseMessage;
}

The RequestHandler builds the needed HttpResponseMessage and takes a Func<object, T> in it's ProcessRequest-Method. RequestHandler 构建所需的HttpResponseMessage并在其 ProcessRequest-Method 中采用Func<object, T>

The HttpResponseMessage is created inside the ProcessRequest-Method with the following line: HttpResponseMessage是在 ProcessRequest-Method 中使用以下行创建的:

HttpResponseMessage httpResponseMessage = request.CreateResponse(httpStatusCode, restResult);

Everything just works fine.一切正常。

If I look at the response in json it looks like:如果我查看 json 中的响应,它看起来像:

{"ValidationItems":[{"ValidationId":"UserIsNew","ErrorParameters":["foo","bar"],"Severity":0,}],"Data":[{"UserId":"ABC123","UserName":"John Smith","IsNew":true},{"UserId":"XYZ789","UserName":"Raimond Test","IsNew":true}]}

This just looks good.这看起来不错。 Now if I look at the response as xml it looks like:现在,如果我将响应视为 xml,它看起来像:

<ComRestResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Data xmlns:d2p1="http://schemas.datacontract.org/2004/07/Comp.Rest.Data.Persons">
    <d2p1:User>
      <d2p1:UserId>ABC123</d2p1:UserId>
      <d2p1:UserName>John Smith</d2p1:UserName>
      <d2p1:IsNew>true</d2p1:IsNew>
    </d2p1:User>
    <d2p1:User>
      <d2p1:UserId>XYZ789</d2p1:UserId>
      <d2p1:UserName>Raimond Test</d2p1:UserName>
      <d2p1:IsNew>true</d2p1:IsNew>
    </d2p1:User>
  </Data>
  <ValidationItems xmlns:d2p1="http://schemas.datacontract.org/2004/07/Comp.BaseInterface.Validation">
    <d2p1:ValidationItem>
      <d2p1:ValidationId>UserIsNew</d2p1:ValidationId>
      <d2p1:ErrorParameters xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <d4p1:string>foo</d4p1:string>
        <d4p1:string>bar</d4p1:string>
      </d2p1:ErrorParameters>
      <d2p1:Severity>Information</d2p1:Severity>
    </d2p1:ValidationItem>
  </ValidationItems>
</ComRestResult>

And this looks not good.这看起来不太好。 Although all informations are present we have a problem with the xml-namespaces.尽管所有信息都存在,但我们对 xml 命名空间有问题。 The d2p1 and all the others. d2p1和所有其他的。

If I apply the [DataContract] and [DataMember] attributes at the User -class like:如果我在User类中应用[DataContract][DataMember]属性,例如:

[DataContract(Name = "User", Namespace = "")]
public class User
{
    [DataMember(Name = "UserId")]
    public string UserId { get; set; }
    [DataMember(Name = "UserName")]
    public string UserName { get; set; }
    [DataMember(Name = "IsNew")]
    public bool IsNew { get; set; }
}

the response-xml for the user looks like:用户的 response-xml 如下所示:

<Data>
 <User>
  <IsNew>true</IsNew>
  <UserId>ABC123</UserId>
  <UserName>John Smith</UserName>
 </User>
 <User>
  <IsNew>true</IsNew>
  <UserId>XYZ789</UserId>
  <UserName>Raimond Test</UserName>
 </User>
</Data>

That is what we need.这就是我们所需要的。 But do we really need to apply the attributes on every class, or is there a possibility to deactivate (or so) the namespace at the serialization generally?但是我们真的需要在每个类上应用属性,还是有可能在序列化时停用(或这样)命名空间?

Another problem is the string[] in the ValidationItem -class.另一个问题是ValidationItem类中的string[] At the moment this is serialized as:目前这被序列化为:

<d2p1:ErrorParameters xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <d4p1:string>foo</d4p1:string>
    <d4p1:string>bar</d4p1:string>
</d2p1:ErrorParameters>

I know I can replace the string[] with the following class:我知道我可以用以下类替换string[]

[CollectionDataContract(ItemName = "value", Namespace = "")]
public class StringArray : List<string>
{
}

But unfortunately this class is very old, is very often used (~4000 references) and is also used for SOAP-Serialization.但不幸的是,这个类非常古老,经常使用(~4000 个引用)并且也用于 SOAP 序列化。 So we can not easily change it.所以我们不能轻易改变它。

There we also need something like a generic serialization to xml without the namespaces.在那里我们还需要像没有命名空间的 xml 的通用序列化。

I solved it by myself.我自己解决了。

According to the following article it's possible to use the XmlSerializer instead of the DataContractSerializer .根据以下文章,可以使用XmlSerializer而不是DataContractSerializer This just works fine.这很好用。

https://docs.microsoft.com/de-de/aspnet/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter https://docs.microsoft.com/de-de/aspnet/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_media_type_formatter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM