I know (at least I think it's so) that when a Web API method is invoked, an HttpWebRequest is passed to it by the client. IOW, when a client sends something like this to invoke a Web API method:
192.168.125.50:28642/api/DeliveryItems/PostArgsAndXMLFileAsStr?serialNum=42&siteNum=99
...a HttpWebRequest object containing values for serialNum (42) and siteNum (99) are passed to the method.
I also hold (as of now, anyway) that if a large bunch of data needs to be sent (too many/much to pass as part of the URI, as serialNum and siteNum are in the example), this data can be embedded in the HttpWebRequest object on the client like this:
string data = "bla blee bloo blah foo bar doo dah";
WebRequest request = WebRequest.Create(uri);
. . .
byte[] arrData = Encoding.UTF8.GetBytes(data);
request.ContentLength = arrData.Length;
using (Stream oS = request.GetRequestStream())
{
oS.Write(arrData, 0, arrData.Length);
}
WebResponse response = request.GetResponse();
...and then decoded on the other (server) end using the "[FromBody]" attribute, something like this:
public void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
XDocument doc = XDocument.Parse(stringifiedXML);
Are my assumptions correct? IOW, for test code like this:
[Test]
public void TestNRBQDeliveryItemInterfacePostPPTData()
{
var DeliveryItem = IOC.container.Resolve<INRBQDeliveryItem>();
string data = @"<Command>
<DSD>
<line_id>1</line_id>
. . .
<discount>0.25</discount>
<fileDate>12/19/2013 1:33:27 PM</fileDate>
</DSD>
</Command>";
string uri = "http://localhost:21609/api/deliveryitems/InsertIntoPPTData";
WebRequest request = WebRequest.Create(uri);
request.Method = Enum.ToObject(typeof(HttpMethods), HttpMethods.POST).ToString();
request.ContentType = "application/json";
((HttpWebRequest)request).Accept = request.ContentType;
((HttpWebRequest)request).KeepAlive = false;
((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;
Encoding encoding = Encoding.UTF8; // needed?
byte[] arrData = Encoding.UTF8.GetBytes(data);
request.ContentLength = arrData.Length;
using (Stream oS = request.GetRequestStream())
{
oS.Write(arrData, 0, arrData.Length);
}
// Send the request to the server by calling GetResponse. (http://msdn.microsoft.com/en-us/library/debx8sh9(v=vs.110).aspx)
WebResponse response = request.GetResponse();
Assert.IsNotNull(response);
}
...should my current Web API method:
[HttpPost]
[Route("api/deliveryitems/InsertIntoPT109Data")]
public void InsertIntoPT109Data(HttpWebRequest httpwebreq)
{
HHSService.InsertIntoPPTData(httpwebreq);
}
...instead be changed to:
[HttpPost]
[Route("api/deliveryitems/InsertIntoPT109Data")]
public void InsertIntoPT109Data([FromBody] stringifiedXML)
{
HHSService.InsertIntoPT109Data(stringifiedXML);
}
?
In an attempt to be more plain, I think that I am being too explicit by using an HttpWebRequest object as an argument to my Web API method; I think/hope that a HttpWebRequest being sent is "a given" and what I need in this case is the "[FromBody] stringifiedXML" argument, and that I can then "unpack" the [FromBody] data something like the example I gave above (e.g., "XDocument doc = XDocument.Parse(stringifiedXML);").
Am I correct in either my existing code (which explicitly passes a HttpWebRequest object as the method's arg) or in the other case (where I assume a HttpWebRequest object is implicitly known to be there, and instead deal with the [FromBody] data embedded within it), or am I right in neither case?
If I am right in the first/current case (that I must pass a HttpWebRequest object), how can I get at the embedded data in the HttpWebRequest object? Would I need to call "getResponseStream" or...???
If I'm able to forego the explicit usage of HttpWebRequest, there's another wrinkle. This:
void InsertIntoPT109Data([FromBody] stringifiedXML);
...doesn't compile as an interface method, because the "[FromBody]" attribute is not recognized. Would replacing that with "String" suffice?
I've replaced the "HttpWebRequest httpwebreq"s with "[FromBody] String stringifiedXML", such as:
public void InsertIntoPT109Data([FromBody] String stringifiedXML)
...but now I get, "The type or namespace name 'FromBody' could not be found (are you missing a using directive or an assembly reference?)"
I get this whether I have added "using System.Web.Http;" or not.
If I need to add a DLL to the project references, which DLL is it?
I think @paulo-morgado covered the first part well, nothing further for me to add.
Regarding your FromBody
update at the end of your post, two things to note:
stringifiedXML
(I assume string
) even if you use [FromBody]
, andusing System.Web.Http;
[FromBody]
. Sometimes people confuse that with "System.Web.Mvc" which is specific to MVC projects and not Web API.