Как отформатировать JSON для почтового запроса - PullRequest
0 голосов
/ 20 декабря 2018

Я немного не уверен, как сделать мой пост-запрос в C #.Я попытался сделать это в Почтальоне, и он работает там без проблем.Я думаю, что моя проблема заключается в форматировании JSON.Я создаю свой JSON с JObjects в библиотеке Newtonsoft.Когда приведенный ниже код выполняется, это вывод;{"accountreference":"XX","messages":"[{\r\n \"to\": \"+XXXXX\",\r\n \"body\": \"XXXXXXXX\"\r\n}]"} Это допустимо, но, как вы можете видеть, оно содержит разрывы строк и escape-символы.После публикации его в API, который я использую, я всегда получаю неверный запрос 400.

Я пробовал различные сериализаторы и методы, но не смог заставить его работать.Я также удостоверился, что заголовок Authroization является правильным, если он был неправильным, API должен был сказать это в своем сообщении возврата.По мнению разработчиков API, это сообщение должно появиться только в том случае, если тело неверно.Я попытался опубликовать строку с переносами строк в Почтальоне, что также дает 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 работает в Почтальоне:

{
    "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.

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Самый простой способ управлять сериализацией 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. 
        }
    }

Надеюсь, это направит вас на правильный путь.

0 голосов
/ 21 декабря 2018

Нашел мой ответ здесь:

POSTing JsonObject с помощью 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, но хорошо.

0 голосов
/ 20 декабря 2018

Вам не нужно создавать свой JSON, используя JObject.Вы можете использовать анонимные классы или вставить свой образец JSON, используя Paste JSON as Classes.На основе вашего образца 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; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...