Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC4 WebAPI and Posting XML data

I'm missing a trick with the new webapi - I'm trying to submit an xml string through a post request and not having much luck.

The front end is using jQuery like this:

    $(document = function () {
    $("#buttonTestAPI").click(function () {

        var d = " <customer><customer_id>1234</customer_id></customer>";
        $.ajax({
            type: 'POST',
            contentType: "text/xml",
            url: "@Url.Content("~/api/Customer/")",
            data: d,
            success: function (result) {
                var str = result;
                $("#output").html(str);
            }
        });
    });
});

My controller is pretty simple at the moment - just the default for the post action - trying to return what was passed in:

    public string Post(string value)
    {
        return value;
    }

However, "value" is repeatedly null. The odd thing is, when I change my data in the jquery to be something like this:

d = "<customer_id>1234</customer_id>";

Then I get "value" in my controller as 1234.

How can I get access to the more complex xml string in my controller?

like image 984
Thomas Avatar asked May 03 '12 09:05

Thomas


People also ask

How do I post XML data in Web API?

To post XML data to the server, you need to make an HTTP POST request, include the XML in the body of the request message, and set the correct MIME type for the XML. The correct MIME type for XML is application/xml.

Can ASP Net Web API return XML?

If XML is required for every response then configure Web API to always return XML. This should NOT be done in the action since it is just configuration. ASP.NET Core defaults to JSON.

Can ASP Net Web API specialize to XML or JSON?

Web API provides media-type formatters for both JSON and XML. The framework inserts these formatters into the pipeline by default. Clients can request either JSON or XML in the Accept header of the HTTP request.


2 Answers

The following will allow you to read a raw XML message via a POST to a Web API method:

public void PostRawXMLMessage(HttpRequestMessage request)
{
   var xmlDoc = new XmlDocument();
   xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);   
}

You can debug and inspect the body, headers, etc. and will see the raw XML posted. I used Fiddler's Composer to make a HTTP POST and this works well.

like image 69
atconway Avatar answered Sep 30 '22 00:09

atconway


You are sending content type of text/xml but you have defined your parameter as string. Ideally your XML should be mapped to a class so that it can be deserialised.

So if you need raw xml then it is not supported yet. Web API currently is geared up for serialization MediaTypeFormatters and missing simple type formatters but they can easily built.

This one is a minimal implementation of such formatter supporting only read in your case and based on beta installer (and not nightly source code since it has substantially changed):

public class TextMediaTypeFormatter : MediaTypeFormatter
{
    public TextMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
    }

    protected override bool CanReadType(Type type)
    {
        return type == typeof (string);
    }

    protected override System.Threading.Tasks.Task<object> OnReadFromStreamAsync(Type type, Stream stream, 
        HttpContentHeaders contentHeaders, 
        FormatterContext formatterContext)
    {
        var taskCompletionSource = new TaskCompletionSource<object>();
        try
        {
            var memoryStream = new MemoryStream();
            stream.CopyTo(memoryStream);
            var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
            taskCompletionSource.SetResult(s);
        }
        catch (Exception e)
        {
            taskCompletionSource.SetException(e);           
        }
        return taskCompletionSource.Task;
    }
}

And to use it, just add it to formatters collection:

GlobalConfiguration.Configuration.Formatters.Insert(0, new TextMediaTypeFormatter());
like image 45
Aliostad Avatar answered Sep 30 '22 00:09

Aliostad