Upload file using WebApi, ajax

I want to upload a file using WebApi by making an ajax call and the file will be saved in the database. I tried the code provided in this link . Here it saves the received data to the hard disk as a file without the specified extension, but I want to do something like when I save the file to the database. I also want to save the file name and the reason for the extension later, if I need to download the file, I can specify the file name and its extension. And in the link, the file is saved to the hard drive as a file, but is there a way I can directly save the file to DB.

+5
source share
6 answers

The answer consists of several parts.

First, to upload a file, you can use a view with this code:

@using (Html.BeginForm()) { <input type="file" value="Choose a file"/> <br/> <input type="button" value="Upload" id="upload"/> } @section scripts { <script type="text/javascript"> $(document).ready(function() { $('#upload').click(function () { var data = new FormData(); var file = $('form input[type=file]')[0].files[0]; data.append('file',file); $.ajax({ url: '/Api/File/Upload', processData: false, contentType: false, data: data, type: 'POST' }).done(function(result) { alert(result); }).fail(function(a, b, c) { console.log(a, b, c); }); }); }); </script> } 

Secondly, to get this data, create a controller using a method similar to the following:

 public class FileController : ApiController { [HttpPost] public async Task<string> Upload() { var provider = new MultipartMemoryStreamProvider(); await Request.Content.ReadAsMultipartAsync(provider); // extract file name and file contents var fileNameParam = provider.Contents[0].Headers.ContentDisposition.Parameters .FirstOrDefault(p => p.Name.ToLower() == "filename"); string fileName = (fileNameParam == null) ? "" : fileNameParam.Value.Trim('"'); byte[] file = await provider.Contents[0].ReadAsByteArrayAsync(); // Here you can use EF with an entity with a byte[] property, or // an stored procedure with a varbinary parameter to insert the // data into the DB var result = string.Format("Received '{0}' with length: {1}", fileName, file.Length); return result; } } 

Third, by default, the maximum download size is limited. You can overcome these limitations by changing web.config :

  1. Add maxRequestLength="max size in bytes" to <configuration><system.web><httpRuntime> . (Or create this control if it does not exist):

  2. Add maxAllowedContentLength to maxAllowedContentLength <configuration><system.web><security><requestFiltering><requestLimits> (or create this element if it does not exist)

These entries look like this:

 <configuration> <system.web> <!-- kilobytes --> <httpRuntime targetFramework="4.5" maxRequestLength="2000000" /> <configuration> <system.webServer> <security> <requestFiltering> <!-- bytes --> <requestLimits maxAllowedContentLength="2000000000"/> 

NOTE. You must include this in the <location> element so that these restrictions apply only to the specific route where the files are uploaded, for example:

 <location path="Api/File/Upload"> <system.web> ... <system.webServer> ... 

Beware of changing the root of web.config , not the one in the Views folder.

Fourth, as for storing data in a database, if you use EF, you just need an object like this:

 public class File { public int FileId { get; set; } public string FileName { get; set; } public byte[] FileContent { get; set; } } 

Create a new object of this class, add to the context and save the changes.

If you use stored procedures, create a procedure with the varbinary parameter and pass byte[] file as the value.

+12
source

A cleaner way to do this using the webAPI controller is as follows:

Create a web api controller file: UploadFileController.cs

 public class UploadFileController : ApiController { // POST api/<controller> public HttpResponseMessage Post() { HttpResponseMessage result = null; var httpRequest = HttpContext.Current.Request; if (httpRequest.Files.Count > 0) { var docfiles = new List<string>(); foreach (string file in httpRequest.Files) { var postedFile = httpRequest.Files[file]; int hasheddate = DateTime.Now.GetHashCode(); //Good to use an updated name always, since many can use the same file name to upload. string changed_name = hasheddate.ToString() + "_" + postedFile.FileName; var filePath = HttpContext.Current.Server.MapPath("~/Images/" + changed_name); postedFile.SaveAs(filePath); // save the file to a folder "Images" in the root of your app changed_name = @"~\Images\" + changed_name; //store this complete path to database docfiles.Add(changed_name); } result = Request.CreateResponse(HttpStatusCode.Created, docfiles); } else { result = Request.CreateResponse(HttpStatusCode.BadRequest); } return result; } } 

Use this webAPI in your markup. Use the following:

 <input type="hidden" id="insertPicture" /> <input id="insertFileupload" type="file" name="files[]" accept="image/*" data-url="/api/uploadfile" multiple> <script> $(function () { $('#insertFileupload').fileupload({ add: function (e, data) { var jqXHR = data.submit() .success(function (result, textStatus, jqXHR) {/* ... */ $('#insertPicture').val(result); alert("File Uploaded"); }) .error(function (jqXHR, textStatus, errorThrown) {/* ... */ alert(errorThrown); }) } }); }); 

You can change the file type (extension for acceptance) in the accept attribute of the input tag. Hope this helps! Enjoy it!

+2
source

If you want to save the file in the BLOB field in your database, you can use the code indicated in the following message: Saving any file in the database, just convert it to an array of bytes? .

The corresponding code is given below:

 public static int databaseFilePut(MemoryStream fileToPut) { int varID = 0; byte[] file = fileToPut.ToArray(); const string preparedCommand = @" INSERT INTO [dbo].[Raporty] ([RaportPlik]) VALUES (@File) SELECT [RaportID] FROM [dbo].[Raporty] WHERE [RaportID] = SCOPE_IDENTITY() "; using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails)) using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) { sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file; using (var sqlWriteQuery = sqlWrite.ExecuteReader()) while (sqlWriteQuery != null && sqlWriteQuery.Read()) varID = sqlWriteQuery["RaportID"] is int ? (int) sqlWriteQuery["RaportID"] : 0; } return varID; } 

