我正在ASP.NET MVC中创建我的第一个站点,这是一种学习的方式.但我遇到了一个我无法找到解决方案的问题.
我希望我的用户能够创建附有歌曲和标签的专辑.
这可能是一个未指定数量的歌曲和标签.但必须至少有5首歌曲和2个标签.
但我无法弄清楚如何通过模型实现这一目标,这是我能够走多远.
public class AlbumCreateModel { [required] [DisplayName("Title")] public string Title { get; set; } [DisplayName("Description")] public string Description { get; set; } [DisplayName("Publish")] public bool Public { get; set; } [DisplayName("Tags")] // Min 2 tags no max public List<AlbumTagModel> Tags { get; set; } [DisplayName("Songs")] // Min 5 songs no max public List<AlbumSongModel> Songs { get; set; } } public class AlbumTagModel { [required] [DisplayName("Tag")] // Regex to test no spaces // min 2 characters // maximum 15 characters public string Tag { get; set; } } public class AlbumSongModel { [required] [DisplayName("Title")] public string Title { get; set; } [required] [DisplayName("Artist")] public string Artist { get; set; } [DisplayName("Description")] public string Description { get; set; } [DisplayName("Song Length")] public double Length { get; set; } [DisplayName("Year")] public int Description { get; set; } }
视图:
<%@ Page Title="" Language="C#" MasterPageFile="~/App/Views/Shared/MasterPage.Master" Inherits="System.Web.Mvc.ViewPage<album.App.Models.AlbumCreateModel>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Create </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <% using (Html.BeginForm()) { %> <%: Html.ValidationSummary(true,"Committing the album was unsuccessful. Please correct the errors and try again.")%> <div> <fieldset> <legend>Album Information</legend> <div class="editor-label"> <%: Html.LabelFor(m => m.Title) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Title)%> <%: Html.ValidationMessageFor(m => m.Title)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Description) %> </div> <div class="editor-field"> <%: Html.TextAreaFor(m => m.Description)%> <%: Html.ValidationMessageFor(m => m.Description)%> </div> <!-- Tags here --> <!-- Songs here --> <p> <input type="submit" value="Commit" /> </p> </fieldset> </div> <% } %> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="MetaData" runat="server"> </asp:Content>
可能的解决方案:
模型:
public class PlaylistModel { [required] [DisplayName("Title")] public string Title { get; set; } [DisplayName("Description")] public string Description { get; set; } [DisplayName("Publish")] public bool Public { get; set; } [DisplayName("Tags")] [ListCount(Min = 2)] // Min 2 tags no max public List<PlaylistTagModel> Tags { get; set; } [DisplayName("Songs")] [ListCount(Min = 5)] public List<PlaylistSongModel> Songs { get; set; } } public class PlaylistTagModel { [required] [DisplayName("Tag")] // Regex to test no spaces // min 2 characters // maximum 15 characters public string Tag { get; set; } } public class PlaylistSongModel { [required] [DisplayName("Title")] public string Title { get; set; } [required] [DisplayName("Artist")] public string Artist { get; set; } [DisplayName("Description")] public string Description { get; set; } [DisplayName("Song Length")] public int Length { get; set; } [DisplayName("Year")] public int Year { get; set; } }
视图:
<%@ Page Title="" Language="C#" MasterPageFile="~/App/Views/Shared/MasterPage.Master" Inherits="System.Web.Mvc.ViewPage<playlist.App.Models.PlaylistModel>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Create </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <% using (Html.BeginForm()) { %> <%: Html.ValidationSummary(true,"Committing the playlist was unsuccessful. Please correct the errors and try again.")%> <div> <fieldset> <legend>Playlist Information</legend> <div class="editor-label"> <%: Html.LabelFor(m => m.Title) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Title)%> <%: Html.ValidationMessageFor(m => m.Title)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Description) %> </div> <div class="editor-field"> <%: Html.TextAreaFor(m => m.Description)%> <%: Html.ValidationMessageFor(m => m.Description)%> </div> <br /> <%: Html.ValidationMessageFor(m => m.Tags)%> <div class="editor-label"> <%: Html.LabelFor(m => m.Tags)%> </div> <div class="editor-field"> <%: Html.EditorFor(m => m.Tags) %> <%: Html.Editor("Tags[" + (Model == null ? 0 : Model.Tags.Count) + "]","PlaylistTagModel")%> </div> <br /> <%: Html.ValidationMessageFor(m => m.Songs)%> <div class="editor-label"> <%: Html.LabelFor(m => m.Songs)%> </div> <div class="editor-field"> <%: Html.EditorFor(m => m.Songs)%> <%: Html.Editor("Songs[" + (Model == null ? 0 : Model.Songs.Count) + "]","PlaylistSongModel")%> </div> <p> <input type="submit" value="Commit" /> </p> </fieldset> </div> <% } %> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="MetaData" runat="server"> </asp:Content>
这两个模板:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<playlist.App.Models.PlaylistSongModel>" %> <fieldset> <legend>Song Information</legend> <%: Html.ValidationSummary(true,"Committing this song was unsuccessful. Please correct the errors and try again.")%> <div class="editor-label"> <%: Html.LabelFor(m => m.Title) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Title)%> <%: Html.ValidationMessageFor(m => m.Title)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Artist)%> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Artist)%> <%: Html.ValidationMessageFor(m => m.Artist)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Description)%> </div> <div class="editor-field"> <%: Html.TextAreaFor(m => m.Description)%> <%: Html.ValidationMessageFor(m => m.Description)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Length)%> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Length)%> <%: Html.ValidationMessageFor(m => m.Length)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Year)%> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Year)%> <%: Html.ValidationMessageFor(m => m.Year)%> </div> </fieldset>
标签:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<playlist.App.Models.PlaylistTagModel>" %> <span class="tag"><%: Html.TextBoxFor(m => m.Tag)%></span> <%: Html.ValidationMessageFor(m => m.Tag)%>
最后我的自定义验证器列出:
public class ListCountAttribute : ValidationAttribute { public int Min { get; set; } public int Max { get; set; } public override bool IsValid(object value) { if (Min == 0 && Max == 0) return true; if (value == null) return false; if (!(value is ICollection)) throw new InvalidOperationException("ListCountAttribute requires underlying property to implement ICollection"); ICollection countable = value as ICollection; if (Min == 0 && Max != 0) return countable.Count <= Max; else if (Max == 0 && Min != 0) return countable.Count >= Min; return (countable.Count >= Min) && (countable.Count <= Max); } public override string FormatErrorMessage(string name) { if (Min == 0 && Max != 0) return "The field set " + name + " can not be larger then " + Max; else if (Max == 0 && Min != 0) return "The field set " + name + " need to have atleast a count of " + Min; return "The field set " + name + " need to between or equal to " + Min + " and " + Max; } }
解决方法
在/ views / shared中创建一个名为“EditorTemplates”的文件夹.
必须完全称之为.
必须完全称之为.
在此文件夹中,创建名为AlbumTagModel.ascx和AlbumSongModel.ascx的文件强烈键入其各自的模型.
回到您的视图页面中:
<%: Html.EditorFor(m => m.Tags)%>
和
<%: Html.EditorFor(m => m.Songs)%>
瞧!
渲染输入标记时,将下标以匹配您的列表. EditorFor将循环并呈现所有内容.
当您发布强类型Albumviewmodel时,您的列表将正确绑定回原始位置.
要添加新歌曲/标签,请将以下内容添加到您的Albumviewmodel:
public AlbumTagModel NewTagModel {get;set;}
并为它添加额外的EditorFor().