【问题标题】:How to format json for post request如何为post请求格式化json
【发布时间】:2018-12-20 16:13:01
【问题描述】:

我有点不确定如何在 C# 中执行我的发布请求。我曾尝试在 Postman 中这样做,并且它在那里工作没有问题。我认为我的问题是 json 格式。我在 Newtonsoft 库中使用 JObjects 构建我的 json。当下面的代码运行时,这是输出; {"accountreference":"XX","messages":"[{\r\n \"to\": \"+XXXXX\",\r\n \"body\": \"XXXXXXXX\"\r\n}]"} 它是有效的,但正如您所见,它包含换行符和转义字符。将其发布到我正在使用的 api 后,我总是会收到 400 错误请求。

我尝试了各种序列化程序和技术,但无法使其正常工作。我还确保授权标头是正确的,如果它不正确,API 应该在其返回消息中这样说。根据 API 的开发人员的说法,只有在正文不正确时才会出现此消息。我已经尝试在 Postman 中发布带有换行符的字符串,这也产生了 400。有没有一种简单的方法可以摆脱它们?

var tmpObj = new JObject {{"to", to}, {"body", message}};

var jsonObj = new JObject
{
    {"accountreference", MessageConfiguration.Ref}, {"messages", "[" + tmpObj + "]"}
};

var json = jsonObj.ToString(Formatting.None);

var httpContent = new StringContent(json, Encoding.UTF8, "application/json");

var url = new Uri("www.xxxxxxxx/hjdhsf");
return await PostAsync(url, httpContent);


protected async Task<HttpResponseMessage> PostAsync(Uri endpoint, HttpContent content)
{
    using (var httpClient = NewHttpClient())
    {
        var result = await httpClient.PostAsync(endpoint, content);
        return result; //Statuscode is 400 here. 
    }
}

这个有效的 json 在 Postman 中工作:

{
    "accountreference":"XXXXX",
    "messages":[{
        "to":"XXXXX",
        "body":"XXX!"
    }]
}

更新:

根据回答,我试过这个:

var body = new
{
    accountreference = MessageConfiguration.Ref,
    messages = new[]
    {
        new
        {
            to = to,
            body = message
        }
    }
};

var json = new JavaScriptSerializer().Serialize(body);

现在 json 看起来是正确的,我什至可以将它从 VS 复制到邮递员中,并且它可以工作。 但是我在 VS 中的请求仍然返回 400。

【问题讨论】:

  • 那是您的确切to 和body 吗?没有像@ 这样的字符?我猜XXXXX 只是占位符数据?
  • 为什么不直接创建一个类来表示您要发布的数据,然后通过JsonConvert.SerializeObject 对其进行序列化?
  • @Liam 不,没有多余的字符。 X 只是占位符。我会尝试额外的课程。
  • 坚持你的双重编码,"[{\r\n \"to\": \"+XXXXX\",\r\n \"body\": \"XXXXXXXX\"\r\n}]" 是一个刺,而不是 json,注意开头和结尾的 "
  • 这一行 "[" + tmpObj + "]" 创建了一个 string ,其中包含您的 json。然后你 json 编码(再次)这就是问题所在。可能最好按照已建议的方式构建对象以解决此问题。

标签: c# json rest json.net


【解决方案1】:

您无需使用 JObject 构建 JSON。您可以使用匿名类或使用Paste JSON as Classes 粘贴您的 JSON 示例。根据您的 JSON 示例,匿名对象将如下所示。

var body = new
{
    accountrefrence = "XXXXX",
    messages = new[]
    {
        new
        {
            to = "XXXX",
            body = "XXX!"
        }
    }
}

实际的类可能是这样的:

public class Rootobject
{
    public string accountreference { get; set; }
    public Message[] messages { get; set; }
}

public class Message
{
    public string to { get; set; }
    public string body { get; set; }
}

【讨论】:

  • 这个解决方案对我有用并创建了正确的 json 输出,但是我似乎仍然在发布请求时遇到问题。
【解决方案2】:

管理 JSON 序列化的最简单方法是使用对象而不是原始字符串或尝试手动组合输出(就像您在这里所做的那样)。

因为您已经在使用 Newtonsoft 库,所以这很容易做到。

首先要创建一个对象,该对象代表您要发送到 api 的数据。正如此处另一个答案所述,您可以通过复制示例 JSON 并在 VS 中执行“将 JSON 粘贴为类”来简单地做到这一点。

生成的类很可能是这样的:

public class Rootobject
{
    public string accountreference { get; set; }
    public Message[] messages { get; set; }
}

public class Message
{
    public string to { get; set; }
    public string body { get; set; }
}

您现在可以做的是获取您的数据并填充此对象的属性的方法。由于您没有提供有关您在做什么的详细信息,我将简单地假设您有可能拥有一种以某种方式接收字符串值的方法。

    public void ComposeAndSendJson(string accountReference, string toAddress, string messageBody)
    {
        RootObject whatIwanttoSend = new RootObject();
        Message messageComposed = new Message();

        messageComposed.to = toAddress;
        messageComposed.body = messageBody;

        whatIwanttoSend.accountReference = accountReference;

        //I'm doing a pretty bad aproach but it's just to ilustrate the concept
        whatIwanttoSend.messages.toList().Add(messageComposed);

        var jsonData = JsonConvert.SerializeObject(whatIwanttoSend);

        //As you're working on async, you may need to do some working on here. In this sample i'm just calling it in Sync. 
        var ApiResponse = PostAsync("YOURENDPOINT",jsonData).Result();

        //Do something else with the response ... 

    }


    protected async Task<Task<HttpResponseMessage> PostAsync(Uri endpoint, object payload)
    {
        using (var httpClient = NewHttpClient())
        {
            //You have to tell the API you're sending JSON data
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //Execute your call
            var result = await httpClient.PostAsJsonAsync(endpoint, payload);

            //Basic control to check all went good.
            if (result.IsSuccessStatusCode)
            {
                return result;
            }

            //Do some management in case of unexpected response status here... 
            return result; //Statuscode is 400 here. 
        }
    }

我希望这能让您走上正确的道路。

【讨论】:

  • 谢谢。但是您在哪里可以找到接受字符串作为有效负载的 PostAsync 方法?我只能找到一个接受 HttpContent 的。
  • 我在记事本中编码时很糟糕 :) 实际上 HttpClient 类有一个接受对象作为参数的 PostAsJsonAsync 方法。让我编辑答案
  • 好吧,我在这里尝试了你的建议,但我的请求仍然由于某种神秘原因而失败!
  • 仍然收到 400 错误?还是现在有什么不同?
  • 它仍然是 400,根据 API 文档,当请求格式错误时它会返回 400。可以在这里看到:developers.esendex.com/api-reference#messagedispatcher我正在使用 Message Dispatcher 端点
【解决方案3】:

在这里找到我的答案:

POSTing JsonObject With HttpClient From Web API

我必须在我的内容中添加一个额外的标题,如下所示:

var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = client.PostAsync(url, content).Result;

我真的很想知道在 StringContent 构造函数中指定它有什么意义,但没关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 2016-11-15
    • 1970-01-01
    相关资源
    最近更新 更多