1

I am using Web API to receive XML data and convert it to an Object. Which is working fine.

    public void Post([FromBody] trackermessages model)
    {
        try
        {

How do I get the RAW XML data? Is there a way to get the XML data as the Request begins or inside this action?

I tried this:

    public void Post([FromBody] trackermessages model, [FromBody] string rawText)
    {
        try
        {

But this is not allowed.

I also tried this:

    public void Post([FromBody] trackermessages model)
    {
        try
        {
            var strean = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();

But I get the Exception:

This method or property is not supported after HttpRequest.GetBufferlessInputStream has been invoked.

EDIT:

I am getting the Exception:

var stream = await Request.Content.ReadAsStreamAsync();
stream.Seek(0, System.IO.SeekOrigin.Begin); // On this Line
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();

enter image description here

Dawood Awan
  • 7,051
  • 10
  • 56
  • 119

3 Answers3

2

This is how I did it, because I had to read the RAW data then convert to Object:

    public void Post(HttpRequestMessage request)
    {
            // Reading data as XML string to log to files - In case message structure is changed
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);
            var str = xmlDoc.InnerXml;

            // Convert to model
            var model = XMLHelper.FromXml<trackermessages>(str);

   }

And the XMLHelper was copied from another question on stackoverflow: https://stackoverflow.com/a/3187539/1910735

Community
  • 1
  • 1
Dawood Awan
  • 7,051
  • 10
  • 56
  • 119
0

Yes, you can get the raw XML. You do need to seek back to the start of the stream since it will have been read to the end when processing the Model.

    public async void Post([FromBody]TestModel value)
    {
        var stream = await this.Request.Content.ReadAsStreamAsync();
        stream.Seek(0, System.IO.SeekOrigin.Begin);
        StreamReader reader = new StreamReader(stream);
        string text = reader.ReadToEnd();
        Console.Write(text);
    }
CamW
  • 3,223
  • 24
  • 34
0

The problem then is that your application is using GetBufferlessInputStream to read uploads without buffering them. While that is good for memory usage on the server, it means that after you've read the stream once it will no longer be available.

Your stream is being read like this when populating your model. By default GetBufferedInputStream is used which is why it works for me.

I suggest that you take the raw XML as input into the action and then manually deserialize into the model. Alternatively you can switch back to accepting posted data into a buffer. You probably followed something like this to turn it on : https://blogs.msdn.microsoft.com/kiranchalla/2012/09/04/receiving-request-file-or-data-in-streamed-mode-at-a-web-api-service/ and should undo that to turn it off.

CamW
  • 3,223
  • 24
  • 34