如何将带有附加数据的 FormData 文件发送到 asp.net web api ajax 调用

Posted

技术标签:

【中文标题】如何将带有附加数据的 FormData 文件发送到 asp.net web api ajax 调用【英文标题】:How to send FormData files with additional data to asp.net web api ajax call 【发布时间】:2019-09-06 17:34:02 【问题描述】:

在这个项目中,我有一种输入和文件上传的形式,ajax 调用使用 FormData 对象将其发送到 api 的特定 Url。 当我在没有文件上传的情况下发送数据时,它工作正常(成功)。 当我发送带有上传文件的表单时,它有时会返回不受支持的媒体类型或使用对象 Null 调用 web api,我在网上尝试了很多代码,但没有成功。在此先感谢,这是我的代码。

html

   <form id="myForm" enctype="multipart/form-data">
                    <div class="form-group">
                        <label for="inputEmail4">Title</label>
                        <input type="text" class="form-control required" name="Title" id="Title" placeholder="Title">
                        <span id="TitleSpan" class="d-none text-danger">This field is required</span>
                    </div>
                    <div class="form-group">
                        <label for="inputAddress">Description</label>
                        <textarea type="text" class="form-control required" name="Description" id="Description" placeholder="Description..." maxlength="500" rows="5"></textarea>
                        <span id="chars">500</span> characters remaining
                        <span id="DescriptionSpan" class="d-none text-danger">This field is required</span>
                    </div>
                    <div class="form-group">
                        <label for="inputState">Priority</label>
                        <select id="Priority" name="Priority" class="form-control">
                            <option selected>Low</option>
                            <option>Medium</option>
                            <option>High</option>
                        </select>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-4">
                            <label for="City">City</label>
                            <select id="City" name="City" class="form-control">
                                <option value="Cairo" selected>Cairo</option>
                                <option value="Giza">Giza</option>
                            </select>
                        </div>
                        <img style="display:none;" src="~/Content/load.gif" id="loadingImg" />
                        <div class="form-group col-md-4">
                            <label for="Region">Region</label>
                            <input type="text" class="form-control required" name="Region" id="Region" placeholder="Region">
                            <span id="RegionSpan" class="d-none text-danger">This field is required</span>
                        </div>
                    </div>
                    <div class="form-group col-md-8">
                        <label for="exampleFormControlFile1">Upload Images</label>
                        <input type="file" class="form-control-file" value="Browse" id="PhotoPath" name="PhotoPath" accept=".png,.jpg,.jpeg" multiple>
                    </div>
                </form>

我的 js

$(document).ready(function () 
    $('#btnAdd').on('click', function (e) 
            CreatePostIssuejs();
        
    );
function CreatePostIssuejs() 
    console.log("Calling");
    console.log("i'm tracking you");
    debugger;
    var files = $("#PhotoPath").get(0).files;
    var formData = new FormData();
    for (var i = 0; i < files.length; i++) 
        formData.append("fileInput", files[i]);
    
    formData.append('Title', $("#Title").val());
    formData.append('Description', $('#Description').val());
    formData.append('Priority', $('#Priority').val());
    formData.append('City', $('#City').val());
    formData.append('Region', $('#Region').val());
    var fileData = formData;
    $.ajax(
        url: 'api/Poset/CreatePostIssue',
        data: fileData,
        type: "POST",
        cache: false,
        contentType: false, // Not to set any content header
        processData: false, // Not to process data
        traditional: true,
        success: function (result, status, xhr) 
            debugger;
            alert(result);
            $('#myModal').modal('hide');
            $('#modalsuc').modal('show');
        ,
        error: function (xhr, status, error) 
            debugger;
            alert(status);
            $('#modalwar').modal('show');
        
    );


网络接口

 [Route("api/Poset/CreatePostIssue")]
        [HttpPost]
        public IHttpActionResult CreatePostIssue([FromBody]PostIssueDTO postissueDTO)
        
            if (ModelState.IsValid)
            
                try
                
                    string fname = null;
                    var userid = User.Identity.GetUserId();
                    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];
                            fname = userid + postedFile.FileName;
                            var filePath = HttpContext.Current.Server.MapPath("~/Images/" + fname);
                            postedFile.SaveAs(filePath);
                            docfiles.Add(filePath);
                        
                    
                    else
                     
                    Post post = new Post();
                    post.PostType = "PostIssue";
                    post.AddedTime = DateTime.Now;
                    post.Title = postissueDTO.Title;
                    post.Description = postissueDTO.Description;
                    post.Priority = postissueDTO.Priority;
                    post.City = postissueDTO.City;
                    post.Region = postissueDTO.Region;
                    post.PhotoUrl = fname;
                    post.UserId = User.Identity.GetUserId();
                    _db.Posts.Add(post);
                    _db.SaveChanges();
                    return Json("success");
                
                catch (Exception ex)
                
                   return Json("somethimg went wrong" + ex);
                

            
            else
            
               return Json("Model State wrong"); 
            

        

