已经浏览了Google的前三页,但仍然无法理解这一点。我有一个控制器,我用来上传图像:
[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
}
是否有可能只为...提供某种,并且每种都显示在底部?有人知道怎么做吗!顺便说一下这是我的第一个C#MVC应用程序,所以如果这是一个愚蠢的问题我道歉。在此先感谢:)
答案 0 :(得分:2)
您应该遵循 P-R-G 模式。在您的Http P ost操作方法中成功保存数据后,您应该对 G ET操作方法执行 r 编辑,您将在读取您需要的数据并将其传递到您将显示它的视图。
我会创建一个视图模型来表示每个图像并使用
public class ProfileImageVm
{
public string FileName { set;get;}
public DateTime CreatedTime { set;get;}
}
现在,为了保存你的http post action方法,我建议你不要在表格中保存文件的物理位置。 Server.MapPath
返回物理路径。存储是不必要的。如果您决定明天将位置移动到服务器中的其他目录,该怎么办?您只需存储唯一的fileName即可。假设您要将所有文件存储在应用程序根目录中的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
,则只需要一个地方变化