-1

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...???

UPDATE

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?

UPDATE 2

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?

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

2 Answers2

2

The HttpWebRequest/HttpWebResponse are not sent to or received from the server. They are used to send to and receive data from the server.

Your assumptions are incorrect.

Paulo Morgado
  • 14,111
  • 3
  • 31
  • 59
1

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:

  1. you need to give a type to stringifiedXML (I assume string) even if you use [FromBody], and
  2. you need to add:
    using System.Web.Http;
    at the top of your file before you can use [FromBody]. Sometimes people confuse that with "System.Web.Mvc" which is specific to MVC projects and not Web API.
djikay
  • 10,450
  • 8
  • 41
  • 52
  • I'm getting "The type or namespace name 'Http' does not exist in the namespace 'System.Web' (are you missing an assembly reference?" on the using clause I've added ("using System.Web.Http;") – B. Clay Shannon-B. Crow Raven Jul 08 '14 at 16:49
  • @B.ClayShannon: Are you using Web API 2? This attribute was added in v2 (or 5.0) or Web API. – djikay Jul 08 '14 at 17:00
  • I believe so, but how can I verify that? – B. Clay Shannon-B. Crow Raven Jul 08 '14 at 17:01
  • @B.ClayShannon You should check your project references and make sure you have a reference to "System.Web.Http" with version 5.0 or later. – djikay Jul 08 '14 at 17:03
  • 1
    @B.ClayShannon If you don't have it, you can take a look at [this question](http://stackoverflow.com/questions/20202188/where-can-i-find-a-nuget-package-for-upgrading-to-system-web-http-v5-0-0-0) that explains how to get it. – djikay Jul 08 '14 at 17:08
  • There are 50 projects in this solution; the first one that has it is version 5.1.0.0 – B. Clay Shannon-B. Crow Raven Jul 08 '14 at 17:10
  • 1
    @B.ClayShannon Check under your "packages" folder to find "Microsoft.AspNet.WebApi.Core.5.1.0" (or similar) and ensure that somewhere inside its folder structure (inside "lib") you have the file "System.Web.Http.dll". Also, don't worry about the 50 projects, you only care about the one where you're trying to add the FromBody attribute. – djikay Jul 08 '14 at 17:13
  • Do you mean "References" folder? – B. Clay Shannon-B. Crow Raven Jul 08 '14 at 17:23
  • 1
    @B.ClayShannon Either "References" section in your project or, what I meant, the "packages" folder in the file system. Also, check out the file "packages.config" in your project, which should have a line similar to this (among many others): ``. – djikay Jul 08 '14 at 17:26