模型 dto

 public class PostIssueDTO
    
        public int Id  get; set; 
        public string PostType  get; set; 
        public DateTime AddedTime  get; set; 
        public string Title  get; set; 
        public string Description  get; set; 
        public string Priority  get; set; 
        public string City  get; set; 
        public string Region  get; set; 
        public HttpPostedFileBase PhotoPath  get; set; 
        public DateTime? UpdatedOn  get; set; 
        public bool IsPinned  get; set; 
        public bool IsDelected  get; set; 

我预计这会像我在网上看到的那样工作。

【问题讨论】:

【参考方案1】:

请用这个替换你的 js 函数:

function CreatePostIssuejs() 
    console.log("Calling");
    console.log("i'm tracking you");
    debugger;

    var formData = new FormData();

    var file = document.getElementById("PhotoPath").files[0];
    formData.append("PhotoPath", file);
    formData.append('Title', $("#Title").val());
    formData.append('Description', $('#Description').val());
    formData.append('Priority', $('#Priority').val());
    formData.append('City', $('#City').val());
    formData.append('Region', $('#Region').val());
    var fileData = formData;
    $.ajax(
        url: 'api/Poset/CreatePostIssue',
        data: fileData,
        type: "POST",
        cache: false,
        contentType: false, // Not to set any content header
        processData: false, // Not to process data
        traditional: true,
        success: function (result, status, xhr) 
            debugger;
            alert(result);
            $('#myModal').modal('hide');
            $('#modalsuc').modal('show');
        ,
        error: function (xhr, status, error) 
            debugger;
            alert(status);
            $('#modalwar').modal('show');
        
    );

更新 请也更改此设置

 public IHttpActionResult CreatePostIssue(PostIssueDTO postissueDTO)

【讨论】:

ajax 未发送到带有错误函数的 api 不支持的媒体类型 @Alaaeddine 我更新了我的答案,这个解决方案现在应该可以工作了@KarimFahmy 类型或命名空间 FromForm 属性未找到 @Alaaeddine 这对我有用:public IHttpActionResult CreatePostIssue(PostIssueDTO postissueDTO) ajax not sent to api with error function unsupported media type,但让我告诉你,我在解决方案后创建了没有 webapi 的项目 MVC 模板创建我已经使用 Nuget 安装了 **webapi ** 这可能是问题吗? @Alaaeddine

以上是关于如何将带有附加数据的 FormData 文件发送到 asp.net web api ajax 调用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 jQuery 中发送带有 Ajax 请求的 FormData 对象? [复制]

我可以在javascript中将数组附加到“formdata”吗?

如何在 javascript 中的 FormData 中附加对象?

如何使用 $.each 将多个文件输入附加到 FormData 对象?

如何在 formData 对象中附加文件而不在 Node.js 中物理保存文件?

将数据 URI 转换为文件,然后附加到 FormData