c# - Base controller for exporting data to excel instead of returning viewmodel -
i have web api
project controllers return view model client application can show data grids.
this sample controller sample method can explain better:
public class samplecontroller: apicontrollerbase { [httpget, appauthorize(null)] public httpresponsemessage getsampledata(int employeeid, datetime fromdate, datetime todate) { httpresponsemessage returnval = null; // new, instead of returning model return file // don't want add every controller, have in base controller or something? // check if user request export grid excel if (this.request.getquerystrings().containskey("exportdata")) { // here have generate excel file returnval = new httpresponsemessage(httpstatuscode.ok); returnval.content = new bytearraycontent(filebytes); returnval.content.headers.contentdisposition = new headers.contentdispositionheadervalue("attachment"); returnval.content.headers.contentdisposition.filename = filename; returnval.content.headers.contenttype = new mediatypeheadervalue("application/octet-stream"); return returnval; } var model = samplerepository.getconsumptionsummary(employeeid, fromdate.touniversaltime().date, todate.touniversaltime().date); if (model != null) { returnval = request.createresponse(httpstatuscode.ok, new model.custom.jsonresponse { data = model, message = "", num = model.count, success = true }); } else { returnval = request.createresponse(httpstatuscode.ok, new model.custom.jsonresponse { data = null, message = "there error processing data.", num = 0, success = false, code = "err-001" }); } return returnval; } }
on client, user can request export same grid data excel. in scenario use same method grid generate excel file , return browser.
if (this.request.getquerystrings().containskey("exportdata")) { }
this line magic in method know if user has requested export data excel.
but, don't want put logic on each method on each controller, have in separate place applies methods.
i thinking in creating
filter
can place in methods or controllers want happen logic.
the code should using in filter or alternative approach be:
// check if user request export grid excel if (this.request.getquerystrings().containskey("exportdata")) { // here have generate excel file... returnval = new httpresponsemessage(httpstatuscode.ok); returnval.content = new bytearraycontent(filebytes); returnval.content.headers.contentdisposition = new headers.contentdispositionheadervalue("attachment"); returnval.content.headers.contentdisposition.filename = filename; returnval.content.headers.contenttype = new mediatypeheadervalue("application/octet-stream"); return returnval; }
any clue?
you have filestreamresult should you, don't have declare things.
i create custom actionresult. in 1 of our applications use custom "excelresult" :
public class excelresult : filestreamresult { public excelresult(stream filestream, string filename) : base(filestream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { filedownloadname = filename; } }
so when need generate , return excel file, (we extracted bit method in our "basecontroller") :
using (memorystream result = (memorystream)exportservice.exporttoexcel(foo)) { return excel(new memorystream(result.getbuffer()), filename); }
and excel method (in our base controller) :
public excelresult excel(stream stream, string filename) { if (stream == null) throw new argumentnullexception("stream"); if (string.isnullorwhitespace(filename)) throw new argumentnullexception("filename"); return new excelresult(stream, filename); }
Comments
Post a Comment