Search code examples
c#httprequestfilestreamashx

Passing a file from an external source to a .ashx handler?


I have a handler on my webserver. I use it to route images from an upload tool on the site the handler sits on.

I do this by using a form's submit action:

<form id="fileupload" action="~/handlers/Upload.ashx" method="post" enctype="multipart/form-data">

Now, I need to expose this handler for external use (from an app or another source that is not my website, etc).

I have tried building a separate test project that uses the same method, only the form action is the url to my handler:

<form id="fileupload" action="http://mywebsite/handlers/Upload.ashx" method="post" enctype="multipart/form-data">

Also, I have tried manually building the request and passing the stream:

using (var stream = File.OpenRead(FILE_PATH))
{
     var httpRequest = WebRequest.Create(UPLOADER_URI) as HttpWebRequest;
     httpRequest.Method = "POST";
     stream.Seek(0, SeekOrigin.Begin);
     stream.CopyTo(httpRequest.GetRequestStream());

     var httpResponse = httpRequest.GetResponse();
     StreamReader reader = new StreamReader(httpResponse.GetResponseStream());
     var responseString = reader.ReadToEnd();

     //Check the responsestring and see if all is ok
 }

The first method using the form on the site where the handler is housed is working as I expect. :)

Using that method externally isn't receiving a response at all.

The C# method hits the handler to the point that is authenticates the user, but after that point I don't believe the file stream is being passed properly. I have a bunch of error handling to check for various properties on the file.. the response should write back these errors, but it is always empty.

Any suggestions or input would be greatly appreciated.

Thank you for your help!

EDIT:

Here is the handler registration in web config:

<add name="Upload" path="Upload.ashx" verb="*" type="mynamespace.Upload" resourceType="Unspecified" preCondition="integratedMode" />

EDIT:

I set up my remote debugger to determine that the handler is being hit in my C# example. But the request has no files in it. stream.CopyTo() must not be the correct call I'm looking for?

Any thoughts?

EDIT:

I modified how the file is being passed a little bit. But still when I get hit the handler, the request.Files is empty. Here is the modified code:

const string FILE_PATH = "C:\\image.jpg";
string UPLOADER_URI = string.Format("http://localhost//handlers/Upload.ashx");

using (var stream = File.OpenRead(FILE_PATH))
{
     var httpRequest = WebRequest.Create(UPLOADER_URI) as HttpWebRequest;
     httpRequest.Method = WebRequestMethods.Http.Post;
     httpRequest.AllowWriteStreamBuffering = true;
     httpRequest.ContentType = "binary/octet-stream";

     stream.Seek(0, SeekOrigin.Begin);

     byte[] bArray = new byte[stream.Length];

     stream.Read(bArray, 0, Convert.ToInt32(stream.Length));

     httpRequest.ContentLength = bArray.Length;

     Stream rStream = httpRequest.GetRequestStream();
     rStream.Write(bArray, 0, bArray.Length);
     rStream.Close();

     var httpResponse = httpRequest.GetResponse();
     StreamReader reader = new StreamReader(httpResponse.GetResponseStream());
     var responseString = reader.ReadToEnd();

     //Check the responsestring and see if all is ok
  }

So now I am converting the file to a byte[] and then writing that byte[] to the request stream. Kind of surprised the stream isn't being written to as I expect. This seems to straight forward.


Solution

  • The first thing I would check is the Handler registration configuration in the web.config. For example, maybe is only allowed to receive POSTs and no GETs. In the file upload scenario uses a POST, but in the another scenario you´re describing looks like you´re using a GET. Maybe that´s why is ignoring your request.

    HTH