ASP MVC 文件上传 HttpPostedFileBase 为空

Posted

技术标签:

【中文标题】ASP MVC 文件上传 HttpPostedFileBase 为空【英文标题】:ASP MVC FIle Upload HttpPostedFileBase is Null 【发布时间】:2012-06-07 01:07:12 【问题描述】:

在我的控制器中,因为我希望能够填写有关视频的一些详细信息并实际上传它,Video 类不需要实际的视频,因为它将被传递到另一个 Web 服务。

public class VideoUploadModel
    
        public HttpPostedFileBase vid  get; set; 
        public Video videoModel  get; set; 
    

    //
    // POST: /Video/Create
    [HttpPost]
    public ActionResult Create(VideoUploadModel VM)
    
        if (ModelState.IsValid)
        
            db.Videos.AddObject(VM.videoModel);
            db.SaveChanges();
            return RedirectToAction("Index");  
        

        ViewBag.UserId = new SelectList(db.DBUsers, "Id", "FName", VM.videoModel.UserId);
        return View(VM);
    

在我看来我有

@model LifeHighlightsShoeLace.Controllers.VideoController.VideoUploadModel
@
   ViewBag.Title = "Create";


<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
@using (html.BeginForm("Create", "Video", FormMethod.Post, new  enctype = "multipart/form-data" ))

@Html.ValidationSummary(true)
<fieldset>
    <legend>Video</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.videoModel.KalturaID)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.videoModel.KalturaID)
        @Html.ValidationMessageFor(model => model.videoModel.KalturaID)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.videoModel.Size)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.videoModel.Size)
        @Html.ValidationMessageFor(model => model.videoModel.Size)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.videoModel.Date)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.videoModel.Date)
        @Html.ValidationMessageFor(model => model.videoModel.Date)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.videoModel.UploadedBy)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.videoModel.UploadedBy)
        @Html.ValidationMessageFor(model => model.videoModel.UploadedBy)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.videoModel.UserId, "User")
    </div>

    <div class="editor-field">
        @Html.DropDownList("UserId", String.Empty)
        @Html.ValidationMessageFor(model => model.videoModel.UserId)
    </div>
    <div class="editor-field">
    <input name="model.vid" type="file" />
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

当我提交表单时,VM 的 videoModel 部分已填写,但实际文件为空。 有什么想法吗?

【问题讨论】:

【参考方案1】:

根据OP评论更新

在 web.config 文件中设置最大文件长度 改变“?”到您希望最大的文件大小,例如 65536 是 64MB

<configuration>
  <system.web>
    <httpRuntime maxRequestLength="?" /> 
  </system.web>
</configuration>

您不能将文件添加到模型中,它将在它自己的字段中,而不是模型的一部分

<input name="videoUpload" type="file" />

您的操作不正确。它需要接受文件作为它自己的参数(或者如果多个使用IEnumerable&lt;HttpPostedFileBase&gt;作为参数类型)

[HttpPost]
public ActionResult Create(VideoUploadModel VM, HttpPostedFileBase videoUpload)

    if (ModelState.IsValid)
    
        if(videoUpload != null)  // save the file
            var serverPath = server.MapPath("~/files/" + newName);
            videoUpload.SaveAs(serverPath);
        

        db.SaveChanges();
        return RedirectToAction("Index");  
    

    ViewBag.UserId = new SelectList(db.DBUsers, "Id", "FName", VM.videoModel.UserId);
    return View(VM);

如果您允许选择多个文件,则必须允许这样做

[HttpPost]
public ActionResult Create(VideoUploadModel VM, IEnumerable<HttpPostedFileBase> videoUpload)

    if (ModelState.IsValid)
    
        if(videoUpload != null)  // save the file
            foreach(var file in videoUpload) 
                var serverPath = server.MapPath("~/files/" + file.Name);
                file.SaveAs(serverPath);
            
        

        db.SaveChanges();
        return RedirectToAction("Index");  
    

    ViewBag.UserId = new SelectList(db.DBUsers, "Id", "FName", VM.videoModel.UserId);
    return View(VM);

【讨论】:

谢谢(和@BuildStarted)。现在,当我单击创建时,IE 给我一个“IE 无法显示网页”错误,并且 chrome 告诉我与 localhost 的连接已中断。如果我不包含文件,它会毫无问题地发布。 听起来您选择了大于 4mb 的文件 更新了答案看看 谢谢,我猜对于大文件上传,我最好使用某种 ajax/flash/silverlight 文件上传器? 不,这是浏览器的问题,无论如何你都必须设置它以允许接受更大的文件【参考方案2】:

它没有绑定的原因是模型绑定器在绑定像您这样的复杂模型时只查看QueryStringFormRouteData。解决此问题的方法是在您的操作方法中添加另一个参数。 (把你的“名字”也改成“vid”)

[HttpPost]
public ActionResult Create(VideoUploadModel VM, HttpPostedFileBase vid)

    //add your vid to the model or whatever you want to do with it :)

    if (ModelState.IsValid)
    
        db.Videos.AddObject(VM.videoModel);
        db.SaveChanges();
        return RedirectToAction("Index");  
    

    ViewBag.UserId = new SelectList(db.DBUsers, "Id", "FName", VM.videoModel.UserId);
    return View(VM);

【讨论】:

【参考方案3】:

为我工作:

public class CreateVeiwModel
    
        public Speaker Speaker  get; set; 
        public Guid Guid  get; set; 
        public HttpPostedFileBase File  get; set; 
    

控制器:

[HttpPost]
        public ActionResult Create(CreateVeiwModel model)
        
            if (ModelState.IsValid)
            try
            
                Repository.AddSpeaker(model.Speaker);
            ...
        

查看:

@Html.Label("Most Up-to-Date CV")
             <input type="file" name="File"/>

我认为解决方案放在那里:Model.File ~ &lt;input name="File"/&gt;

【讨论】:

【参考方案4】:

改变

<input name="model.vid" type="file" />

@Html.TextBoxFor(model => model.vid, new type="file") 

根据您页面上的其他内容以及呈现视图的位置,MVC 将生成唯一 ID,我认为您的硬编码 ID 未正确与表单字段相关联。

【讨论】:

是的,我以前有过,我只是再试一次。 VM.vid 仍然为空。

以上是关于ASP MVC 文件上传 HttpPostedFileBase 为空的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 文件上传

asp.net mvc 文件跨域上传,接收返回结果

ASP.NET mvc上传多个附件

ASP.Net MVC 5 图像上传到文件夹

ASP MVC 文件上传 HttpPostedFileBase 为空

ASP.NET Core MVC(C#) 文件上传及后台输出响应Aspose.Words处理后文件