Search code examples
c#jsonrestrestsharp

REST api with C#.NET complex json data in body posting


I want to use sms gateway in my app. that's why I've contact with an operator and the operator give me a api format.

URL: https://ideabiz.lk/apicall/smsmessaging/v2/outbound/3313/requests

Request header

Content-Type: application/json 
Authorization: Bearer [access token] 
Accept: application/json

Body

{
    "outboundSMSMessageRequest": {
        "address": [
            "tel:+94771234567"
        ],
        "senderAddress": "tel:12345678",
        "outboundSMSTextMessage": {
            "message": "Test Message"
        },
        "clientCorrelator": "123456",
        "receiptRequest": {
            "notifyURL": "http://128.199.174.220:1080/sms/report",
            "callbackData": "some-data-useful-to-the-requester"
        },
        "senderName": "ACME Inc."
    }
}

Now, I've code it :

RestClient client = new RestClient(@"https://ideabiz.lk/");
RestRequest req = new RestRequest(@"apicall/smsmessaging/v2/outbound/3313/requests", Method.POST);

req.AddHeader("Content-Type", @"application/json");
req.AddHeader("Authorization", @"Bearer " + accessToken.ToString());
req.AddHeader("Accept", @"application/json");

string jSon_Data = @"{'outboundSMSMessageRequest': {'address': ['tel:+94768769027'],'senderAddress': 'tel:3313','outboundSMSTextMessage': {'message': 'Test Message : " + System.DateTime.Now.ToString() + "'},'clientCorrelator': '123456','receiptRequest': {'notifyURL': 'http://128.199.174.220:1080/sms/report','callbackData': 'some-data-useful-to-the-requester'},'senderName': ''}}";


JObject json = JObject.Parse(jSon_Data);
req.AddBody(json);

IRestResponse response = client.Execute(req);
string x = response.Content.ToString();
Console.WriteLine(x.ToString());

When i execute this program, in the line

req.AddBody(json);

my system crash and give error message that:

An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll

How can i post complex JSON by using C#.NET ?


Solution

  • You have two problems here:

    1. You need to set RequestFormat = DataFormat.Json before the call to AddBody:

          req.RequestFormat = DataFormat.Json;
          req.AddBody(json);
      

      Without setting the parameter, RestSharp tries to serialize the JObject to XML and falls into an infinite recursion somewhere -- most likely trying to serialize JToken.Parent.

    2. According to RestSharp's readme.txt (archived here), starting in version 103.0, RestSharp no longer uses Json.NET as their JSON serializer:

      There is one breaking change: the default Json*Serializer* is no longer 
      compatible with Json.NET. To use Json.NET for serialization, copy the code 
      from https://github.com/restsharp/RestSharp/blob/86b31f9adf049d7fb821de8279154f41a17b36f7/RestSharp/Serializers/JsonSerializer.cs 
      and register it with your client:
      
      var client = new RestClient();
      client.JsonSerializer = new YourCustomSerializer();
      

      RestSharp's new built-in JSON serializer doesn't understand JObject so you need to follow the instructions above if you are using one of these more recent versions, Create:

      public class JsonDotNetSerializer : ISerializer
      {
          private readonly Newtonsoft.Json.JsonSerializer _serializer;
      
          /// <summary>
          /// Default serializer
          /// </summary>
          public JsonDotNetSerializer() {
              ContentType = "application/json";
              _serializer = new Newtonsoft.Json.JsonSerializer {
                  MissingMemberHandling = MissingMemberHandling.Ignore,
                  NullValueHandling = NullValueHandling.Include,
                  DefaultValueHandling = DefaultValueHandling.Include
              };
          }
      
          /// <summary>
          /// Default serializer with overload for allowing custom Json.NET settings
          /// </summary>
          public JsonDotNetSerializer(Newtonsoft.Json.JsonSerializer serializer){
              ContentType = "application/json";
              _serializer = serializer;
          }
      
          /// <summary>
          /// Serialize the object as JSON
          /// </summary>
          /// <param name="obj">Object to serialize</param>
          /// <returns>JSON as String</returns>
          public string Serialize(object obj) {
              using (var stringWriter = new StringWriter()) {
                  using (var jsonTextWriter = new JsonTextWriter(stringWriter)) {
                      jsonTextWriter.Formatting = Formatting.Indented;
                      jsonTextWriter.QuoteChar = '"';
      
                      _serializer.Serialize(jsonTextWriter, obj);
      
                      var result = stringWriter.ToString();
                      return result;
                  }
              }
          }
      
          /// <summary>
          /// Unused for JSON Serialization
          /// </summary>
          public string DateFormat { get; set; }
          /// <summary>
          /// Unused for JSON Serialization
          /// </summary>
          public string RootElement { get; set; }
          /// <summary>
          /// Unused for JSON Serialization
          /// </summary>
          public string Namespace { get; set; }
          /// <summary>
          /// Content type for serialized content
          /// </summary>
          public string ContentType { get; set; }
      }
      

      And then do:

          RestRequest req = new RestRequest(@"apicall/smsmessaging/v2/outbound/3313/requests", Method.POST);
          req.JsonSerializer = new JsonDotNetSerializer();
      

    2023 update.

    As of Release 107.0.0 the default JSON serializer for RestSharp is System.Text.Json. This serializer also doesn't understand JObject, but as of .NET 6 supports an equivalent built-in type type JsonObject, so switching to System.Text.Json.Nodes for creating and deserializing free-form JSON is an option.

    The RestSharp documentation documentation has been updated with a section NewtonsoftJson (aka Json.Net):

    RestSharp support Json.Net serializer via a separate package RestSharp.Serializers.NewtonsoftJson

    WARNING

    Please note that RestSharp.Newtonsoft.Json package is not provided by RestSharp, is marked as obsolete on NuGet, and no longer supported by its creator.