【问题标题】:How to Upload Image in ASP MVC?如何在 ASP MVC 中上传图片?
【发布时间】:2016-08-03 12:35:12
【问题描述】:

我在尝试上传图片时遇到了这个问题。当我点击提交按钮时,我收到以下错误:

索引代码:

当我在没有模态参数的情况下使用它时,它可以工作,但窗口不是模态的,看起来很糟糕。

型号:

public partial class Prod
{
    public string PName { get; set; }
    public byte[] PFile{ get; set; }
}

索引视图:

@using (Html.BeginForm("Create", "Products", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <p>
       @Html.ActionLink(" ", "Create", "Products", null, new { data_modal = "file", id = "btnCreate", @class = "btn btn-small btn-primary pull-right fa fa-cart-plus" })

       @Html.ActionLink(" ", "Create", "Products", null, new { id = "btnCreate", @class = "btn btn-small btn-primary pull-right fa fa-cart-plus" })
    </p>
}

创建视图:

@using (Html.BeginForm("Create", "Products", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

    <div class="modal-body">

        <div class="form-horizontal">
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            <div class="form-group">
                @Html.LabelFor(model => model.PFile, "Plik", htmlAttributes: new { @class = "control-label col-md-3" })
                <div class="col-md-9">
                    @Html.TextBoxFor(model => model.PFile, new { type = "file", name = "imageF" })
                    @Html.ValidationMessageFor(model => model.PFile, "", new { @class = "text-danger" })
                </div>
            </div>

        </div>

    </div>

    <div class="modal-footer">
        <button class="btn" data-dismiss="modal">Anuluj</button>
        <input class="btn btn-primary" type="submit" value="Zapisz" />
    </div>
}

控制器:

[HttpPost]        
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = "PFile")] Prod pro, HttpPostedFileBase imageF)
{                    
    if (ModelState.IsValid)
    {
   
            if (imageF != null)
            {
                pro.PName= imageF.ContentType;
                pro.PFile= new byte[imageF.ContentLength];
                imageF.InputStream.Read(pro.PFile, 0, imageF.ContentLength);
            }

         
             db.Prods.Add(pro);
             db.SaveChanges();
             return Json(new { success = true });
  
    }

    return PartialView("Create", pro);
}

modalform.js

$(function () {

    $.ajaxSetup({ cache: false });

    $("a[data-modal]").on("click", function (e) {

        // hide dropdown if any
        $(e.target).closest('.btn-group').children('.dropdown-toggle').dropdown('toggle');


        $('#myModalContent').load(this.href, function () {


            $('#myModal').modal({
                /*backdrop: 'static',*/
                keyboard: true
            }, 'show');

            bindForm(this);
        });

        return false;
    });


});

function bindForm(dialog) {

    $('form', dialog).submit(function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            contentType: 'multipart/form-data',
            success: function (result) {
                if (result.success) {
                    $('#myModal').modal('hide');
                    //Refresh
                    location.reload();
                } else {
                    $('#myModalContent').html(result);
                    bindForm();
                }
            }
        });
        return false;
    }); 
} 

有什么问题?请帮忙解决这个问题。

【问题讨论】:

  • 通过ajax发帖是不是表单编码类型丢失了?
  • 对不起,我是初学者,我不知道你是什么意思
  • 我的意思是您在表单中添加了 enctype multipart/form-data,但随后您通过 ajax 帖子提交文件,而我没有看到它带有相同的编码类型。
  • 我在我的 JS 文件中添加了:contentType:'multipart/form-data',但没有帮助(请看 - 我编辑了代码)。也许我做错了什么

标签: asp.net asp.net-mvc base64 image-upload


【解决方案1】:

抱歉我的英语不好!

使用这种形式,您不需要使用 ajax。确保 PName 有一个隐藏的输入,否则您发送到控制器的模型将无效。我很确定您需要一个 ID 才能在数据库中添加数据,因此将其添加到您的模型中并确保您的变量 pro 具有有效的 id(一个数字)。

试试这个让你的控制器上传文件。确保根据您的需要更改退货线路! :

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = "PFile,PName")] Prod pro)
{                    
    if (ModelState.IsValid)
    {    
        try
        {
            if (Request.Files[0] != null && Request.Files[0].ContentLength > 0)
            {
                byte[] tmp = null;
                using (var bin = new BinaryReader(Request.Files[0].InputStream))
                {
                    tmp = bin.ReadBytes(Request.Files[0].ContentLength);
                }
                pro.PName = Request.Files[0].ContentType;
                pro.PFile = tmp;
            }
        }
        catch {
            throw new Exception("There is no file to upload.");
            // TODO Change the exception to this if your want your PFile and PName to be null if there's no file.
           // pro.PName = "";
           // pro.PFile = null;
        }
        db.Prods.Add(pro);
        db.SaveChanges();
        return RedirectToAction("Index", "Whatever");
    }
    return PartialView("Create", pro);
}

【讨论】:

  • 只有当我打开时没有像我的代码那样的模态表单时它才有效。当我使用模态表单参数时,出现此错误:索引超出范围。必须是非负数且小于集合的大小。
  • @Ebasse 好的,所以尝试使用 ajax 但使用 formData 发送它!这是通过 ajax 将文件发送到 C# 方法的好方法!
【解决方案2】:

请检查这个。首先,您不能通过 ajax 调用发布文件。在服务器端发布文件需要完整的回发。还有一些其他技术可以处理来自 ajax 调用的文件。

检查此代码..

控制器功能。

   public ActionResult Create(Prod pro)
    {
        if (ModelState.IsValid)
        {

            if (pro.PFile != null)
            {
                pro.PName = pro.PFile.ContentType;
                pro.PFileByte = new byte[pro.PFile.ContentLength];
                pro.PFile.InputStream.Read(pro.PFileByte, 0, pro.PFile.ContentLength);
            }


            //db.Prods.Add(pro);
            //db.SaveChanges();
            return Json(new { success = true });
        }
        return PartialView("Create", pro);
    }

视图模型...

public partial class Prod
{
    public string PName { get; set; }
    public byte[] PFileByte { get; set; }
    public HttpPostedFileBase PFile { get; set; }
}

删除您的表单提交功能并检查。如果需要 ajax 调用,请在 cmets 上告诉我。

【讨论】:

  • 当我更改此代码并提交表单时,出现错误空异常。独立或模态参数与否。请告诉我如何更改 .js 文件才能正常工作?
  • 另一种方式是以base64string的形式在模型内部发送文件。在 javascript 中读取文件作为缓冲区,然后将其转换为 base64string。您可以轻松地将此字符串发送到控制器操作。在控制器上将此 base64 转换为缓冲区数组。如果您不使用 ajax 调用,上述代码必须有效。
【解决方案3】:

尝试在 Bind 属性中包含 HttpPostedFileBase 对象的名称。您未放入的任何内容都将从请求中排除。 像这样:

public ActionResult Create([Bind(Exclude = "PFile", Include = "imageF")] Prod pro, HttpPostedFileBase imageF)

【讨论】:

  • 不变。我认为探针在 JS 文件中
  • 对不起,我更新了我的答案。您必须使用包含而不是排除
  • 不变。我的代码在没有从 .js 文件中使用的 data_modal 参数的情况下工作。当我添加这个参数是错误 Null Exception
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 2014-12-04
  • 2021-08-27
  • 1970-01-01
相关资源
最近更新 更多