【问题标题】:ASP.NET MVC validating modelASP.NET MVC 验证模型
【发布时间】:2015-02-03 07:53:01
【问题描述】:

我在验证表单时遇到了一些困难。

由于我想从数据库中填充组合框(另一个表,我正在使用视图包来执行此操作),有没有办法在这种情况下使用 ComboBoxFor,所以我可以使用 System.ComponentModel.DataAnnotations 和 jquery.validate.js ?

查看:

@model MyProject.OpenAccess.Document
@using (Html.BeginForm("CreateDocument", "Create", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
  <label>Select file:</label><br />
  <input type="file" name="file" /><br />
  <label>Filetype</label><br />
  @Html.DropDownList("fileType", (IEnumerable<SelectListItem>)ViewBag.ListFiletypes, "-Filetypes", new { @class = "filetype-cb" }) <br />
  <input type="submit" value="Add"/>
}

控制器:

public ActionResult CreateDocument(HttpPostedFileBase file, string fileType)
{
  if (file != null && file.ContentLength > 0)
  {
    Document doc = new Document()
    {
      Filetype = fileType
    }
    if (this.TryValidateModel(doc))
    {
      this.dbContext.Add(doc);
      this.dbContext.SaveChanges();
      id = doc.ID;
      //save document using document ID
    }
  }
}

编辑:

这是我目前的实现:

Layout.cshtml

记得添加:

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

查看

@model MyProject.OpenAccess.Document
@using (Html.BeginForm("CreateDocument", "Create", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <label>Select file:</label><br />
    <input type="file" data-val="true" data-val-required="Please select a file!" name="file" /><br />
    <label>Filetype</label><br />
    @Html.DropDownListFor(m => m.FileType, (IEnumerable<SelectListItem>)ViewBag.ListFiletypes, "", new { @class = "filetype-cb" })
    <input type="submit" value="Add"/>
}

控制器

[HttpGet]

public ActionResult CreateDocument()
{
    ViewBag.ListFiletypes = new SelectList(this.dbContext.ListFiletypes.ToList(), "FileType", "FileType");
    //Populate dropdownlist from database
}

[HttpPost]

 public ActionResult CreateDocument(HttpPostedFileBase file, Document doc)
 {
    if (file != null && file.ContentLength > 0)
    {
        if (this.TryValidateModel(doc))
        {
            this.dbContext.Add(doc);
            this.dbContext.SaveChanges();
            id = doc.ID;
            //save document using document ID
        }
    }
}

型号

public partial class Document
{
    private int _iD;
    public virtual int ID
    {
        get
        {
            return this._iD;
        }
        set
        {
            this._iD = value;
        }
    }

    private string _fileType;
    [Required(ErrorMessage = "Required!")]
    public virtual string FileType
    {
        get
        {
            return this._fileType;
        }
        set
        {
            this._fileType = value;
        }
    }
}

是否有充分的理由使用 Viewmodel 而不是 Viewbag 来填充 DropDownListFors(从 http://www.codeproject.com/Articles/687061/Multiple-Models-in-a-View-in-ASP-NET-MVC-MVC 找到)?

此实现的唯一问题是我无法在客户端验证文件(因此用户无法发布空文件)。

编辑:只需添加:

  <input type="file" data-val="true" data-val-required="Please select a file!" name="file" />

【问题讨论】:

  • 如果您没有模型并将验证属性添加到模型的属性中,那么您将无法获得开箱即用的验证。既然你在视图中声明了@model Document,那么Document需要有一个属性fileType,或者使用视图模型来显示和编辑你想要的东西
  • 您在寻找@Html.DropDownListFor 吗?您可以将其与模型的属性一起使用,然后使用数据注释对其进行验证。
  • @Stephen,我为模型属性分配了验证属性。
  • @Muthu,是的,我的意思是 DropDownListFor,但我遇到了一个问题:如何从 Viewbag 填充 DropDownListFor?
  • 您需要发布您的模型。如果您有一个名为fileType 的属性,则应该没有问题。

标签: c# asp.net-mvc validation


【解决方案1】:

通常您有 3 个不同的部分,用于构建您的场景的正确实现。

视图模型:

在正确的实现中,每个视图都有自己的视图模型。在你的情况下,这将是这样的:

public class CreateDocumentViewModel
{
    [Required]
    public IEnumerable<SelectListItem> filetypes { get; set; }
    // Maybe some more attributes you need in the view?
}

注意:这里你可以使用你想要的DataAnnotations。

视图:

视图包含下拉列表中的实际数据。

@model CreateDocumentViewModel
@using (Html.BeginForm("CreateDocument", "Create", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
     <label>Select file:</label><br />
     <input type="file" name="file" /><br />
     <label>Filetype</label><br />
     @Html.DropDownListFor(model => model.filetypes, model.filetypes, "-Filetypes", new { @class = "filetype-cb" })
     <br />
     <input type="submit" value="Add"/>
}

控制器:

您需要的控制器有 2 个动作。 GET 和 POST 操作。

[HttpGet]       
public ActionResult CreateDocument()
{
    CreateDocumentViewModel model = new CreateDocumentViewModel();
    model.filetypes = FillFileTypesFromDB; // Here you fill the data for the dropdown!
    return View(model);    
}

最后,您需要将 POST 操作保存回您的数据库。

[HttpPost]
public ActionResult CreateDocument(HttpPostedFileBase file, string fileType)
{
  if (file != null && file.ContentLength > 0)
  {
    Document doc = new Document()
    {
      Filetype = fileType
    }
    if (this.TryValidateModel(doc))
    {
      this.dbContext.Add(doc);
      this.dbContext.SaveChanges();
      id = doc.ID;
      //save document using document ID
    }
  }
}

我希望我完全理解了您的问题,并有助于解决它。

【讨论】:

  • 感谢您的清晰示例。所以我应该在同一个视图模型中包含我的模型(MyProject.OpenAccess.Document)和那些下拉列表?在您的示例中,您似乎正在验证文件类型集合(DropDownList 数据)而不是在您发回表单时进行验证,我错了吗?
  • 是的,就是这样。一旦您发布表单,视图模型中的数据注释就会被验证。例如,如果您有一个视图模型和一个内部用“必需”装饰的属性“密码”,则在您填写视图中的密码字段之前,您无法发布表单。
猜你喜欢
  • 2015-02-26
  • 2011-12-24
  • 1970-01-01
  • 2010-11-18
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多