首先抱歉我的英语不好。我是ASP.NET MVC的新手,目前我正在做一些小型的" Rent-a-car"项目就可以了。
我想创建一个表单,页面管理员可以在页面上添加汽车,其中包含name
,year of production
和picture
等详细信息。在一些教程之后,我创建了一个表格来创建一个名字和生产年份的汽车,我单独制作了一个表格,管理员可以上传汽车的图片。
现在我有两个带有两个提交按钮的HTML表单,一个用于创建汽车,另一个用于上传汽车图像。我想将这两种形式合并为一个,管理员可以在其中输入汽车名称,生产年份,选择他想要上传的图片,然后用一个按钮提交所有这些。
我不知道该怎么做所以请查看下面的代码并告诉我我需要做些什么改变,我将不胜感激
这是我的车型:
public class Car
{
[Key]
public int CarID { get; set; }
public string Model { get; set; }
public int YearOfProduction { get; set; }
public string Price { get; set; }
public string Photo { get; set; }
public string AlternateText { get; set; }
[NotMapped]
public HttpPostedFileBase File { get; set; } //for image upload
}
这是" Cars"中的创建(汽车)动作方法。控制器:
[Authorize(Roles = "Administrator")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "CarID,Model,YearOfProduction")] Car car)
{
if (ModelState.IsValid)
{
db.Cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(car);
}
这是我的上传(汽车图片)行动方法在"汽车"控制器:
[HttpPost]
public ActionResult Upload(Car picture)
{
if (picture.File.ContentLength > 0)
{
var fileName = Path.GetFileName(picture.File.FileName);
var path = Path.Combine(Server.MapPath("~/Images/Cars"), fileName);
picture.File.SaveAs(path);
}
return RedirectToAction("Index");
}
这是我创建汽车的HTML表单:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Car</h4>
<hr/>
@Html.ValidationSummary(true, "", new {@class = "text-danger"})
<div class="form-group">
@Html.LabelFor(model => model.Model, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.Model, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.Model, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.YearOfProduction, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.YearOfProduction, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.YearOfProduction, "", new {@class = "text-danger"})
</div>
</div>
<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>
}
这是我上传汽车图片的HTML表单:
@using (Html.BeginForm("Upload", "Cars", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table>
<tr>
<td>File:</td>
<td><input type="file" name="File" id="File"/></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="submit" value="Upload"/></td>
</tr>
</table>
}
答案 0 :(得分:2)
您可以在<input>
标记中使用命令名称,如下所示:
@Html.BeginForm()
{
@Html.AntiForgeryToken()
<!-- Your Razor code for the input form goes here -->
<!-- Now your Upload button -->
<table>
<tr>
<td>File:</td>
<td><input type="file" name="File" id="File"/></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="commandName" value="Upload"/></td>
</tr>
</table>
<!-- Finally, your form submit button -->
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" name="commandName" value="Create" class="btn btn-default"/>
</div>
</div>
}
在你的控制器中&#39; action方法接受它作为参数。
public ActionResult Create(Car car, string commandName)
{
if(commandName.Equals("Create"))
{
// Call method to create new record...
}
else if (commandName.Equals("Upload"))
{
// Call another method to upload picture..
}
}
如果你研究,还有另一个优雅的通用解决方案,你可以在Action方法上应用多按钮属性,它会自动调用控制器动作。但是,在这种情况下你需要注意获取值(*它超出了这个问题的范围)。您可以参考:How do you handle multiple submit buttons in ASP.NET MVC Framework?
答案 1 :(得分:1)
您可以在其他表单中添加输入文件字段,并将两种操作方法的代码合并为一个。
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Car</h4>
<hr/>
@Html.ValidationSummary(true, "", new {@class = "text-danger"})
<div class="form-group">
@Html.LabelFor(model => model.Model, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.Model, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.Model, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.YearOfProduction, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.YearOfProduction, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.YearOfProduction, "", new {@class = "text-danger"})
</div>
</div>
<div>
<label>File</label>
<input type="file" name="File" id="File"/>
</div>
<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>
}
和action方法,将文件保存到磁盘并将文件名存储在db表记录中,以便以后可以检索此文件(用于查看目的)。
[Authorize(Roles = "Administrator")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Car car)
{
if (ModelState.IsValid)
{
if (car.File.ContentLength > 0)
{
var fileName = Path.GetFileName(car.File.FileName);
var path = Path.Combine(Server.MapPath("~/Images/Cars"), fileName);
picture.File.SaveAs(path);
car.Photo = fileName;
}
db.Cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(car);
}
此外,您可以考虑生成一个唯一的文件名,以便在用户为不同记录更新同名文件时,不会覆盖磁盘上的现有文件。
您可以使用此代码生成随机文件名。
var fileName = Path.GetFileName(car.File.FileName);
fileName = Path.GetFileNameWithoutExtension(fileName) +
"_" +
Guid.NewGuid().ToString().Substring(0, 4) + Path.GetExtension(fileName);
var path = Path.Combine(Server.MapPath("~/Images/Cars"), fileName);
//continue with saving
另请注意,the best way to prevent over posting is by using a view model包含您的观看所需的属性。您可以创建视图模型并使用它来将数据从视图传输到操作方法。在这种情况下,您可以完全删除属性(从实体类中用[NotMapped]
修饰)
答案 2 :(得分:0)
查看this。
看起来它可能会帮助您将两种表单(和控制器操作)合并为一个
答案 3 :(得分:0)
如果汽车尚未保存,图片将如何上传?