在ASP.NET MVC4中上传和保存文件

时间:2015-10-12 00:04:58

标签: asp.net-mvc asp.net-mvc-4

我有一个文件字段,用于上传图像,同时保存数据库中的文件路径。我遵循了这个sample tutorial并调整了我的代码。以下是我的模特

using System;
using System.Web;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BOL
{
    public class TeamValidation
    {
        [Key]
        public int teamID { get; set; }

        [Required(ErrorMessage = "Please Enter Your Team Name")]
        [Display(Name = "Team Name")]
        public string teamName { get; set; }      

        [DisplayName("Team Picture")]
        [Required(ErrorMessage = "Please Upload Team Picture")]
        [ValidateFile]
        public HttpPostedFileBase teamPicture { get; set; }
        //public string teamPicture { get; set; }

        [Required]
        [Display(Name = "Description")]
        public string description { get; set; }

        //[AllowHtml]
        [Required(ErrorMessage = "Please Enter Team Content")]        
        [Display(Name = "Content")]
        [MaxLength(200)]
        public string content { get; set; }
    }

    //Customized data annotation validator for uploading file
    public class ValidateFileAttribute : ValidationAttribute
    {
        public override bool IsValid(object value)
        {
             int MaxContentLength = 1024 * 1024 * 3; //3 MB
             string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png" };

             var file = value as HttpPostedFileBase;

             if (file == null)
                return false;
             else if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
             {
                 ErrorMessage = "Please upload Your Photo of type: " + string.Join(", ", AllowedFileExtensions);
                 return false;
             }
             else if (file.ContentLength > MaxContentLength)
             {
                 ErrorMessage = "Your Photo is too large, maximum allowed size is : " + (MaxContentLength / 1024).ToString() + "MB";
                 return false;
             }
             else
                return true;
        }
    }

    [MetadataType(typeof(TeamValidation))]
    public partial class team
    {
        [Key]
        public int teamID { get; set; }

        public string teamName { get; set; }

        public string teamPicture { get; set; }

        public string description { get; set; }

        public string content { get; set; } 
    }
}

这是控制器

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BOL;

namespace TeamBuildingCompetition.Areas.Admin.Controllers
{
    public class TeamController : BaseAdminController
    {
        // GET: Admin/Team
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult teamView()
        {
            var teamList = objBs.teamBs.GetALL();
            return View(teamList);
        }

        [HttpPost]
        public ActionResult Create(team objTeam)
        {

            try
            {
                if (ModelState.IsValid)
                {
                    var fileName = Path.GetFileName(objTeam.teamPicture.FileName);
                    var path = Path.Combine(Server.MapPath("~/Content/Upload"), fileName);
                    objTeam.teamPicture.SaveAs(path);

                    TempData["Msg"] = "Created Successfully!";
                    objBs.teamBs.Insert(objTeam);
                    return RedirectToAction("Index");
                }
                else
                {
                    return View("Index");
                }
            }
            catch (Exception e1)
            {
                TempData["Msg"] = "Create Failed! :" + e1.Message;
                return RedirectToAction("Index");
            }
        }

    }
}

我在下面的剪辑中有错误,因此我无法运行该文件。下面是来自控制器的错误的错误线:

enter image description here

以及模型中的波浪线如下所示:

enter image description here

悬停在Squiggly线上时,我遇到了这个错误

TeamValidation.cs 错误是HttpPostedFileBase的生成类

虽然TeamController上的波浪线为.FileName的错误 '串'不包含' FileName'的定义并且没有扩展方法' FileName'接受类型'字符串'

的第一个争论

2 个答案:

答案 0 :(得分:2)

您的问题是在类[MetadataType]上使用部分类和team属性。您的数据模型具有属性string teamPicture,并且您的元数据类具有冲突的属性HttpPostedFileBase teamPicture。您的控制器方法具有参数team objTeam,因此objTeam.teamPicture.FileName会引发错误,因为teamPicturestring的类型。要解决此问题,请从数据模型中删除[MetadataType]属性,并使用视图模型表示要在视图中编辑的内容

数据模型(在命名空间BOL中)

public class team
{
    [Key]
    public int teamID { get; set; }
    public string teamName { get; set; }
    public string teamPicture { get; set; }
    public string description { get; set; }
    public string content { get; set; } 
}

