1

I am using RestSharp to post an object to asp.net Web API action. For JSON format, my client side codes work OK with server side that provides Web API post action. For XML format, my other client side codes do not work; debugging on server side Web API action, the object binding is always null; the input paramenter "analyticsLogs" is recevied as null for XML format (see codes below). Please help.

The following is my asp.net web API POST action on server side:

[HttpPost]
        public HttpResponseMessage PostAnalyticsLogs([FromBody] AnalyticsLogs analyticsLogs)
        {
            _logger.Info(analyticsLogs);

            bool status = _analyticService.CreateAnalyticsLogs(analyticsLogs);
            HttpResponseMessage response = new HttpResponseMessage();

            if(status)
            {
                response = Request.CreateResponse<AnalyticsLogs>(HttpStatusCode.OK, analyticsLogs);
            }                
            else
            {
                response = Request.CreateResponse<AnalyticsLogs>(HttpStatusCode.InternalServerError, analyticsLogs);
            }
            return response;
        }

The client codes for JSON format works OK:

private void buttonPostAnalyticsLogsDTO_Click(object sender, EventArgs e)
        {

            try
            {
                string pingMessage = string.Empty;

                clearDataGridViewLinqToExcel();

                if (!isWebAPISiteRunning(out pingMessage))
                {
                    MessageBox.Show(pingMessage);
                    _logger.Error(pingMessage);
                    return;
                }

                // POST
                AnalyticsLogs analyticsLogs = new AnalyticsLogs();
                Analytics analytics = new Analytics();
                analytics.Action = "Action test JSON";
                analytics.Category = "Category test JSON";
                analytics.Label = "Label test";
                analytics.Value = 2147483647;
                analytics.Timestamp = DateTime.Now;

                analyticsLogs.Add(analytics);  
                // REST SHARP

                var client = new RestClient(_webApiBaseUrl);
                var request = new RestRequest();
                request.Method = Method.POST;
                request.RequestFormat = DataFormat.Json;  // JSON ***************
                request.Resource = "Analytic";


                request.AddBody(analyticsLogs);


                var response = client.Execute<AnalyticsLogs>(request);


                if (response.ResponseStatus == ResponseStatus.Error)
                {
                    _logger.Error(response.ErrorMessage);
                    MessageBox.Show(response.ErrorMessage);
                    return;
                }

                dataGridViewLocalDMSWebAPIForDataAggregator.DataSource = response.Data;
            }
            catch(Exception ex)
            {
                _logger.Error(ex);
                MessageBox.Show(ex.Message);
            }
        }

The client codes for XMLformat do not work:

private void buttonPostAnalyticsLogsDTO_XML_Click(object sender, EventArgs e)
        {
            try
            {
                string pingMessage = string.Empty;

                clearDataGridViewLinqToExcel();

                if (!isWebAPISiteRunning(out pingMessage))
                {
                    MessageBox.Show(pingMessage);
                    _logger.Error(pingMessage);
                    return;
                }

                // POST
                AnalyticsLogs analyticsLogs = new AnalyticsLogs();
                Analytics analytics = new Analytics();
                analytics.Action = "Action test XML";
                analytics.Category = "Category test XML";
                analytics.Label = "Label test";
                analytics.Value = 47950494;
                analytics.Timestamp = DateTime.Now;

                analyticsLogs.Add(analytics);  

                // REST SHARP

                var client = new RestClient(_webApiBaseUrl);
                var request = new RestRequest();
                request.Method = Method.POST;
                request.RequestFormat = DataFormat.Xml; // XML *****************
                request.Resource = "Analytic";


                request.AddBody(analyticsLogs);


                var response = client.Execute<AnalyticsLogs>(request);


                if (response.ResponseStatus == ResponseStatus.Error)
                {
                    _logger.Error(response.ErrorMessage);
                    MessageBox.Show(response.ErrorMessage);
                    return;
                }

                dataGridViewLocalDMSWebAPIForDataAggregator.DataSource = response.Data;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                MessageBox.Show(ex.Message);
            }
        }

My custom DTO classes:

public class Analytics
    {
        public DateTime Timestamp { get; set; }

        public long UserExpId { get; set; }
        public string UserExpStatus { get; set; }
        public string Category { get; set; }
        public string Action { get; set; }
        public string Label { get; set; }
        public int Value { get; set; }
    }

public class AnalyticsLogs : List<Analytics>
    {
    }

Debugging the problem with XML client codes gives me some information:

    (new System.Collections.Generic.Mscorlib_CollectionDebugView<RestSharp.Parameter>(request.Parameters)).Items[0] :RequestBody


    +       [0] {text/xml=<AnalyticsLogs>
  <Analytics>
    <Timestamp>9/9/2014 9:15:58 AM</Timestamp>
    <UserExpId>0</UserExpId>
    <Category>Category test XML</Category>
    <Action>Action test XML</Action>
    <Label>Label test</Label>
    <Value>47950494</Value>
  </Analytics>
</AnalyticsLogs>}      RestSharp.Parameter



    request.RootElement : null
1
  • probably try without the datetime field. If it works, then this is due to the date time serialization problem with restsharp Commented Sep 24, 2014 at 11:54

1 Answer 1

2

I've found the problem. The RestSharp Serializer is not comaptible with the DataContractSerializer or XmlSerializer. Both are used from Web API (Default: DataContractSerializer).

RestSharp produces clean XML but the DataContractSerializer need some extra information (aka xmlns:i and xmlns attributes).

You can reproduce your problem within an console application with this code: (It will throw an detailed exception within the deserialization process)

AnalyticsLogs analyticsLogs = new AnalyticsLogs();
Analytics analytics = new Analytics();
analytics.Action = "Action test XML";
analytics.Category = "Category test XML";
analytics.Label = "Label test";
analytics.Value = 47950494;
analytics.Timestamp = DateTime.Now;

analyticsLogs.Add(analytics);

var serializer = new RestSharp.Serializers.XmlSerializer();
var xml = serializer.Serialize(analyticsLogs);
var obj = Deserialize<AnalyticsLogs>(xml);

static string Serialize<T>(T value) {
    XmlMediaTypeFormatter formatter = new XmlMediaTypeFormatter();
    // formatter.UseXmlSerializer = true;

    // Create a dummy HTTP Content.
    Stream stream = new MemoryStream();
    var content = new StreamContent(stream);
    /// Serialize the object.
    formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait();
    // Read the serialized string.
    stream.Position = 0;
    return content.ReadAsStringAsync().Result;
}

static T Deserialize<T>(string str) where T : class {
    XmlMediaTypeFormatter formatter = new XmlMediaTypeFormatter();
    // formatter.UseXmlSerializer = true;

    // Write the serialized string to a memory stream.
    Stream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(str);
    writer.Flush();
    stream.Position = 0;
    // Deserialize to an object of type T
    return formatter.ReadFromStreamAsync(typeof(T), stream, null, null).Result as T;
}

The Methods are from Web API Tutorial and you have to install Web API in your console app. I've found no solution to get them both work together - sry :(

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.