6

I would like to send the following XML document to my Web Api 2 controller; however, the [FromBody] parameter is always null.

Here is the request XML body:

<razorInbound server="PortfolioExposureServer" request="lookupRiskPointRecord">
  <caller>RazorClient</caller>
  <responseMode>xml</responseMode>
  <body>
    <conditions>
      <fromOffset>0</fromOffset>
      <top>100</top>
      <condition>
        <keyPath>
          <keyElement nodeOffset='1'>Currency</keyElement>
          <keyElement nodeOffset='2'>ID</keyElement>
        </keyPath>
        <lookupValue>USD</lookupValue>
      </condition>
    </conditions>
  </body>
</razorInbound>

Using Postman to send the request, is as follows :

POST /api/razorXmlRequest HTTP/1.1
Host: localhost:5000
Content-Type: application/xml
Cache-Control: no-cache
Postman-Token: 6ca91ebf-31e0-77f2-6f81-cb9993b69b1a

<razorInbound server="PortfolioExposureServer" request="lookupRiskPointRecord">
  <caller>RazorClient</caller>
  <responseMode>xml</responseMode>
  <body>
    <conditions>
      <fromOffset>0</fromOffset>
      <top>100</top>
      <condition>
        <keyPath>
          <keyElement nodeOffset='1'>Currency</keyElement>
          <keyElement nodeOffset='2'>ID</keyElement>
        </keyPath>
        <lookupValue>USD</lookupValue>
      </condition>
    </conditions>
  </body>
</razorInbound>

And the Web Api 2 controller :

NOTE: The param parameter is always null

I believe I need a proper class definition to correctly map the XML request, but I'm not sure how to construct it.

using System;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using RazorServices;
using System.Net.Http;
using System.Web.Http;
using System.Xml.Linq;
using System.Net;
using System.Xml;

namespace RazorWebApi.Controllers
{
    [Route("api/razorXmlRequest")]
    public class RazorXmlRequestController : ApiController
    {
        public class RawXml {
            public string RazorXml { get; set; }
        }

        [HttpPost]
        public async Task<HttpResponseMessage> Post([FromBody]RawXml param )
        {
            HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.OK);

            // code omitted...
			
            return resp;
        }
    }
}

And by the way, we are currently getting around this issue by setting up a StreamReader object to pull from this.Request.Content; however in my unit test I need to send my xml as a parameter.

[HttpPost]
        public async Task<HttpResponseMessage> Post()   // [FromBody]RawXml param )
        {
            HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.OK);

            StreamReader sr = new StreamReader(await this.Request.Content.ReadAsStreamAsync(), Encoding.UTF8);
            string xml = sr.ReadToEnd();

            if (xml == null || xml.Length < 4)
            {
                throw new RazorServicesException("Invalid XML");
            }
            RazorSession cred = RzWebApi.Cred;
            string reply = await RzWebApi.RazorSrv.xmlRequests.Request(cred, xml);
            resp.Content = new StringContent(reply, System.Text.Encoding.UTF8, "text/plain");
            return resp;
        }

2 Answers 2

8

Final solution was to change the Post param type to XElement:

[Route("api/razorXmlRequest")]
public class RazorXmlRequestController : ApiController
{
    /// <summary>
    /// Raw Razor request XML 
    /// </summary>
    /// <returns>Razor reply message as text</returns>
    [HttpPost]
    public async Task<HttpResponseMessage> Post([FromBody]XElement xml)
    {
        HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.OK);
        RazorSession cred = RzWebApi.Cred;
        string reply = await RzWebApi.RazorSrv.xmlRequests.Request(cred, xml);
        resp.Content = new StringContent(reply, System.Text.Encoding.UTF8, "application/xml");
        return resp;
    }
}

This worked straight-away without even providing the XmlFormatter as the gentlemen had suggested above (@TusharJ, thank you anyway for your input).

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

1 Comment

I tried something similar but getting an error. stackoverflow.com/questions/68128537/… .Please advice.
5

You can configure Web API to use XmlSerializer in your WebApiConfig.Register as follows;

config.Formatters.XmlFormatter.UseXmlSerializer = true;

1 Comment

Turns out that I can change the Post method to Post([FromBody]XElement param ) and the header's Content-Type: application/xml, and this will solve the problem. The xml content gets passed to the controller even without your suggestion above.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.