【问题标题】:Deserialize response body from web api从 web api 反序列化响应正文
【发布时间】:2015-08-12 10:51:31
【问题描述】:

此代码是来自 api 的示例响应正文。

message_type=incoming&mobile_number=639181234567&shortcode=29290123456&request_id=5048303030534D415254303030303032393230303032303030303030303133323030303036333933393932333934303030303030313331313035303735383137&message=This+is+a+test+message&timestamp=1383609498.44

有没有办法将响应主体放置到像这样的实体的属性中? 或者类似反序列化响应正文?

public class SampleApi
{
    public string MessageId { get; set; }

    public string MessageType { get; set; }

    public string MobileNumber { get; set; }

    public string Message { get; set; }

    public string ShortCode { get; set; }

    public string ClientId { get; set; }

    public string SecretKey { get; set; }

    //Start From Reply Api

    public string RequestId { get; set; }
}   

【问题讨论】:

  • 这个奇卡是偶然的吗?如果是这样,看起来请求正文的格式是这样的,而不是响应正文(那些似乎是 JSON),如果是这样,您可能会对将自定义对象序列化为从响应反序列化它的请求正文更感兴趣...不是吗?
  • 是的,这个响应来自 Chikka Api,特别是来自 Chikka 接收 Api。我将收到此回复,然后我将使用 Eser 的代码答案对其进行反序列化。,.

标签: c# asp.net-web-api deserialization dotnet-httpclient


【解决方案1】:

你可以为它写一个自定义的反序列化器

public T Deserialize<T>(string resp) where T : new()
{
    var nameValuePairs = HttpUtility.ParseQueryString(resp);
    var obj = new T();
    var props = obj.GetType().GetProperties()
                   .ToDictionary(p => p.Name.Replace("_","") , p => p, StringComparer.InvariantCultureIgnoreCase);
    foreach(var key in nameValuePairs.AllKeys)
    {
        var newkey = key.Replace("_", "");
        if (props.ContainsKey(newkey))
            props[newkey].SetValue(obj, Convert.ChangeType(nameValuePairs[key], props[newkey].PropertyType));
    }
    return obj;
}

并用作

string response = "message_type=incoming&mobile_number=639181234567&shortcode=29290123456&request_id=5048303030534D415254303030303032393230303032303030303030303133323030303036333933393932333934303030303030313331313035303735383137&message=This+is+a+test+message&timestamp=1383609498.44";
var sampleApi = Deserialize<SampleApi>(response);

【讨论】:

  • 我为像 props[newkey].SetValue(obj, Convert.ChangeType(nameValuePairs[key], props[newkey].PropertyType), null); 这样的第三个参数添加了 null 以使其工作。无论如何再次感谢!
【解决方案2】:

这是一种自定义消息格式(不是 XML 或 JSON),因此唯一的方法是在“&”上拆分字符串,然后在“=”上拆分每个名称/值对并将其映射到您的类属性.

【讨论】:

  • 所以如果没有库可以处理这种格式,我想我会照你说的做,谢谢!
【解决方案3】:

在控制器中你可以直接使用你的类型

    ActionResult YourApiAction(SampleApi sampleApi)
    {
        var allMapped = sampleApi.MappMessage();
        ....allMapped.MessageType...
    }

但消息中的名称必须与您输入的名称相同。 message_type --> 应该是 MessageType 等等。 然后魔法直接在你的类型中序列化你的消息。

我的评论:

 class SampleApi
 {
    string message_type { get; set; }
    string MessageType { get; private set }

    SampleApi MappMessage()
    {
       MessageType = message_type;
       return this;
    }
 }

【讨论】:

  • 是的,这也是个好主意,但是调用我的 api 的其他 api 来自不同的来源,所以我不能从 message_type 更改它-->MessageType。但是,如果您有一个想法,将属性中的数据注释放置到一个类中以映射响应(类似于这个 ` [MapResponse="message_type"] public string MessageType { get; set; }`),这将是一个很好的选择想法也。
  • 重命名类 SampleApi.message_type 中的属性。或者将消息属性名称添加到类。然后编写一个方法 getMessage 在其中将消息属性映射到您的属性名称
  • 这也是一个好主意(即使在 resharper 看来它看起来并不好),我也可以将它用于其他情况。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 2018-11-23
  • 1970-01-01
相关资源
最近更新 更多