【问题标题】:Display a collection of images after each upload MVC每次上传MVC后显示一组图片
【发布时间】:2017-11-24 22:03:59
【问题描述】:

浏览了 Google 的前 3 页,但仍然无法深入了解。我有一个控制器用来上传图片:

[HttpPost]
    [Authorize(Roles = "Admin,Tradesman,Customer")]
    public ActionResult UploadFile(HttpPostedFileBase file)
    {
        // to do: ensure only valid file types are sent
        try
        {
            if (file.ContentLength > 0)
            {
                using (var ctx = new ApplicationDbContext())
                {
                    if (ModelState.IsValid)
                    {
                        // Need to check we have a current UserId and JobId before we go any furthur
                        var profileData = Session["UserProfile"] as UserProfileSessionData;

                        if (profileData.JobIdGuid.ToString().Length != 36)
                        {
                            // to do: something went horribly wrong! Redirect back to main view
                        }

                        if (profileData.UserIdGuid.ToString().Length != 36)
                        {
                            // to do: something went horribly wrong! Redirect back to main view
                        }

                        var photo = new Photos();

                        photo.Guid = Guid.NewGuid();
                        photo.Url = Server.MapPath("~/Images/2017");
                        photo.Extension = Path.GetExtension(file.FileName);
                        photo.JobGuid = profileData.JobIdGuid;
                        photo.UserIdGuid = profileData.UserIdGuid;
                        photo.Timestamp = DateTime.Now;

                        ctx.Photo.Add(photo);
                        ctx.SaveChanges();

                        string _path = Path.Combine(photo.Url, photo.Guid.ToString() + photo.Extension);
                        file.SaveAs(_path);
                    }
                }         
            }
            ViewBag.Message = "File Uploaded Successfully.";
            return View();
        }
        catch
        {
            ViewBag.Message = "File upload failed.";
            return View();
        }
    }

每张图片都保存到给定的位置,保存到db的位置,快乐的日子。我想要的是让我的图像在每次上传后显示在同一页面上。该模型与您期望的一样,只是 Id、Guid、Url、Extension、UserId、Timestamp。

这是上传图片的视图:

@{
ViewBag.Title = "UploadFile";
}

<h2>Upload File</h2>

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

<div>
    @Html.TextBox("file", "", new { type = "file" }) 

    <br />

    <input type="submit" value="Next" />

    @ViewBag.Message
</div>  

// to do display the images uploaded
}

是否可以只使用某种 for...each 并将每个都显示在底部?有人知道怎么做吗!顺便说一句,这是我的第一个 C# MVC 应用程序,所以如果这是一个愚蠢的问题,我深表歉意。在此先感谢:)

【问题讨论】:

  • 您应该重定向到 GET 操作,您将在其中读取数据并显示在您的视图中。遵循 PRG 模式。

标签: c# asp.net-mvc entity-framework image-processing asp.net-mvc-5


【解决方案1】:

您应该遵循 P-R-G 模式。在您的 HttpPost 操作方法中成功保存数据后,您应该r重定向到您的 GET 操作方法,您将在其中读取您需要的数据并将其传递给您将显示它的视图。

我会创建一个视图模型来表示每个图像并使用它

public class ProfileImageVm
{
   public string FileName { set;get;}
   public DateTime CreatedTime { set;get;}
}

现在,对于您的 http post 操作方法中的保存部分,我建议您不要将文件的物理位置保存在表中。 Server.MapPath 返回物理路径。存储是不必要的。如果您决定明天将该位置移动到服务器中的某个其他目录怎么办?您可以简单地存储唯一的文件名。假设您要将所有文件存储在应用程序根目录下的Images/2017 中,您可以使用Server.MapPath 获取物理位置,以便将文件存储在磁盘中,但不要使用它来存储表记录.

var fileName = Path.GetFileNameWithoutExtension(file.FileName);       
photo.Url = fileName ;
photo.Extension = Path.GetExtension(file.FileName);

使用此代码,它只是按原样存储文件名(不带扩展名),而不是唯一的名称。这意味着,如果您要上传第二个同名文件,它将覆盖磁盘中的第一个文件。如果要生成唯一的文件名,请使用此 post 中的 GetUniqueName 方法。

现在在 GET 操作方法中,您读取 Photos 集合并从中创建我们的视图模型列表。

public ActionResult UploadFile()
{
   var list= ctx.Photos
                .Select(x=>new ProfileImageVm { FileName=x.Url + x.Extension ,
                                                CreatedTime = x.Timestamp })
                .ToList();
   return View(list);
}

现在在您的 UploadFile 视图中将强类型化到 ProfileImageVm 列表,您可以循环遍历模型数据并渲染图像。

@model List<ProfileImageVm>
@using (Html.BeginForm("UploadFile", "Job", FormMethod.Post, 
                                            new { enctype = "multipart/form-data" }))
{

    @Html.TextBox("file", "", new { type = "file" }) 
    <input type="submit" value="Next" />
}
<h3>Images</h3>
@foreach(var item in Model)
{
   <img src="~/Images/2017/@item.FileName" />
   <p>Uploaded at @item.CreatedTime </p>
}

现在,在成功保存照片和表格中的记录后,您将返回一个重定向响应到 GET 操作。

file.SaveAs(_path);
return RedirectToAction("Upload","Job");

您还可以将基本路径 ~/Images/2017 保留在配置设置/常量中,并在您的应用中使用它,因此如果您决定将其更改为 ~/Images/profilepics,则只需更改一个位置。

【讨论】:

  • 非常感谢您的回复,我有一个 public ActionResult UploadFile() { return View(); } 仅用于返回视图,我是将其更改为 public ActionResult UploadFile() 上面的方法还是创建另一个单独的方法?
  • 是的。你将用我上面写的替换你现有的方法
  • Cool 已经改变了那个 ty,目前它在这一行 @foreach(模型中的 var 项)处跌倒了,在我的页面加载之前,模型为空。我错过了什么吗?一切正常..
  • 您确定将list 传递给 View 方法,正如我在呈现该视图的 GET 操作方法的答案中解释的那样吗?
  • 现在似乎可以工作了,再次感谢 :) :) :),我在它循环我的图像之前添加了这个 @if (Model != null)。回到您不记录完整网址的观点,这是出于安全考虑,因为现在我可以看到,如果我记录了这一点,那么我最终可能会在页面源上显示完整的网址?
猜你喜欢
  • 1970-01-01
  • 2018-11-12
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 2013-03-28
  • 2014-03-22
  • 1970-01-01
相关资源
最近更新 更多