1

I need to read content of message from the request body in WCF REST service like -

SERVICE SIDE CODE

string request = Encoding.UTF8.GetString(OperationContext.Current.RequestContext.RequestMessage.GetBody<byte[]>());

But I am getting an error on the service side, no matter what I try:

Expecting element 'base64Binary' from namespace 'http://schemas.microsoft.com/2003/10/Serialization/'.. Encountered 'Element' with name 'Human', namespace 'http://numans.hr-xml.org/2007-04-15'.

and the service contract is defined as:

 //[OperationContract(Name = "LoadMessages", IsOneWay = true)]
    [WebInvoke(Method = "POST",
        UriTemplate = "/LoadMessages",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare)]
    [Description("Inbound Message")]
    void LoadMessages();

and the implementation is as:

    public void LoadMessages()
    {
        string content = string.Empty;
        //var request = OperationContext.Current.RequestContext.RequestMessage.GetBody<FileState>();
        string request = Encoding.UTF8.GetString(OperationContext.Current.RequestContext.RequestMessage.GetBody<byte[]>());
 }

CLIENT SIDE CODE

Content that I'm sending is:

string jsonData = "{ \"categoryid\":\"" + file.CategoryId + "\",\"fileId\":\"" + file.FileId + "\" }";

I tried many options to send data from the client like:

var buffer = System.Text.Encoding.UTF8.GetBytes(jsonData);
var content = new ByteArrayContent(buffer);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

and also tried this:

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

Posting request:

 HttpResponseMessage executionResult = httpClient.PostAsync($"{url}/LoadMessages", content).Result;

I also tried serializing/de-serializing at client/server end, but that also is not working.

Can someone please suggest code samples what I can try that might work? Or point out what am I doing wrong.

A few more examples of what I tried with the JSON data :

 var jsonData = JsonConvert.SerializeObject(data, Formatting.Indented); 
 var details = JObject.Parse(data);

Pasting my client side function for clarity:

  HttpClient httpClient = new HttpClient(new HttpClientHandler());
  HttpStatusCode statusCode = HttpStatusCode.OK;
  string auditMessage = string.Empty;
  using (httpClient)
  {
     var url = ConfigurationManager.AppSettings["APIURL"];
     try
     {
        string jsonData = "{ \"categoryid\":\"" + file.CategoryId + "\",\"fileId\":\"" + file.FileId + "\" }";
                    
         //var jsonData = JsonConvert.SerializeObject(data, Formatting.Indented);
         //var details = JObject.Parse(data);

         //var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
        var buffer = System.Text.Encoding.UTF8.GetBytes(jsonData);
        var content = new ByteArrayContent(buffer);
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        HttpResponseMessage executionResult = httpClient.PostAsync($"{url}/LoadMessages", content).Result;
        statusCode = executionResult.StatusCode;
        if (statusCode == HttpStatusCode.Accepted)
        {
          file.Status = "Success";
        }
      }
      catch (Exception ex)
      {
      }
    }
Shivani
  • 224
  • 5
  • 19

1 Answers1

1

Here is my demo:

This is the interface document of the service:

enter image description here

This is the request:

class Program
{
    
    static void Main(string[] args)
    {
        
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8012/ServiceModelSamples/service/user");
        request.Method = "POST";
        request.ContentType = "application/json;charset=UTF-16";
        string Json = "{\"Email\":\"123\",\"Name\":\"sdd\",\"Password\":\"sad\"}";
        request.ContentLength = Encoding.UTF8.GetByteCount(Json);
        Stream myRequestStream = request.GetRequestStream();
        StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
        myStreamWriter.Write(Json);
        myStreamWriter.Close();

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();

        Stream myResponseStream = response.GetResponseStream();
        //myResponseStream.ResponseSoapContext
        StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
        string retString = myStreamReader.ReadToEnd();
        myStreamReader.Close();
        myResponseStream.Close();
        Console.WriteLine(retString);
        Console.ReadKey();

    }
}

enter image description here

Feel free to let me know if the problem persists.

UPDATE

Define the Test class:

[DataContract]
    public class Test { 
    [DataMember]
    public string categoryid { get; set; }
    [DataMember]
    public string fileId { get; set; }
    }

the implementation is as:

public void LoadMessages(Test test)
    {
  Test dataObject = OperationContext.Current.RequestContext.RequestMessage.GetBody<Test>(new DataContractJsonSerializer(typeof(Test)));
           Console.WriteLine(dataObject.categoryid);
 }
Ding Peng
  • 3,702
  • 1
  • 5
  • 8
  • I have updated my question for a few more details, added client side function. I am facing issues at reading service side request body, and your code seems to be reading client side response (correct me if I'm wrong). Can you see my code above and suggest? – Shivani Sep 14 '20 at 06:36
  • Hi,I found a similar question on SO, you can refer to this link:https://stackoverflow.com/questions/33998431/error-while-reading-body-of-request-message – Ding Peng Sep 14 '20 at 07:49
  • I tried it that way, it didn't work, so posted another question specific to my problem. This is how I am receiving content at the service (depends on how I send - sometimes root type ="object") { "categoryid":"e2769919-4b07-42e4-bf18-001a7fce436b","fileId":"3405" } – Shivani Sep 14 '20 at 07:59
  • You can try to send the request with Postman first. – Ding Peng Sep 14 '20 at 08:29
  • I have tested the service side code through Postman already, Surprisingly, it works. I'm sending same data through Postman - { "categoryid": "E2265519-4D237-42E4-BF18-001A7FCE436B", "fileId": "3405" } .I am passing from service like this - string data = "{ \"categoryid\":\"" + file.CategoryId + "\",\"fileId\":\"" + file.FileId + "\" }"; var content = new StringContent(data, Encoding.UTF8, "application/json"); So I am not sure if I am passing incorrectly. – Shivani Sep 14 '20 at 08:37
  • Will adding DataContract matter? Because I've not exposed my api method as OperationContract, so I thought it'll work without it. – Shivani Sep 14 '20 at 08:39
  • In WCF, data is serialized through DataContract, adding DataContract will not affect the function of the service, I suggest you add it. – Ding Peng Sep 14 '20 at 09:18
  • The DataContract helped with the solution, thank you. – Shivani Sep 14 '20 at 10:20