将HttpPostedFileBase从视图→控制器→返回到视图

本文关键字:视图 返回 控制器 HttpPostedFileBase | 更新日期: 2023-09-27 18:11:29

我的应用程序允许用户通过选择图像上传单个图像:@Html.TextBoxFor(m => m.Image, new {type = "file"})。如果有任何验证错误,我将丢失其选定的文件。因此,我需要通过If(!ModelState.IsValid)代码块临时保存它:

public ActionResult Create(MyModel model) {
    if (!ModelState.IsValid)
    {
         if(model.Image != null && model.Image.ContentLength > 0) {
         var displayName = Path.GetFileName(model.Image.FileName);
         var fileExtension = Path.GetExtension(displayName);
         var fileName = string.Format("{0}{1}", Guid.NewGuid(), fileExtension);
         var path = Path.Combine(Server.MapPath("~/App_Data/Files"), fileName);
         model.Image.SaveAs(path);
         model.displayName = displayName;
         model.FilePath = path;
         return View(model);
     }
 }

我使用@Html.HiddenFor(m => m.FilePath)在视图。

model.Image类型为HttpPostedFileBase。I 必须以某种方式重新获得用户选择的图像为!ModelState.IsValid之后的HttpPostedFileBase,以便能够将其保存在数据库中。是否有机会在@Html.TextBoxFor(m => m.Image, new {type = "file"})内传递回信息?

我后来如何将HttpPostedFileBase转换为byte[],以便在数据库中存储图像数据。

我不知道如何用我现有的工具做这件事。

Edit: model property:

public string displayName { get; set; }
public string FilePath { get; set; }
public HttpPostedFileBase Image { get; set; }

将HttpPostedFileBase从视图→控制器→返回到视图

出于安全原因,不能设置文件输入的值(只能通过用户在浏览器中选择文件来设置)。

在视图中,您将需要一个条件检查来显示文件名和路径(最初是null)

@if (Model.displayName != null)
{
    <div>@Model.displayName</div> // let the user know that its been uploaded
    @Html.HiddenFor(m => m.FilePath)
}

则在控制器中,如果ModelState有效,则需要有条件地检查FilePath的值。在您提交而ModelState无效的情况下,当用户重新提交时,FilePath的值现在将包含保存文件的路径。但是如果ModelState在初始提交时有效,那么FilePath的值将是null

您的控制器代码需要(注意,这假设MyModel实际上是一个视图模型,并且您有一个包含属性public byte[] Image { get; set; }的关联数据模型,用于将文件保存到数据库表

public ActionResult Create(MyModel model)
{
    if (!ModelState.IsValid)
    {
        .... // code as above to save temporary file and return the view
    }
    // Initialize an instance of your data model
    var dataModel = new .... // assumes this contains a property byte[] Image
    if (model.FilePath == null)
    {
        // The code above has never run so read from the HttpPostedFileBase property
        if(model.Image != null && model.Image.ContentLength > 0) {
        {
            MemoryStream target = new MemoryStream();
            model.Image.InputStream.CopyTo(target);
            dataModel.Image = target.ToArray();
        }
    }
    else
    {
        // Read from the temporary file
        dataModel.Image = System.IO.File.ReadAllBytes(filename);
        .... // Delete the temporary file
    }
    // Map other properties of your view model to the data model
    // Save and redirect
}