asp.net - MVC 6 WebAPI returns serialized HttpResponseMessage instead of file stream -
i'm trying make asp.net 5 mvc 6 webapi project output file, in response httpget request.
the file azure files share, stream containing binary file.
it seems me mvc serializes response object, , returns resulting json, rather returning response object itself.
here controller method:
[httpget] [route("getfile")] public httpresponsemessage getfile(string username, string password, string fullname) { var client = new azurefilesclient.azurefilesclient(username, password); stream azurefilestream = client.getfilestream(fullname).result; var filename = path.getfilename(fullname); using (httpresponsemessage response = new httpresponsemessage(httpstatuscode.ok)) { response.content = new streamcontent(azurefilestream); response.content.headers.contenttype = new mediatypeheadervalue("application/octet-stream"); response.content.headers.contentdisposition = new contentdispositionheadervalue("attachment") { filename = filename }; return response; } } the getfilestream method on azurefilesclient here, though stream source containing binary file content:
public async task<stream> getfilestream(string filename) { var uri = new uri(share.uri + "/" + filename); var file = new cloudfile(uri, credentials); using (var stream = new memorystream()) { await file.downloadtostreamasync(stream); stream.seek(0, seekorigin.begin); return stream; } } edit: here sample of json response:
{ "version": { "major": 1, "minor": 1, "build": -1, "revision": -1, "majorrevision": -1, "minorrevision": -1 }, "content": { "headers": [ { "key": "content-type", "value": [ "application/octet-stream" ] }, { "key": "content-disposition", "value": [ "attachmentx; filename=\"samplefile.docx\"" ] } ] }, "statuscode": 200, "reasonphrase": "ok", "headers": [], "requestmessage": null, "issuccessstatuscode": true }
after combination of reading documentation aswell trial , error, problems have been solved.
the azure part made using nuget package "windowsazure.storage" (4.4.1-preview)
first output got json serialized. required custom action result returned instead.
using microsoft.aspnet.mvc; using system.io; using system.threading.tasks; public class fileresultfromstream : actionresult { public fileresultfromstream(string filedownloadname, stream filestream, string contenttype) { filedownloadname = filedownloadname; filestream = filestream; contenttype = contenttype; } public string contenttype { get; private set; } public string filedownloadname { get; private set; } public stream filestream { get; private set; } public async override task executeresultasync(actioncontext context) { var response = context.httpcontext.response; response.contenttype = contenttype; context.httpcontext.response.headers.add("content-disposition", new[] { "attachment; filename=" + filedownloadname }); await filestream.copytoasync(context.httpcontext.response.body); } } now getting binary data streamed azure files share (or other async stream source)
using microsoft.windowsazure.storage; using microsoft.windowsazure.storage.auth; using microsoft.windowsazure.storage.file; using system; using system.collections.generic; using system.io; using system.text; using system.threading.tasks; public async task<stream> getfilestreamasync(string filename) { var uri = new uri(share.uri + "/" + filename); var file = new cloudfile(uri, credentials); // note: not wrap stream variable in using, since close stream soon. var stream = new memorystream(); await file.downloadtostreamasync(stream); stream.seek(0, seekorigin.begin); return stream; } and controller code. note use of iactionresult interface.
[httpget] [route("getfile")] public async task<iactionresult> getfile(string username, string password, string fullname) { var client = new azurefilesclient.azurefilesclient(username, password); stream stream = await client.getfilestreamasync(fullname); string filename = path.getfilename(fullname); return new customactionresults.fileresultfromstream(filename, stream, "application/msword"); } note: example used word files, might want making contenttype parameter dynamic, instead of static this.
Comments
Post a Comment