Search code examples
c#asp.net-mvc-4asp.net-web-apimediatypeformatter

ASP.NET Web API PUT action parameter does not carry through


OK, so I have a MediaTypeFormatter:

public class iOSDeviceXmlFormatter : BufferedMediaTypeFormatter
{
    public iOSDeviceXmlFormatter() {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
    }
    public override bool CanReadType(Type type) {
        if (type == typeof(iOSDevice)) {
            return true;
        }
        return false;
    }

    public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) {
        iOSDevice device = null;
        using (XmlReader reader = XmlReader.Create(readStream)) {
            if (reader.ReadToFollowing("iOSDevice")) {
                if (!reader.IsEmptyElement) {
                    device = new iOSDevice();
                    ... do processing here ...
                }
            }
        }
        readStream.Close();
        return device;
    }

I have this action to handle PUT:

    public void Put(string id, iOSDevice model)
    {
    }

I have tried this as well:

    public void Put(string id, [FromBody]iOSDevice model)
    {
    }

And I've tried this:

    public void Put(string id, [FromBody]string value)
    {
    }

None of these work when I do this:

string data = "<iOSDevice>xml_goes_here</iOSDevice>";
WebClient client = new WebClient();
client.UploadString(url, "PUT", data);

The action refuses to trigger my iOSDeviceXmlFormatter, and it won't even read it as a [FromBody] string. How do you get this thing to map?

Thanks,

Allison


Solution

  • How did you register your formatter? You'll want to register this formatter in the first position so that it takes precedence over WebAPI's default formatters. The code would look like this:

    config.Formatters.Insert(0, new iOSDeviceXmlFormatter());
    

    That should make sure that any requests that come in with content-type application/xml or text/xml for type iOSDevice use your formatter for deserialization.