Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attaching files to WCF REST service responses

Tags:

rest

wcf

I have a resource that looks something like this:

/users/{id}/summary?format={format}

When format is "xml" or "json" I respond with a user summary object that gets automagically encoded by WCF - fine so far. But when format equals "pdf", I want my response to consist of a trivial HTTP response body and a PDF file attachment.

How is this done? Hacking on WebOperationContext.Current.OutgoingResponse doesn't seem to work, and wouldn't be the right thing even if it did. Including the bits of the file in a CDATA section or something in the response isn't safe. Should I create a subclass of Message, then provide a custom IDispatchMessageFormatter that responds with it? I went a short distance down that path but ultimately found the documentation opaque.

What's the right thing?

like image 892
David Seiler Avatar asked Jun 07 '10 18:06

David Seiler


2 Answers

It turns out that what I need is WCF "raw" mode, as described here. Broadly speaking, I want to do this:

[OperationContract, WebGet(UriTemplate = "/users/{id}/summary?format={format}"]
public Stream GetUserSummary(string id, string format)
{
    if(format == "pdf")
    {
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/pdf";
        return new MemoryStream(CreatePdfSummaryFileForUser(id));
    }
    else
    {
        // XML or JSON serialization.  I can't figure out a way to not do this explicitly, but my use case involved custom formatters anyway so I don't care.
    }
}
like image 133
David Seiler Avatar answered Sep 28 '22 06:09

David Seiler


In theory you could do it with a multi-part content MIME type (see http://www.faqs.org/rfcs/rfc2387.html). However, it would be much easier to return a URL in the XML/JSON response and the client can do a GET on that link to return the file.

like image 44
Darrel Miller Avatar answered Sep 28 '22 05:09

Darrel Miller