C# 每次上传MVC后显示一组图像
已经浏览了谷歌的前3页,但仍然无法了解这一点。我有一个用于上传图像的控制器:C# 每次上传MVC后显示一组图像,c#,asp.net-mvc,entity-framework,image-processing,asp.net-mvc-5,C#,Asp.net Mvc,Entity Framework,Image Processing,Asp.net Mvc 5,已经浏览了谷歌的前3页,但仍然无法了解这一点。我有一个用于上传图像的控制器: [HttpPost] [Authorize(Roles = "Admin,Tradesman,Customer")] public ActionResult UploadFile(HttpPostedFileBase file) { // to do: ensure only valid file types are sent try {
[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、扩展名、UserId和时间戳
以下是上载图像的视图:
@{
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
}
@{
ViewBag.Title=“上传文件”;
}
上载文件
@使用(Html.BeginForm(“UploadFile”,“Job”,FormMethod.Post,new{enctype=“multipart/formdata”}))
{
@TextBox(“文件“,”,新的{type=“文件”})
@查看包。留言
//要显示上载的图像,请执行以下操作:
}
是否有可能只为每个…设置一些类型,并在底部显示每个?任何人都知道怎么做!顺便说一句,这是我的第一个C#MVC应用程序,如果这是一个愚蠢的问题,我道歉。提前感谢:)您应该遵循p-R-G模式。在HttpPost操作方法中成功保存数据后,您应该执行redirect到GET操作方法,在该方法中,您将读取所需的数据并将其传递到要显示它的视图 我将创建一个视图模型来表示每个图像并使用它
public class ProfileImageVm
{
public string FileName { set;get;}
public DateTime CreatedTime { set;get;}
}
现在,对于http post操作方法中的save部分,我建议您不要将文件的物理位置保存在表中。Server.MapPath
返回物理路径。这是不必要的。如果您决定明天将该位置移动到服务器中的其他目录,该怎么办?您可以简单地存储唯一的文件名。假设您要在app root中存储Images/2017
中的所有文件,可以使用Server.MapPath
获取物理位置,以便将文件存储在磁盘中,但不要使用该位置存储表记录
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
photo.Url = fileName ;
photo.Extension = Path.GetExtension(file.FileName);
使用这段代码,它只是按原样存储文件名(不带扩展名),而不是唯一的名称。这意味着,如果您正在上载同名的第二个文件,它将覆盖磁盘中的第一个文件。如果要生成唯一的文件名,请从此文件名使用GetUniqueName
方法
现在,在GetAction方法中,您阅读照片集合并从中创建视图模型的列表
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>
}
您还可以在配置设置/常量中保留基本路径
~/Images/2017
,并在整个应用程序中使用该路径,因此如果您决定将其更改为~/Images/profilepics
,您只需更改一个位置。您应该遵循p-R-G模式。在HttpPost操作方法中成功保存数据后,您应该执行redirect到GET操作方法,在该方法中,您将读取所需的数据并将其传递到要显示它的视图
我将创建一个视图模型来表示每个图像并使用它
public class ProfileImageVm
{
public string FileName { set;get;}
public DateTime CreatedTime { set;get;}
}
现在,对于http post操作方法中的save部分,我建议您不要将文件的物理位置保存在表中。Server.MapPath
返回物理路径。这是不必要的。如果您决定明天将该位置移动到服务器中的其他目录,该怎么办?您可以简单地存储唯一的文件名。假设您要在app root中存储Images/2017
中的所有文件,可以使用Server.MapPath
获取物理位置,以便将文件存储在磁盘中,但不要使用该位置存储表记录
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
photo.Url = fileName ;
photo.Extension = Path.GetExtension(file.FileName);
使用这段代码,它只是按原样存储文件名(不带扩展名),而不是唯一的名称。这意味着,如果您正在上载同名的第二个文件,它将覆盖磁盘中的第一个文件。如果要生成唯一的文件名,请从此文件名使用GetUniqueName
方法
现在,在GetAction方法中,您阅读照片集合并从中创建视图模型的列表
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>
}
您还可以在配置设置/常量中保留基本路径
~/Images/2017
,并在整个应用程序中使用该路径,因此如果您决定将其更改为~/Images/profilepics
,您只需更改一个位置。您应该重定向到GET操作,在该操作中读取数据并在视图中显示。遵循PRG模式。您应该重定向到GET操作,在那里您将读取数据并在视图中显示。遵循PRG模式。非常感谢您的回答,我有一个公共ActionResult UploadFile(){return View();}用于仅返回视图,我是将其更改为公共ActionResult UploadFile()上方的方法还是创建另一个单独的方法?是的。您将用我上面写的方法替换您现有的方法。如果您已经更改了ty,那么在@foreach(模型中的var项)这一行中,当前它已经崩溃了,在我的页面加载之前,模型是空的。我错过什么了吗?它构建一切正常..你确定你正在将list
传递给视图方法吗?正如我在呈现该视图的GET action方法的答案中所解释的那样?现在似乎可以工作了,再次感谢:):),我在循环我的图像之前添加了这个@if(Model!=null)。回到你关于不记录完整url的观点,这是因为安全问题吗?现在我可以看到,如果我记录了,那么我可能会在页面上显示完整url源代码?非常感谢你的回答,我有一个公共ActionResult UploadFile(){return View();}这是u