嗨,我有一个像这样的控制器:
public class MyController : Controller
{
public MyController(Uow uow)
{
;
}
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
var validationResults = _uow.GetResults(file.FileName, file.InputStream);
return View(new MyViewModel { Errors = validationResults.Errors, Data = validationResults.Data });
}
[HttpPost]
public void Save(MyViewModel viewModel)
{
//Save the data
}
}
这有一个类似的观点:
@model MyViewModel
<form action="" method="post" enctype="multipart/form-data">
<label for="file" id="filelabel">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" id="submitbtn" disabled="disabled" />
<img class="loader" id="loader" style="display: none;" alt="Loading..." src="@Url.Content("~/Content/Images/ajax-loader.gif")" />
@if (Model != null && Model.Errors.Any())
{
foreach (var error in Model.Errors)
{
<span class="error">@error</span>
}
}
<button id="savebtn" >Save</button>
</form>
<script type="text/javascript">
$(document).ready(function () {
$('#file').change(function () {
alert("in here");
$('#submitbtn').prop('disabled', false);
});
$('#submitbtn').click(function () {
$('#loader').show();
});
});
</script>
所以我在这里尝试的是将文件上传到控制器的方法。我已经实现了这一点,并且我在Index Post中收到了它。然后我处理这个工作正常。然后我将相关数据放在viewModel中并重新显示表单。
我想要的是当按下Save按钮时,使用填充的viewModel调用Save Post方法。然而,每当我按下按钮时,它都会发布到Index Post,这是有道理的。
有人可以告诉我如何保留我的文件上传和处理代码,但是当我稍后按下Save按钮时,viewModel会被发送到Save Post方法吗?
答案 0 :(得分:0)
如果您必须将这些操作分开并且不要更改当前的表单,那么您需要一个单独的表单才能异步发布或不发布到其他操作...这意味着做一些令人讨厌的事情,比如更新另一个中的隐藏字段每当对第一个表单进行更改时使用javascript进行表单...由于表单字段可以在不触发某些javascript事件的情况下进行更改的多种方式,因此不是万无一失的。
当单击保存按钮时,还可以使用javascript更改表单操作..但说实话,这对我来说似乎太脏了,我会使用viewmodel来实现1动作。
我建议您在视图模型上使用HttpPostedFileBase
并让Index操作处理验证和保存数据。
有关强类型表单助手和注释的详细信息,请参阅此示例:how to validate input file with jquery and dataannotation in asp.net mvc 3
它显示HttpPostedFileBase
属性DataAnnotations
,您可能想尝试编写一个自定义注释,如果您需要以这种方式验证它,则会调用您的UOW ..但不确定为什么呢?
我也建议使用Model.ValidationMessageFor()帮助器。
接收视图模型的操作的一般模式如下所示:
[HttpPost]
public ActionResult Index(MyViewModel myViewModel)
{
try
{
// Check your viewmodel is valid
if (!ModelState.IsValid)
{
// not valid so return to the view with the view model as a param
// The validation message helpers will display the relevant error messages
return View(myViewModel);
}
// modelstate is valid so perform any work i.e. save to database
// attach any additional information to the view modal to give feedback maybe?
// or redirect the user to some other page
return View(myViewModel);
}
catch
{
// any exceptions then go back to the view and hopefully the validation helpers will kick in
return View(myViewModel);
}
}
就个人而言,我会做这类事情,但你可以得到这个想法:
在视图模型中
[DisplayName("Update your image")]
[Required]
public HttpPostedFileBase Image { get; set; }
public string ImageName { get; set; }
在视图中
@if (Model.ImageName != null) {
<img src="@Url.Content("~/uploads/" + Model.ImageName)" alt="" />
}
<div class="control-group">
@Html.LabelFor(model => model.Image)
<div class="controls">
@Html.TextBoxFor(model => model.Image, new { @type = "file", @class = "input-file" })
@Html.ValidationMessageFor(model => model.Image)
</div>
</div>
在控制器发布操作中,检查ModelState.IsValid
var fileName = "";
// check for a posted file and that it has a size to it before attempting to save the file
if (myViewModel.Image != null && myViewModel.Image.ContentLength > 0)
{
var currentDate = DateTime.UtcNow.ToString("yyyymmddhhmmss");
var fileType = Path.GetExtension(myViewModel.Image.FileName);
Random random = new Random();
fileName = Path.GetFileNameWithoutExtension(myViewModel.Image.FileName) + "-" + currentDate + random.Next(1, 10000) + fileType;
// upload the file
var path = Path.Combine(Server.MapPath("~/uploads"), fileName);
myViewModel.Image.SaveAs(path);
}
// for saving to the database on an model entity
if (fileName != "")
{
entity.ImageName = fileName;
}