2

我目前正在使用 ServiceStack 实现 API,但遇到了问题。我得到的 API 规范定义了将发送到 API 的 XML 数据包。此规格无法更改,也不受我自己的控制。

问题是在根元素中,有一个项目列表,如下所示:

<data>
    <id>0</id>
    <locationID>10</locationID>
    <cust>
       <id>0</id>
    </cust>
    <cust>
       <id>0</id>
    </cust>
    <cust>
       <id>0</id>
    </cust>
    <cust>
       <id>0</id>
    </cust>
</data>

我已经实现了规范并且几乎是正确的,但是我无法弄清楚如何在没有周围父节点的情况下让元素在 XML 中重复。

由于这是使用 ServiceStack,我正在使用 Data Contracts 并尝试将元素设置为 CollectionDataContract,但是它将元素包装在父节点中。

我想知道是否可以指定不使用父元素,或者是否可以在包含没有父节点的节点的节点中实现一个普通列表。

有任何想法吗?

4

1 回答 1

1

这对于 ServiceStack 中使用的 .NET 的 DataContract Xml 序列化程序是不可能的。如果您找到支持此功能的 XmlSerializer,您可以注册以使用它:

appHost.ContentTypeFilters.Register(ContentType.Xml, SerializeToStream, DeserializeFromStream);

或者注册一个自定义 contentType,如下所示: http ://www.servicestack.net/ServiceStack.Northwind/vcard-format.htm

就个人而言,在这种情况下,我只会返回一个序列化的 xml 字符串。您可以这样做:

  • 在 Service 的主体中,只需返回一个字符串(您可以将其包装在 HttpResult 中以强制指定特定的 ContentType)。在您的服务中返回 XML 字符串将始终为所有端点返回 XML。

  • 通过覆盖 ServiceBase 中的 OnAfterExecute 并将强类型响应 DTO 转换为用于 XML ContentType 请求的 XML 字符串。

  • 注册自定义响应过滤器(或过滤器属性

例如:

appHost.ResponseFilters.Add((req, res, dto) =>
{
    if (req.ResponseContentType == ContentType.Xml)
    {
        var sb = new StringBuilder();
        DataDto dataDto = (DataDto)dto;
        sb.AppendLine("<data>");
        sb.AppendFormat("<id>{0}</id>",dataDto.Id);
        //... etc
        res.ContentType = ContentType.Xml;
        using (var sw = new StreamWriter(res.OutputStream)) {
          sw.WriteLine(sb.ToString());
        }
        res.Close();
    }
});
于 2012-06-19T18:29:09.490 回答