0

I need to send a uri to a Controller method in my my Web API app which has the following signature:

public HttpResponseMessage PostXMLFile(string serialNum, string siteNum, XElement xElement)

Or should it be this instead:

public HttpResponseMessage PostXMLFile(string serialNum, string siteNum, List<XElement> xElements)

?

Anyway, as you can see, it can't be just the XML, but must have the serialNum and siteNum args, too.

I'm assuming the uri can look like this:

http://<machineName>:<port>/api/<ControllerName>?serialNum=N&siteNum=N&xElement=<some flattened XML>

IOW, something like:

http://Platypus:4242/api/Platypi?serialNum=2&siteNum=7&xElement=<xml bla bla </xml>

Am I right (about what needs to be placed in the URI)?

If so, how do I get that "some flattened XML" there. Is it something like this:

string xml = Bla; //some XML as string
XMLSerializer xmlSerial = new XMLSerializer();
string serialized = xmlSerial.Serialize(xml);

...and then tack the contents of serialized onto the end of the URI? Or how can I accomplish this?

Note: the XML passed as an arg will usually contain hundreds of XML "records" (arrays of elements?)

UPDATE

This is what I would like to be able to do (fantasy pseudocode):

UriBuilder uriBuilder = new UriBuilder();
XMLSerializer xmlCereal = new XMLSerializer();
File xmlToSerialize = // Load XML from file
string xmlAsStr = xmlCereal.Serialize(xmlToSerialize);
uriBuilder.Query.Add(xmlAsStr);
// pass uri to the Web API Post method

...but don't know just how to implement that in reality.

UPDATE 2

Also, do I have to explicitly specify XML as a type to be serialized in my Web API by doing adding something to WebApiConfig's Register method? I currently have this, with Json explcitly added:

public static void Register(HttpConfiguration config, IWindsorContainer container)
{
    MapRoutes(config);
    RegisterControllerActivator(container);
    config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
        new CamelCasePropertyNamesContractResolver();
}

Do I need to add a:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

line or lines, too?

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    I think those formatters are just for responses eg for sending XML or JSON back from a controller method – Daniel Feb 24 '14 at 22:49
  • 1
    Could you change the parameter from XElement to string and then do XElement.Parse()? – Daniel Feb 24 '14 at 22:54
  • I really need to send an entire XML file, so I probably need a generic list of XElement or something else. – B. Clay Shannon-B. Crow Raven Feb 24 '14 at 23:02
  • 1
    If you really want your controller method to accept an XElement or List instead of string or string[] I don't know if there's anything out of the box that will do it but you might be able to create a custom model binder that does it and then add the ModelBinderAttribute and your custom type to your method. – Daniel Feb 24 '14 at 23:38
  • I don't really care what it sends/the data type; I just need to be able to send two string args, and a "bunch" of XML. IOW, if there's a way to serialize an XML file to a string in a way that it can be parsed on the other end without jumping through too many miniscule and razor-sharp hoops, that would be fine. – B. Clay Shannon-B. Crow Raven Feb 24 '14 at 23:48

1 Answers1

1

I'll post this as an answer as it's a bit hard to describe in comments

public HttpResponseMessage PostXMLFile(string serialNum, string siteNum, string xmlString)
{
    var xElement = XElement.Parse(xmlString);
    // do whatever now with your xElement;
}

Then you'd be able to call your method like:

http://<machineName>:<port>/api/<ControllerName>?serialNum=2&siteNum=7&xmlString=<xml bla bla </xml>

(though watch out for encoding)

As for adding the XML to your url, because it's just a string, you can just read it as normal text and append it to your url.

If you want to accept lists of elements, I believe you can change your controller method to

public HttpResponseMessage PostXMLFile(string serialNum, string siteNum, [ModelBinder]List<string> xmlStrings)
{
    foreach(var xmlString in xmlStrings)
    {
       var xElement = XElement.Parse(xmlString);
       // do whatever now with your xElement;
    }
}

and your url will look something like

http://<machineName>:<port>/api/<ControllerName>?serialNum=2&siteNum=7&xmlStrings=<xml bla bla </xml>&xmlStrings=<xml more bla bla </xml>&xmlStrings=<xml even more bla bla </xml>

It doesn't quite make sense to me that you would want to load text from a file and then 'serialize' it to XML for wire transmission when both the file contents and xml are already serialized. You don't need to create any XDocuments or XElements until your controller method receives the xml string.

Daniel
  • 452
  • 3
  • 12
  • What I really want to do is send an xml file at the same time that I'm passing those other two args (serialNum and siteNum); the xml file is potentially too long to pass on the URI. At the receiving end, I'll parse the XML file. It needs to be sent from the client as XML and then parsed in the Web API app. – B. Clay Shannon-B. Crow Raven Feb 25 '14 at 17:25
  • "It doesn't quite make sense to me that you would want to load text from a file and then 'serialize' it to XML" The file starts out as XML. Why they want to send it that way, I'm not sure, but that's how it is. At the other/server end it gets parsed and certain elements inside the XML get posted to a "database" (MS Access). – B. Clay Shannon-B. Crow Raven Feb 25 '14 at 17:30
  • See my new question here: http://stackoverflow.com/questions/22002407/how-can-i-simultaneously-pass-args-and-an-xml-file-to-a-web-api-controller-metho – B. Clay Shannon-B. Crow Raven Feb 25 '14 at 17:36