部分视图文件上传

时间:2016-01-04 09:31:46

标签: c# asp.net-mvc entity-framework

我正在试图弄清楚如何使用局部视图存储multiplie文件。可以看到局部视图的屏幕截图 here

只要我使用常规表单输入,部分视图本身就能正常工作。然而,存储文件有点复杂。由于我正在使用Entity First,我只是存储对文件的引用而不是实际文件本身。 这适用于单个文件。字节引用存储到我的数据库中,我可以在视图中生成指向该文件的链接,该视图显示某个记录的所有属性。 但是,如果我想要多次上传,我对如何解决这个问题一无所知。每增加一行一个。

我也不确定如何通过jQuery定位某一行的单独字段,因为所有行都是动态生成的,但这是一个不同的问题。

相关代码:

我的控制器的POST操作:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateSrv([Bind(Include = "ID,CreationTimestamp,EditTimestamp,requestStatus,Requester,Reponsible,DeliveryDate,Project,CostCenter, MailCounter, ExtendedOrders")] Request request, HttpPostedFileBase upload)
    {

        if (ModelState.IsValid)
        {
            if (upload != null && upload.ContentLength > 0)
            {
                if (upload.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(upload.FileName);
                    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                    upload.SaveAs(path);

                    using (var reader = new System.IO.BinaryReader(upload.InputStream))
                    {
                        request.ExtendedOrders.ToArray()[0].File = reader.ReadBytes(upload.ContentLength);
                    }
                }                    
            }

            request.CreationTimestamp = DateTime.Now;
            request.EditTimestamp = DateTime.Now;
            request.RequestStatus = "Initial";
            request.RequestType = "Services";
            db.requests.Add(request);
            db.SaveChanges();

            return RedirectToAction("Index");
        }
        return View(request);
    }

使用AJAX将行添加到局部视图的控制器方法:

    [HttpGet]
    public ActionResult AddOrderRowExtended()
    {
        OrderExtended order = new OrderExtended();
        order.Units = GetSelectListItems(GetUnitsFromDB());
        order.Unit = "PC";
        order.Currencies = GetSelectListItems(GetCurrenciesFromDB());
        order.Currency = "European Euro";
        return PartialView("~/Views/Orders/OrderExtendedCreate.cshtml", order);
    }       

然后我在“主”视图中调用局部视图。 addOrder按钮动态添加更多行:

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


<div class="form-horizontal">
... some fields of my Request model...

            <tbody id="OrderZone">
            @foreach (var row in Model.ExtendedOrders)
            {
                Html.RenderPartial("~/Views/Orders/OrderExtendedCreate.cshtml", row);
            }
        </tbody>
    <button class="btn btn-sm btn-success" type="button" id="addOrder">Add row</button>
    <br />
    <div class="body-content">
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>      
</div>

我的OrderExtended模型:

public class OrderExtended
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }


   ....

    [NotMapped]
    [DataType(DataType.Upload)]
    public HttpPostedFileBase Quotation { get; set; }

    public byte[] File { get; set; }

    //FK
    public int RequestRefId { get; set; }

    [ForeignKey("RequestRefId")]
    public virtual Request Request { get; set; }
}

OrderExtendedCreate.cshtml

@model RFP_MVC.Models.OrderExtended



<tr class="editorRow">
    @using (Html.BeginCollectionItem("ExtendedOrders"))
    {
        <td class="col-md-2">@Html.EditorFor(model => model.Material, new { htmlAttributes = new { @class = "input-sm form-control" } })</td>
        <td class="col-md-1">@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "input-sm form-control" } })</td>
        <td class="col-md-2">@Html.DropDownListFor(model => model.Unit, Model.Units, new { id = "Unit", @class = "input-sm form-control select2" })</td>
        <td class="col-md-2">@Html.DropDownListFor(model => model.PurchGroup, Model.PurchGroupList, "Select...", new { @class = "input-sm form-control" })</td>
        <td class="col-md-2">
            <div class="input-group">
                <span class="input-group-btn">
                    <button class="btn btn-sm btn-default" type="button" data-toggle="modal" data-target="#myModal"><span class="glyphicon glyphicon-search"></span></button>
                </span>
                @Html.EditorFor(model => model.Vendor, new { htmlAttributes = new { id = "Vendor" , @class = "input-sm form-control" } })
            </div>
        </td>
        <td class="col-md-1">@Html.EditorFor(model => model.OrderingCode, new { htmlAttributes = new { @class = "input-sm form-control" } })</td>
        <td class="col-md-1">@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "input-sm form-control" } })</td>
        <td class="col-md-1">@Html.DropDownListFor(model => model.Currency, Model.Currencies, new { id = "Currency", @class = "input-sm form-control select2" })</td>
        <td class="col-md-2">
            <span class="btn btn-sm btn-default btn-file glyphicon glyphicon-folder-open"><input type="file" name="upload"></span>
        </td>
    }
</tr>

提前致谢

更新了解决方案:

更改了我的POST方法

  1. 将参数更改为IEnumerable(由ramiramilu建议):

    IEnumerable files

  2. 遍历所有文件并处理它们:

    int fileIndex = 0; foreach(文件中的HttpPostedFileBase上传) {     if(upload!= null&amp;&amp; upload.C​​ontentLength&gt; 0)     {
            var fileName = Path.GetFileName(upload.FileName);         var path = Path.Combine(Server.MapPath(“〜/ uploads”),fileName);         upload.SaveAs(路径);

        using (var reader = new System.IO.BinaryReader(upload.InputStream))
        {
            request.ExtendedOrders.ToArray()[fileIndex].File = reader.ReadBytes(upload.ContentLength);
        }
    
    fileIndex++;
    }
    

    }

2 个答案:

答案 0 :(得分:2)

如果您要上传多个文件,则需要IEnumerable<HttpPostedFileBase> upload作为Action的参数。获得IEnumerable<HttpPostedFileBase> upload后,请使用foreach并保存每个文件。

答案 1 :(得分:0)

您可以使用以下代码使用部分视图上传文件。 创建文件上传控制器。

public class FileUploadController : Controller
 {
     //
     // GET: /FileUpload/

     public ActionResult Index()
     {
         return View();
     }
     public ActionResult UploadFile()
     {
         var httpPostedFileBase = Request.Files["FileName"];
         if (httpPostedFileBase != null && httpPostedFileBase.ContentLength > 0)
         {
             string extension = System.IO.Path.GetExtension(httpPostedFileBase.FileName);
             string path1 = string.Format("{0}/{1}", Server.MapPath("~/SavedFiles"),  extension);
             if (System.IO.File.Exists(path1))
                 System.IO.File.Delete(path1);

             httpPostedFileBase.SaveAs(path1);
         }
         ViewData["Status"] = "Success";
         return View("Index");
     }
 }

您可以在主视图中存在部分视图。

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
//like wise you can call the fileupload partial view in multiple views
        @Html.Partial("_FileUpload")
    </div>
</body>
</html>

你的偏见是这样的..

@using(Html.BeginForm("UploadFile","FileUpload",FormMethod.Post,new{enctype="multipart/form-data"}))
{
    <input type="file" name="FileName" id="file" style="width:240px"/>
    <input type="submit" value="Upload"/>
}

您还可以查看此文章..

http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx/

希望这会对你有所帮助。 感谢