Question

I am working on an ASMX web service; trying to create a method that will download a document from a server and show the document in the browser (the calling .aspx web page). My service builds without error but I get the following error when I try to "Add Web Reference" in my Proxy class project:

System.Web.HttpResponse cannot be serialized because it does not have a parameterless constructor.

Here is a snippet of the code in .ASMX file:

public class FileService : System.Web.Services.WebService
{
    [WebMethod]
    public void DownloadDocument(string URI, HttpResponse httpResponse)
    {
        int DownloadChunkSize = (int)Properties.Settings.Default.DownloadChunkSize;
        // some more code here....
        using (httpResponse.OutputStream)
        {
            // more code here...
        }
    }
}

I see I am confused about how to send back an HttpResponse from a web service to a requesting web page. Could someone please give me a tip on how to do this? Thanks.

Was it helpful?

Solution

You should look into web handlers (.ashx). They are perfect for what you are trying to achieve.

For example:

public class Download : IHttpHandler, IRequiresSessionState {

    public void ProcessRequest(HttpContext context) {
        var pdfBytes = /* load the file here */
        context.Response.ContentType = @"Application/pdf";
        context.Response.BinaryWrite(pdfBytes);
        context.Response.End();
    }
}

UPDATE: An ashx handler is actually a replacement to aspx. Basically, it has no UI but still processes get / post requests just like an aspx page does. The point is to reduce the overhead generated by running a regular aspx page when all you need to do is return some simple content (like a file...) or perform a quick action.

The IRequiresSessionState interface allows you to use the SESSION object like any other page in your site can. If you don't need that, then leave it off.

This site has an interesting walk through on how to create one. Ignore Step 4 as you probably don't care about that.

Assuming that you have a regular page (aspx) that has a link to your document: The link in the aspx file would actually point directly to your ashx handler. for example:

<a href="/document.ashx?id=blah">Click Here</a>

Then the code in the ProcessRequest method of the ashx handler would do whatever calls it needed (like talk to your DLL) to locate the document then stream it back to the browser through the context.Response.BinaryWrite method call.

OTHER TIPS

That is not how standard ASMX web services work. If you want to make your own handler, or even use an ASPX page to deliver the doc, you are fine, but the standard ASMX web service method of doing this is to actually return the bits of the document as an encoded blob.

If you want to roll your own, consider this article: http://msdn.microsoft.com/en-us/magazine/cc163879.aspx

The web smethod (from asmx) returns an object, which can be serialized.

You need to create your method like:

[WbeMethod] public byte[] DownloadDocument(string URI)

Or if the content is some text - return string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top