然后在项目中为视图模型创建一个新文件夹(例如ViewModels)。请注意,由于视图是用于创建新团队,因此不应要求teamID

public class TeamVM
{
    [Required(ErrorMessage = "Please Enter Your Team Name")]
    [Display(Name = "Team Name")]
    public string TeamName { get; set; }      
    [DisplayName("Team Picture")]
    [Required(ErrorMessage = "Please Upload Team Picture")]
    [ValidateFile]
    public HttpPostedFileBase TeamPicture { get; set; }
    [Required]
    [Display(Name = "Description")]
    public string Description { get; set; }
    [Required(ErrorMessage = "Please Enter Team Content")]        
    [Display(Name = "Content")]
    [MaxLength(200)]
    public string Content { get; set; }
}

您的GET方法应初始化并返回TeamVM

的实例
[HttpGet]
public ActionResult Create()
{
  TeamVM model = new TeamVM();
  return View(model);
}

,视图将为@model yourAssembly.TeamVM

然后POST方法将

[HttpPost]
public ActionResult Create(TeamVM model)
{
  ....
  var fileName = Path.GetFileName(model.TeamPicture.FileName);
  var path = Path.Combine(Server.MapPath("~/Content/Upload"), fileName);
  model.TeamPicture.SaveAs(path);
  // map the view model to a new instance of the data model
  team objTeam = new team
  {
    teamName = model.TeamName,
    teamPicture = path,
    description = model.Description,
    content = model.Content
  };
  // save and redirect
  objBs.teamBs.Insert(objTeam);
  ....
}

答案 1 :(得分:1)

您使用MetadataTypeAttribute,在文档中是:

然后将元数据类型定义为普通类,除了为要应用验证属性的每个成员声明简单属性。

文档示例:

   * {
   margin: 0px;
   padding: 0px;
 }
 .header_wrap {
   width: 100%;
   height: 160px;
   background: red;
   position: relative;
 }
 .main_wrap {
   width: 100%;
   height: 1475px;
   background: green;
 }
 .footer_wrap {
   width: 100%;
   height: 325px;
   background: aqua;
 }
 .main {
   width: 1000px;
   height: 100%;
   background: blue;
   margin: auto;
   position:relative;
   top:-200px;
   z-index:10;
 }
 footer {
   width: 1000px;
   height: 100%;
   background: aqua;
   margin: auto;
 }
 .header_top_wrap {
   width: 100%;
   height: 23px;
   background: #ccc;
 }
 .header_bottom_wrap {
   width: 100%;
   height: 40px;
   background: #06F;
   position: absolute;
   bottom: 0px;
   left: 0px;
 }
 .header_top {
   width: 1000px;
   height: 100%;
   background: purple;
   margin: auto;
 }
 .header_bottom {
   width: 175px;
   /*height: 100%;
   margin: auto;*/
   background: black;
   z-index:1;
 }
 .bottom_menu {
     width:150px; 
 }
 .bottom_menu > li {
   /*display: inline-block;*/
 }
 .bottom_menu a
 {
     font-family: Impact, Haettenschweiler, "Franklin Gothic Bold", "Arial Black", sans-serif;
     color: #fff;

 }
 .bottom_menu > li >a {
   display: block;
   text-decoration: none;
   padding: 0;
   height: 40px;
   line-height: 35px;
   text-align: center;
   width:150px;
 }
.bottom_menu > li:hover >a
{
    background:#fff;
    color:#151716;
    width:170px;
}
.submenu  a:active, .submenu  a:visited{
  display: block;
  color: #fff;
  text-decoration: none;
  z-index: 21;
}
.submenu {
  position: absolute;
  margin-left:160px;
  display: none;
  width:auto;
  height:auto;
  background:white;
  list-style:none;
  z-index:100;
  margin-top:-40px;
}
.dropdown:hover > .submenu{
  display: block;

}
.submenu>li>a
{
    display:block;
    width:100%;
    height:42px;
    background:black;
    text-decoration:none;
    line-height:58px;
    padding-left:20px;
    border:1px dashed white;
}

然后你的班级团队应该是这样的:

[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
  ... Existing members defined here, but without attributes or annotations ...
}