c# - Uploading and Downloading in Visual Studio vs. Production -
when create code in visual studio, runs temp directory. @ hosting provider (one hosts asp.net sites), in different directory (typically app server virtual folder iis). need have uploaded files in directory iis web server can find them, use case below work.
q: how can define links in mvc controllers/views work both in development in production (upload & download)?
use case: app needs allow file uploaded (still don't know on dev box upload to), , via link on page download same file.
in case you're in need of more detailed answer i'll give hints , on right track.
define contract can abstract concrete file provider implementation in order minimize impact , modifications code if need change underlying file storage later. instance if go azure in future version can implement azurefileprovider , store file using blobs.
public interface ifileprovider { uploadresult uploadfile(byte[] filecontent, string filename); downloadresult downloadfile(int fileid); }
implement interface file system-based file provider:
public class filesystemfileprovider : ifileprovider { public filesystemfileprovider(string absoutebasepath) { //check if absolutebaspath exists , create directory if doesn't. if (!directory.exists(absoutebasepath)) directory.createdirectory(absoutebasepath); } public uploadresult uploadfile(byte[] filecontent, string filename) { //todo: upload file implementation here } public downloadresult downloadfile(int fileid) { //todo download file implementation here } }
you can adjust contract according needs. here in sample uploadresult , downloadresult simple classes retrieve result of operations. example definition downloadresult:
public class downloadresult { public bool success { get; set; } public byte[] filecontent { get; set; } public string downloadname { get; set; } public string sizeinbytes { get; set; } //... other useful properties }
in startupauth.cs or global.asax (the place bootstrapper code runs, initialize file provider concrete implementation. approach works better ioc container in place. can use autofac, ninject or other like, please self favor , use one.
//read base path web.config may adjust on production hosting provider without need make , compile app var filebasepath = configurationmanager.appsettings["filebasepath"]; //get path absolute file system path var absolutebasepath = server.mappath(filebasepath); //initialize file provider absolute path var fileprovider = new filesystemfileprovider(absolutebasepath); //todo: configure ioc return fileprovider instance when ifileprovider requested.
as see in step 2 read application setting value web.config file. should present on appsettings section in configuration file.
<appsettings> <add key="filebasepath" value="~/filestorage"/> </appsettings>
with in place inject fileprovider controllers this:
public class uploadcontroller : controller { private readonly ifileprovider fileprovider; public uploadcontroller(ifileprovider fileprovider) { this.fileprovider = fileprovider; }
and can use provider on relevant action when need it.
[httppost] public actionresult upload(fileuploadmodel model) { //validate if (modelstate.isvalid) { //use fileprovider here upload file var content = new byte[model.postedfile.contentlength]; model.postedfile.inputstream.write(content, 0, content.length); var result = fileprovider.uploadfile(content, model.postedfile.filename); if (result.success) { //todo: notify user operation success return redirecttoaction("index", "upload"); } } // return view(model); }
hope helps!
ps: don't know why code formatting little bit crazy.
Comments
Post a Comment