You can combine the approach in the link you sent with the code for transferring the MemoryStream to the database provided in the answer I am linked to.

To save the actual file name, you will need a specific column in your table. Basically you will need a BLOB column for the contents of the file and another TEXT or VARCHAR column for the file name. The specified link shows how to get the file name.

However, as others have pointed out, you should not save files to a database. The most common way to handle file downloads is to save them to a location on the server and transfer the path to the saved file to the TEXT or VARCHAR field in the database.

+1
source

You cannot directly save the file to the database.

One of the parameters, in addition to saving the local file, saves it in the memory stream and then transfers it to the database. This question can give you sample code, how can you get the file name and extension and save the file in memory: Web API: how to access the values โ€‹โ€‹of a multi-line form when using MultipartMemoryStreamProvider?

0
source

I think that what you want to achieve is partially answered in this previous question

Now, about saving directly to the database, you can achieve this by not saving the file to your hard drive first, usually by taking an array of stream bytes and putting it in your entity object or database property as a byte [] (byte array)

0
source

JS code as below.

 var Sendmodel = new FormData();Sendmodel.append("TemplatePath",$('#fileTemplatePath')[0].files[0]);Sendmodel.append("Name","pradip"); $.ajax({ url: "api/project/SaveCertificateSettings", type: 'POST', contentType: false, processData: false, data: Sendmodel, success: function (data, textStatus, xhr) { }, error: function (xhr, textStatus, errorThrown) { alert('error'); } }); 

WEB API code as shown below.

 public object SaveCertificateSettings() { string Name = Convert.ToString(HttpContext.Current.Request.Form["Name"]); if (HttpContext.Current.Request.Files.AllKeys.Any()) { // Get the uploaded image from the Files collection var httpPostedFile = HttpContext.Current.Request.Files["TemplatePath"]; if (httpPostedFile != null) { // httpPostedFile.FileName; // Get the complete file path } } } 
0
source

Source: https://habr.com/ru/post/1210741/


All Articles