C# ASP MVC 文件上传 HttpPostedFileBase 为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10856240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:33:08  来源:igfitidea点击:

ASP MVC FIle Upload HttpPostedFileBase is Null

c#asp.net-mvcrazoruploadhttppostedfilebase

提问by Matthew Arkin

In my controller I have, because I wanted to be able to fill out some details about the video and actually upload it, the Video class doesn't need the actual video because it's going to be passed to another web service.

在我的控制器中,因为我希望能够填写有关视频的一些详细信息并实际上传它,所以 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);
    }

and in my view I have

在我看来我有

@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>

}

}

When I submit the form the videoModel part of VM is filled out but vid the actual file is null. Any ideas?

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

采纳答案by CD Smith

Update according to OP comment

根据OP评论更新

set the Max file length in the web.config file Change the "?" to a file size that you want to be your max, for example 65536 is 64MB

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

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

You can't add the file to the model, it will be in it's own field not part of the model

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

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

Your action is incorrect. It needs to accept the file as it's own parameter (or if multiple use IEnumerable<HttpPostedFileBase>as the parameter type)

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

[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);
}

If you were allowing multiple files to be selected you have to allow for that

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

[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);
}

回答by Jason Kulatunga

change

改变

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

to

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

depending on what else is on your page, and where the view is being rendered, the MVC will generate unique ID's, I think your hard coded ID is not correctly associated with the form fields.

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

回答by Buildstarted

The reason it isn't binding is because the model binder only looks at QueryString, Form, and RouteDatawhen binding a complex model such as yours. The way to get around this is to have another parameter in your action method. (change your "name" to just "vid" as well)

它不具约束力的原因是因为模型绑定只着眼于QueryStringFormRouteData绑定一个复杂的模型,如你的时候。解决这个问题的方法是在你的 action 方法中有另一个参数。(将您的“名称”也更改为“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);
}

回答by AZIP

Works for me:

对我有用:

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

Controller:

控制器:

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

View:

看法:

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

I think solution placed there: Model.File~ <input name="File"/>

我认为解决方案放在那里:Model.File<input name="File"/>