ASP.. NET MVC:让视图上传图像时的视图和控制器问题



通过使用一个将HttpPostedFileBase属性绑定到视图的视图模型来解决,这样表单只需要一个post方法来上传图像,然后将实体添加到数据库。

下面是表单标签:

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

和绑定到视图模型属性的视图控件(如果名称匹配,默认情况下会发生),在我的情况下,属性是HttpPostedFileBase文件:

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

这比我在下面的路径要容易得多,试图为单个视图提供两个不同的后动作(这应该是可能的,从我读到的一切,但我认为我的问题是试图在一个表单中有一个表单):

我的controller for Lesson有两个post方法可以调用:

第一个是创建一个新的Lesson:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Lesson lesson)//, WebImage Photo)
{
if (ModelState.IsValid && Request.Form["Create"]!=null) 
//Request.Form check because the image file function is calling back to this handler
//Once that is sorted out the check can be removed and simply use ModelState.IsValid
{
db.Lessons.Add(lesson);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.DivID = new SelectList(db.Divisions, "ID", "DivName", lesson.DivID);
ViewBag.ProjectID = new SelectList(db.Projectinformations, "ID", "Code", lesson.ProjectID);
ViewBag.PeopleID = new SelectList(db.Peoples, "ID", "Firstname", lesson.PeopleID);
return View(lesson);
}

在页面上,这是带有提交按钮的表单(简称),该按钮调用控制器。create()操作:

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
//. . . for each Lesson property there is a form group with @Html Label
//@Html.EditorFor, etc. and then at the bottom is this:
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" name="Create" class="btn btn-default" />
</div>
</div>

图像路径字段是主表单的一部分,我为它的文本框等留下了生成的代码。这是表单的一部分,我试图插入一个图像上传调用不同的控制器动作:

<div class="form-group">
<div class="col-md-10">
<form action="UploadImage" name="ImageFileForm" id="imageForm" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="OK" name="OK" />
</form>
</div>
@Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Image, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
</div>
</div>

这是UploadImage

的控制器动作
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadImage(HttpPostedFileBase file)
{
string imagePath ="";
if (file != null)
{
var newFileName = Path.GetFileName(file.FileName);
imagePath = @"LessonsLearnedImages" + newFileName;
file.SaveAs(@"~" + imagePath);
}
ViewBag.DivID = new SelectList(db.Divisions, "ID", "DivName", lesson.DivID);
ViewBag.ProjectID = new SelectList(db.Projectinformations, "ID", "Code", lesson.ProjectID);
ViewBag.MOAPeopleID = new SelectList(db.MOApeoples, "ID", "Firstname", lesson.MOAPeopleID);
ViewBag.Image = imagePath;
return View();
}

当我按下ImageUpload按钮,然而,控制器创建(表单默认)函数被调用。我可能会使用控制器中的Create操作来处理Request中的所有事情。表单检查,但这已经失败了,当我添加一个HttpPostedFileBase参数给它。

对于图片上传,有两件事需要保存。第一部分是保存实际图像,例如。保存到计算机上的文件夹中。第二部分是保存有关图像的信息。将其完整路径保存在数据库中。完成这两部分是必要的,这样您就可以稍后检索图像。

捕获图像(或上传文件)的一种方法是使用HttpPostedFileBase作为参数类型:

[HttpPost]
public async Task<ActionResult> Upload(HttpPostedFileBase myFile)
{
// myFile contains several properties which you need to be able to save the file
}

myFile参数有几个需要保存的属性。例如,您上传图像的路径和您可以提取为byte[]的实际图像内容。

网页上相应的形式,删减到必要的部分,将是:

<form action="Upload" method="post" enctype="multipart/form-data">
<input type="file" name="myFile" />
<input type="submit" value="Click me to upload" />
</form>

您需要确保以下行,以便调用正确的控制器动作:

  • 表单的方法应该匹配控制器方法的动词(表单中的post对应于控制器中的HttpPost)
  • 表单的动作应该匹配控制器方法的名称(在本例中为Upload)
  • 输入的名称应该与控制器方法的参数(本例中为myFile)的名称相匹配

您还需要确保enctype是multipart/form-data,以便myFile参数实际具有值。如果不是,可以执行正确的控制器方法,但参数可能为空。

在所有这些之后,您应该有一个合适的myFile参数,您可以使用其属性来保存。例如,在保存图像之后,您可以将其完整路径存储在Lessons表的ImagePath列中。

正如您所提到的,一旦控制器方法完成执行,图像(以及与此相关的任何其他内容)就会丢失。但这没关系,因为我们已经在持久存储中保存了图像和图像路径。要在以后检索图像,您可以查看相关的课程。例如,假设您有一个Model对象,对应于您从数据库中获得的课程,则显示图像可能如下所示:

<img src="@Model.ImagePath" />

编辑

似乎你想在创建页面上保存多个字段,而图像文件只是其中一个字段。在这种情况下,控制器上只需要一个方法,页面上只需要一个表单元素。

要捕获文件,将HttpPostedFileBase添加为课程视图模型中的属性,例如:

public class Lesson
{
public HttpPostedFileBase File { get; set; }
}

最新更新