Upload file using WebApi, ajax

后端 未结 6 1166
深忆病人
深忆病人 2020-12-06 02:39

I want to upload file using a WebApi by making an ajax call and the file will save into database. I tried the code given in the this link. Here, it is saved the received da

相关标签:
6条回答
  • 2020-12-06 03:18

    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 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 讨论(0)
  • 2020-12-06 03:23

    You can't directly save file to the database.

    One of the options, apart from saving the file locally, is saving it into the memory stream and then passing it to the database. This question can give you the code example of how you can get the filename and extension and save the file into the memory: Web API: how to access multipart form values when using MultipartMemoryStreamProvider?

    0 讨论(0)
  • 2020-12-06 03:25

    I think what you want to achieve here is partly answered in this previous question

    Now, about saving directly to database, you should be able to achieve this without saving the file to a hard drive first, normally by taking the stream byte array and putting it into your database entity or row property as a byte[] (array of bytes)

    0 讨论(0)
  • 2020-12-06 03:35

    If you want to save the file to a BLOB field in your database, then you can use the code provided in the following post: Saving any file to in the database, just convert it to a byte array?.

    The relevant code is 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 committing a MemoryStream to the database provided in an answer I linked to.

    You will need a specific column in your table to save the actual file name. Basically, you will need a BLOB column for the file content and another TEXT or VARCHAR column for the file name. The link you provided shows a way to obtain the name of the file.

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

    0 讨论(0)
  • 2020-12-06 03:42

    The answer has several parts.

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

    @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>    
    }
    

    Second, to receive this data, create a controller, with a method like this:

    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 upload size is limited. You can overcome this limitations modifying web.config:

    1. Add maxRequestLength="max size in bytes" in <configuration><system.web><httpRuntime>. (Or create this lement if it doesn't exist):

    2. Add maxAllowedContentLength to <configuration><system.web><security><requestFiltering><requestLimits> element (or create this element if it doesn't 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 should include this inside a <location> element, so that this limits are only applied to the particular route where the files are uploaded, like this:

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

    Beware to modify the root web.config, not the one in the Views folder.

    Fourth, as to saving the data in the database, if you use EF, you simply need an entity 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 changes.

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

    0 讨论(0)
  • 2020-12-06 03:44

    A cleaner way to do this using 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;
        }
    }
    

    To use this webAPI in your markup. Use 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 type of file (extensions to accept) in the "accept" attribute of the input tag. Hope it will help! Enjoy!

    0 讨论(0)
提交回复
热议问题