建立json响应

时间:2015-10-14 21:06:52

标签: c# json wcf rest self-hosting

我正在开发一个自托管的rest api,用于监控多个服务器的状态。

我的任务是,当一切正常时,我应该只返回

{"response":"ok"}

但是,当查询的服务器或服务器出现错误时,我必须返回

{  "response" :  [ {"agent":"<server>:<port>","port":"<port>" ,"Error":"<Description of the error>"} ]  }

我正在考虑构建一个帮助器类来在这个模式上构建对象并将它们返回到其余的api

public class HelperErrorResponseClass
{
    public string agent { get; set; }
    public string port { get; set; }
    public string Error { get; set; }
}

这没问题,问题是,当一切都好的时候如何处理。我有这个Api响应助手类

public class Response
{
    public string response { get; set; }
}

但我发现我需要将响应属性更改为List<HelperErrorResponseClass>才能发送错误响应。你是否认为,如果我用Json.Net将List<HelperErrorResponseClass>对象字符串化,它将以所需的格式返回?

编辑:忘记添加,我使用Web Api构建其余服务。

UDPATE

经过进一步的研究,我找到了解决问题的方法。

this post之后,我能够重写像这样的辅助类

[DataContract]
[KnownType(typeof(List<HelperErrorResponseClass>))]
public class Response
{
    [DataMember]
    public object response { get; set; }
}

[DataContract]
public class HelperErrorResponseClass
{
    [DataMember(EmitDefaultValue = false)]
    public string agent { get; set; }
    [DataMember(EmitDefaultValue = false)]
    public string port { get; set; }
    [DataMember(EmitDefaultValue = false)]
    public string error { get; set; }
}

这项工作是为了满足我和我的客户需求......除了一件小事。当我从List获得结果,并且假设我添加了KnownTypes指令时,我的回复就是这个

{"response":[{"__type":"HelperErrorResponseClass:#AppCommonLib","Error":"ERROR","InstanceId":"<InstanceId> : <Port>","PortType":"<PortType>"},{"__type":"HelperErrorResponseClass:#AppCommonLib","Error":"ERROR","InstanceId":"<InstanceId> : <Port>","PortType":"<PortType>"}]}

知道如何摆脱响应的__type属性吗?使得必须显式只返回助手类的声明属性?

3 个答案:

答案 0 :(得分:1)

处理此问题的最简单方法是将处理函数的返回类型设置为字符串,然后可以检查错误并执行类似的操作;

//pseudo code to give an idea
if (errorsList.Count() > 0)
{
     return JsonConvert.SerializeObject(errorsList);
}
else
{
     return JsonConvert.SerializeObject(new Response("ok"));
}

现在有人说......除非提供要求的人员根本不灵活,否则你应该重做设计。如何返回错误数组和调用API的人可以推断,如果它的长度为0,那么一切正常。看起来很直接,对吧?您也可以将所有属性放在一个对象上,这些字段只会返回null或空字符串。或者,如果没有值,您可以更改序列化设置以排除它们。

答案 1 :(得分:1)

保持简单并使用匿名类型。

if (condition) 
{
    return JsonConvert.SerializeObject(new { response = new { agent = "x", port = "y", error = "z" }});
}
else 
{
   return JsonConvert.SerializeObject(new { response = "ok"});  
}

更多信息:

https://msdn.microsoft.com/en-us/library/bb397696.aspx

答案 2 :(得分:1)

我个人认为您不需要Response课程,特别是它属于object类型。恕我直言,你已经过分复杂了你所拥有的非常简单的问题。它不仅是__type,还有HelperErrorResponseClass:#AppCommonLib之类的其他信息,不应该存在。

您遇到的另一个问题是HelperErrorResponseClass类的名称不正确。这不是帮助类。它是一个标准的数据对象类。

  

辅助类是一个用静态方法填充的类。它通常用于隔离“有用”算法。

我就是这样做的:

  1. 我摆脱了Response班。
  2. 我会使用您原来简单的HelperErrorResponseClass课程,但会将其重命名为更有意义的内容,例如ErrorDetails
  3. 我会回复这样的回复:
  4. if (errorsList.Count() > 0) {
        return JsonConvert.SerializeObject(new { response = errorsList});
    }
    else {
       return JsonConvert.SerializeObject(new { response = "ok"});
    }
    

    但是,如果您真的想坚持使用更新的解决方案,那么摆脱__type的简单方法就是将其从最终的序列化字符串中删除:

    if (errorsList.Count() > 0) {
        string r = JsonConvert.SerializeObject(new { response = errorsList});
        return r.Replace("__type", "");
    }
    else {
       return JsonConvert.SerializeObject(new { response = "ok"});
    }