【问题标题】:HttpPostedfileBase is null using jQuery Ajax使用 jQuery Ajax 的 HttpPostedfileBase 为空
【发布时间】:2015-02-06 20:07:58
【问题描述】:

我在 Asp.net Mvc 中上传文件时遇到问题。首先我应该使用 Ajax 来传递上传文件的值。

在 javascript 中我有填充它的模型,当我用调试器检查它时是否正确填充了对象,但是当我将此模型发送到服务器(控制器)时

httpPostedfileBase 值始终为空。

我在 google 上搜索它,在一些帖子中我看到我不能将文件上传器与 Ajax 一起使用,但在其他帖子中我看到我可以。

但我无法修复我的代码。

这是我的 Javascript 代码。

$(document).ready(function () {

$('#btnUploadFile').on('click', function () {
   var data= new FormData();

    debugger;
    var files = $("#fileUpload").get(0).files;

    if (files.length > 0) {
        data.append("UploadedImage", files[0]);
    }
    var ResturantSharingViewModel =
   {
       Type: $("#SharingTargetType").val(),
       SharingTitle: $("#SharingTitle").val(),
       content: $("#Content").val(),
       ItemId : $("#ItemId").val(),
       Photos: files[0]
   };
    $.ajax({
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        url: '<%= Url.Action("SaveOneDatabase")%>',
        data: JSON.stringify(ResturantSharingViewModel),
          success: function (result) {
              var rs = result;
          },
          error: function () {
              alert("Error loading data! Please try again.");
          }
      });

我的控制器public virtual bool SaveOneDatabase(ResturantSharingViewModel result) 我的 ResturantSharingViewModel 视图模型

 public class ResturantSharingViewModel
{
    public Guid SharingPremiumHistoryID { get; set; }
    public string SharingTitle { get; set; }
    public string Content { get; set; }
    public DateTime AddedDate { get; set; }
    public bool IsSubmit { get; set; }
    public DateTime SubmitedDate { get; set; }
    public IEnumerable<SelectListItem> SharingTypes { get; set; }
    public IEnumerable<SelectListItem> SharingTargetType { get; set; }
    public short Type { get; set; }
    public Guid ItemId { get; set; }
    public HttpPostedFileBase[] Photos { get; set; }
}

我的 HTML 元素

    <form enctype="multipart/form-data">
    <article>
    <%--<% =Html.BeginForm("Add","PremiumSharing") %>--%>
   <hgroup class="radiogroup">
    <h1>ارسال خبر</h1>
    <%= Html.HiddenFor(model => model.SharingPremiumHistoryID) %>
    <%= Html.HiddenFor(model => model.ItemId) %>
    <div class="group">
        <span> ارسال به </span>
        <%= Html.DropDownListFor(model => model.SharingTargetType, Model.SharingTypes) %>
    </div>
</hgroup>
<div class="newseditor">
    <div class="input-form">
        <%= Html.LabelFor(model => model.SharingTitle, "عنوان خبر") %>
        <%= Html.TextBoxFor(model => model.SharingTitle) %>
    </div>

    <div class="input-form">
        <%= Html.LabelFor(model => model.Content, "متن خبر") %>
        <%= Html.TextAreaFor(model => model.Content) %>
    </div>
    <div><input id="fileUpload" type="file" />

    </div>
    <% if (ViewBag.IsInEditMode != null && !(bool)ViewBag.IsInEditMode)
       {%>
    <div class="input-form">
        <%= Html.CheckBox("SendToInTheCity") %> ارسال در بخش «در شهر» فیدیلیو
    </div>
    <%} %>

    <div class="input-submit">
        <button name="post" id="btnUploadFile"  onclick="uploadFile()" >ارسال خبر</button>
    </div>
    <br />
</div>

【问题讨论】:

  • 如果在控制器中添加“HttpPostedFileBase 文件”作为输入参数,您会看到什么?
  • 你的意思先生,你能给我举个例子吗?
  • 现在在您的标题中看到您使用 HttpPostedFileBased。对不起。

标签: javascript asp.net-mvc


【解决方案1】:

首先,可以使用 Ajax 上传,重要的是您需要在表单上设置 &lt;form enctype="multipart/form-data"&gt;&lt;/form&gt; 以告诉它您的表单有文件上传输入。然后您需要接受HttpPostedFileBase 作为控制器操作中的输入参数。

试试这个。 jquery 上传代码示例。 (主要取自How can I upload files asynchronously?

function uploadFile(uploadId) {
    var formData = new FormData($('form')[0]);

    $.ajax({
        url: '<%= Url.Action("SaveOneDatabase")%>',
        type: 'Post',
        beforeSend: function(){},
        success: function(result){

        },
        xhr: function() {  // Custom XMLHttpRequest
        var myXhr = $.ajaxSettings.xhr();
            if(myXhr.upload) { // Check if upload property exists
                // Progress code if you want
            }
            return myXhr;
        },
        error: function(){},
        data: formData,
        cache: false,
        contentType: false,
        processData: false
    });
}

HTML 表单需要这个属性。查看这篇文章为什么需要它 -> What does enctype='multipart/form-data' mean?

enctype="multipart/form-data"

C#

[HttpPost]
public ActionResult SaveOneDatabase(HttpPostedFileBase file)
{
}

【讨论】:

  • 你能展示一下你的表单元素和输入类型文件元素的样子吗?
  • @salar 我稍微改了一下代码,你用的是什么浏览器?
  • 我用的是firefox开发者版,觉得和浏览器无关
  • @salar 如果您使用的是 IE 9 及以下版本,它将无法正常工作。不过这应该可以。
【解决方案2】:

我修改了@a moradi 的答案。

JS:

//FormData:
//Consider it a normal form but with "multipart/form-data" encoding type.
//Inside it works same as XMLHttpRequest.send() method.    
var model = new FormData();
model.append("File", $('#file')[0].files[0]);
model.append("Name", "Name");
$.ajax({ 
        url: someUrl,
        type: "POST",
        data: model,
        //contentType: 
        //Sets the ContentType in header.
        //The default contentType is "application/x-www-form-urlencoded; charset=UTF-8". But this will prevent us sending AntiForgeryToken to service/controller.
        //To prevent this contentType is set to false.
        contentType: false,
        //processData:
        //To prevent data getting converted to string format, 'processData' option is set to false.
        processData: false,
        success = function (m) {...}
        error = function (m) {...}
    });

查看模型:

public class PhotoAlbumViewModel {
    public  string Name { get; set; }
    public HttpPostedFileBase File { get; set; }
}

控制器:

public JsonResult AddPhoto(PhotoAlbumViewModel model) {
    ...
}

参考:

详情请参考以下链接:FormDataJQueryContentType

【讨论】:

  • 像魅力一样工作
  • 我可以在没有 View Model 的情况下执行此操作吗?
【解决方案3】:

查看:

<script/>
var add_photo_url = "@Url.Action("AddPhoto", "Gallery")"; 
    var model = new FormData();    
    var i=0;//selected file index 
    model.append("File", files[i]);
    model.append("Name", "test");
    $.ajax({// and other parameter is set here 
        url: add_photo_url,
            type: "POST",
            data: model,
            dataType: "json",
            cache: false,
            contentType: false,
            processData: false

        })
        .always(function (result) { 
        });
</script>

查看模型:

public class PhotoAlbumViewModel {
    public  string Name { get; set; }
    public HttpPostedFileBase File { get; set; }
}

控制器:

public JsonResult AddPhoto(PhotoAlbumViewModel model) {
    // var result =...
    // and set your result; 
    return Json(result, JsonRequestBehavior.AllowGet);
}

【讨论】:

  • 请为您的代码添加一些解释。不鼓励仅使用代码回答。
  • 我可以在没有 ViewModel 的情况下执行此操作吗?
  • 这种方法有效吗? public JsonResult AddPhoto(string Name,HttpPostedFileBase File)
猜你喜欢
  • 2016-01-02
  • 2014-07-08
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
相关资源
最近更新 更多