WCF 包装 REST 的变量复杂类型

发布于 2024-09-08 07:28:59 字数 1250 浏览 1 评论 0原文

我正在实现一个 lo-REST API 并希望返回 XML 或 JSON。在 .NET WCF 中构建它。

我喜欢 Flickr 和 Last FM API 的设计,它们将变量复杂类型包装在一个简单的响应 ala:

<lfm status="ok">
  <user>
    <name>RJ</name>
    <realname>Richard Jones </realname>
    <country>UK</country>
    <age>27</age>
  </user>
</lfm>

or

<lfm status="ok">
  <track>
    <name>Best track ever</name>
    <album>Thriller</album>
  </user>
</lfm>

or 中,或者

<lfm status="fail">
  ... error details
</lfm>

复杂类型的序列化很简单,正如您所期望的那样(使用 DataContract、DataMember 等)。但是将其包装在某种自定义响应中让我感到困惑,因为其中可能包含可变的复杂类型。为响应提供由复杂类型填充的类型对象的成员不会序列化:

[DataContract]
public class Response
{
    public enum ResponseStatus
    {
        ok,
        fail
    }

    [DataMember]
    public ResponseStatus Status { get; set; }

    [DataMember]
    public object Data { get; set; }

}

非常感谢任何想法或帮助。

非常感谢, 亚历克斯

编辑: 蒂姆·罗伯茨(Tim Roberts)提供了一个有趣的解决方案,尽管它的序列化效果不佳。一个选项是将所有潜在的复杂类型作为指定 [DataMember(EmitDefaultValue = false)] 的属性,这样 null 就不会序列化。但不确定这是最好的解决方案。

I'm implementing a lo-REST API and looking to return either XML or JSON. Building it in .NET WCF.

I like the design of both Flickr and Last FM APIs which wrap their variable complex types in a simple response ala:

<lfm status="ok">
  <user>
    <name>RJ</name>
    <realname>Richard Jones </realname>
    <country>UK</country>
    <age>27</age>
  </user>
</lfm>

or

<lfm status="ok">
  <track>
    <name>Best track ever</name>
    <album>Thriller</album>
  </user>
</lfm>

or

<lfm status="fail">
  ... error details
</lfm>

Serialization of the complex types is simple as you'd expect (using DataContract, DataMember etc). But wrapping it in some kind of custom response is tripping me up because of the variable complex types that may be contained inside. Giving the response a member of type object which is filled by the complex type does not serialize:

[DataContract]
public class Response
{
    public enum ResponseStatus
    {
        ok,
        fail
    }

    [DataMember]
    public ResponseStatus Status { get; set; }

    [DataMember]
    public object Data { get; set; }

}

Any ideas or help is greatly appreciated.

Many thanks,
Alex

EDIT:
Tim Roberts provides an interesting solution although it doesn't serialise nicely. An option is to have all potential complex types as properties with [DataMember(EmitDefaultValue = false)] specified so nulls do not serialise. Not sure this is the best solution though.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽容 2024-09-15 07:28:59

您可以为 Response 中的 Data 类型定义类层次结构:

例如,

[DataContract]
public abstract class Data
{ }

[DataContract]
public class FooData : Data
{ }

[DataContract]
public class BarData : Data
{ }

然后在 Response 类上指示已知类型:

[DataContract]
[KnownType(typeof(FooData))]
[KnownType(typeof(BarData))]
public class Response
{
    public enum ResponseStatus
    {
        ok,
        fail
    }

    [DataMember]
    public ResponseStatus Status { get; set; }

    [DataMember]
    public Data Data { get; set; }
}

You could define a class hierarchy for your Data types within Response:

e.g.,

[DataContract]
public abstract class Data
{ }

[DataContract]
public class FooData : Data
{ }

[DataContract]
public class BarData : Data
{ }

then indicate the known-types on the Response class:

[DataContract]
[KnownType(typeof(FooData))]
[KnownType(typeof(BarData))]
public class Response
{
    public enum ResponseStatus
    {
        ok,
        fail
    }

    [DataMember]
    public ResponseStatus Status { get; set; }

    [DataMember]
    public Data Data { get; set; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文