篇(18)-Asp.Net Core入门实战-文章管理之文章内容管理(下拉框二级结构递归实现)
文章管理是CMS系统的核心表之一,存储文章内容,特点就是字段端,属性多,比如是否标识为热点、推荐等属性,是否发布,类别,SEO关键字等。我们本章讲解文章内容的增删改查。
(1).文章Sql表结构设计
 - CREATE TABLE [dbo].[Article](
- [Id] [int] IDENTITY(1,1) NOT NULL,
- [CategoryId] [int] NOT NULL,
- [Title] [varchar](128) NOT NULL,
- [ImageUrl] [varchar](128) NULL,
- [Content] [text] NULL,
- [ViewCount] [int] NOT NULL,
- [Sort] [int] NOT NULL,
- [Author] [varchar](64) NULL,
- [Source] [varchar](128) NULL,
- [SeoTitle] [varchar](128) NULL,
- [SeoKeyword] [varchar](256) NULL,
- [SeoDescription] [varchar](512) NULL,
- [AddManagerId] [int] NOT NULL,
- [AddTime] [datetime] NOT NULL,
- [ModifyManagerId] [int] NULL,
- [ModifyTime] [datetime] NULL,
- [IsTop] [bit] NOT NULL,
- [IsSlide] [bit] NOT NULL,
- [IsRed] [bit] NOT NULL,
- [IsPublish] [bit] NOT NULL,
- [IsDeleted] [bit] NOT NULL,
- CONSTRAINT [PK_ARTICLE] PRIMARY KEY NONCLUSTERED
- (
- [Id] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
- GO
- SET ANSI_PADDING OFF
- GO
- ALTER TABLE [dbo].[Article] ADD DEFAULT (getdate()) FOR [AddTime]
- GO
- ALTER TABLE [dbo].[Article] ADD DEFAULT ((0)) FOR [IsTop]
- GO
- ALTER TABLE [dbo].[Article] ADD DEFAULT ((0)) FOR [IsSlide]
- GO
- ALTER TABLE [dbo].[Article] ADD DEFAULT ((0)) FOR [IsRed]
- GO
- ALTER TABLE [dbo].[Article] ADD DEFAULT ((0)) FOR [IsPublish]
- GO
- ALTER TABLE [dbo].[Article] ADD DEFAULT ((0)) FOR [IsDeleted]
- GO
- ALTER TABLE [dbo].[Article] WITH CHECK ADD CONSTRAINT [FK_ARTICLE_RELATIONS_ARTICLEC] FOREIGN KEY([CategoryId])
- REFERENCES [dbo].[ArticleCategory] ([Id])
- GO
- ALTER TABLE [dbo].[Article] CHECK CONSTRAINT [FK_ARTICLE_RELATIONS_ARTICLEC]
- GO
复制代码
那么对应的Article Model代码如下:- public class Article
- {
- /// <summary>
- /// 主键
- /// </summary>
- [Key]
- public Int32 Id { get; set; }
- /// <summary>
- /// 分类ID
- /// </summary>
- [Required]
- public Int32 CategoryId { get; set; }
- /// <summary>
- /// 文章标题
- /// </summary>
- [Required]
- public String Title { get; set; }
- /// <summary>
- /// 图片地址
- /// </summary>
- public String ImageUrl { get; set; }
- /// <summary>
- /// 文章内容
- /// </summary>
- public String Content { get; set; }
- /// <summary>
- /// 浏览次数
- /// </summary>
- [Required]
- public Int32 ViewCount { get; set; }
- /// <summary>
- /// 排序
- /// </summary>
- [Required]
- public Int32 Sort { get; set; }
- /// <summary>
- /// 作者
- /// </summary>
- public String Author { get; set; }
- /// <summary>
- /// 来源
- /// </summary>
- public String Source { get; set; }
- /// <summary>
- /// SEO标题
- /// </summary>
- public String SeoTitle { get; set; }
- /// <summary>
- /// SEO关键字
- /// </summary>
- public String SeoKeyword { get; set; }
- /// <summary>
- /// SEO描述
- /// </summary>
- public String SeoDescription { get; set; }
- /// <summary>
- /// 添加人ID
- /// </summary>
- [Required]
- public Int32 AddManagerId { get; set; }
- /// <summary>
- /// 添加时间
- /// </summary>
- [Required]
- public DateTime AddTime { get; set; }
- /// <summary>
- /// 修改人ID
- /// </summary>
- public Int32? ModifyManagerId { get; set; }
- /// <summary>
- /// 修改时间
- /// </summary>
- public DateTime? ModifyTime { get; set; }
- /// <summary>
- /// 是否置顶
- /// </summary>
- public Boolean IsTop { get; set; }
- /// <summary>
- /// 是否轮播显示
- /// </summary>
- public Boolean IsSlide { get; set; }
- /// <summary>
- /// 是否热门
- /// </summary>
- public Boolean IsRed { get; set; }
- /// <summary>
- /// 是否发布
- /// </summary>
- public Boolean IsPublish { get; set; }
- /// <summary>
- /// 是否删除
- /// </summary>
- [Required]
- public Boolean IsDeleted { get; set; }
- }
复制代码
(2).视图Create代码
(2.1)视图代码
考虑到要同时上传图片,注意form表单的额 enctype类型;- @{ ViewData["Title"] = "新建文章"; }
- @model Article
- <form action="/Article/Create" method="post" enctype="multipart/form-data">
- @Html.AntiForgeryToken()
- <label asp-for="Title">标题</label>
- <input type="text" asp-for="Title" name="Title" placeholder="请输入标题">
- <label asp-for="CategoryId">文章类型</label>
- @Html.DropDownList("ddl_CategoryId", ViewBag.database as IEnumerable<SelectListItem>)
- <label>设置</label>
- @*@Html.CheckBox("IsTop") 置顶
- @Html.CheckBox("IsRed") 热点
- @Html.CheckBox("IsSlide") 幻灯*@
- <input type="checkbox" name="IsTop" asp-for="IsTop" />置顶
- <input type="checkbox" name="IsRed" asp-for="IsRed"/>热点
- <input type="checkbox" name="IsSlide" asp-for="IsSlide" />幻灯
- <label asp-for="ImageUrl">文章首页图</label>
- <input type="file" asp-for="ImageUrl" name="ImageUrl"/>
- <label asp-for="Content">内容</label>
- <textarea placeholder="内容" asp-for="Content" name="Content" cols="30" rows="10"></textarea>
- <label asp-for="Sort">排序</label>
- <input type="text" placeholder="排序" asp-for="Sort" name="Sort" />
- <label asp-for="ViewCount">点击量</label>
- <input type="text" placeholder="点击量" asp-for="ViewCount" name="ViewCount" />
- <label asp-for="IsPublish">是否发布</label>
- <select asp-for="IsPublish" name="IsPublish" class="IsPublish">
- <option value="False">否</option>
- <option value="True" selected>是</option>
- </select>
- <label asp-for="Author">作者</label>
- <input type="text" asp-for="Author" name="Author" placeholder="作者名">
- <label asp-for="Source">来源</label>
- <input type="text" asp-for="Source" name="Source" placeholder="文章来源">
- <label asp-for="SeoTitle">SEO标题</label>
- <input type="text" asp-for="SeoTitle" name="SeoTitle" placeholder="SEO标题">
- <label asp-for="SeoKeyword">SEO关键词</label>
- <input type="text" asp-for="SeoKeyword" name="SeoKeyword" placeholder="SEO关键词">
- <label asp-for="SeoDescription">SEO摘要描述</label>
- <input type="text" asp-for="SeoDescription" name="SeoDescription" placeholder="SEO摘要描述">
- <button type="submit">确定</button>
- <button type="reset">重置</button>
- </form>
复制代码
(2.2)视图中的下拉框的实现方式(递归和循环嵌套)

我想在添加文章时,实现一个具有二级层次结构的下拉框,如上图所示。所以,在对下拉框进行数据绑定时,就要费点功夫,上个章节讲文章类别管理时,的表结构就一个,分类都存在一张表中,所以要进行递归的获取子菜单或者通过循环嵌套来实现。
递归的主要核心函数为:- /// <summary>
- /// 递归函数,实现获取子菜单
- /// </summary>
- /// <param name="lists">递归前的列表</param>
- /// <param name="newlists">递归后的新列表</param>
- /// <param name="parentId">父Id</param>
- /// <returns></returns>
- public static List<CategorySelectItemListView> GetChildCategory(List<CategorySelectItemListView> lists, List<CategorySelectItemListView> newlists, int parentId)
- {
- newlists = new List<CategorySelectItemListView>();
- List<CategorySelectItemListView> tempList = lists.Where(c => c.ParentId == parentId).ToList();
- for (int i = 0; i < tempList.Count; i++)
- {
- CategorySelectItemListView category = new CategorySelectItemListView();
- category.Id = tempList[i].Id;
- category.ParentId = tempList[i].ParentId;
- category.Title = tempList[i].Title;
- category.Children = GetChildCategory(lists, newlists, category.Id);
- newlists.Add(category);
- }
- return newlists;
- }
- /// <summary>
- /// 循环嵌套,实现获取子菜单
- /// </summary>
- /// <param name="lists">循环遍历前的列表</param>
- /// <returns></returns>
- public static List<CategorySelectItemListView> GetChildCategory(List<CategorySelectItemListView> lists)
- {
- List<CategorySelectItemListView> categorylist = new List<CategorySelectItemListView>();
- for (int i = 0; i < lists.Count; i++)
- {
- if (0 == lists[i].ParentId)
- categorylist.Add(lists[i]);
- for (int j = 0; j < lists.Count; j++)
- {
- if (lists[j].ParentId == lists[i].Id)
- lists[i].Children.Add(lists[j]);
- }
- }
- return categorylist;
- }
复制代码
然后在Create和Edit的Action中去绑定对应的下拉菜单即可。
注意:List 集合的CategorySelectItemListView,这个是新建的ViewModel对象,用来专门绑定下拉菜单使用,其代码如下:- public class CategorySelectItemListView
- {
- public int Id { get; set; }
- public string Title { get; set; }
- public int ParentId { get; set; }
- public List<CategorySelectItemListView> Children { get; set; }
- public CategorySelectItemListView()
- {
- Children = new List<CategorySelectItemListView>();
- }
- public CategorySelectItemListView(int id,string title,int parentid)
- {
- this.Id = id;
- this.Title = title;
- this.ParentId = parentid;
- Children = new List<CategorySelectItemListView>();
- }
- public CategorySelectItemListView(int id, string title, CategorySelectItemListView parent)
- {
- this.Id = id;
- this.Title = title;
- this.ParentId = parent.Id;
- Children = new List<CategorySelectItemListView>();
- }
复制代码
(3).视图Edit代码,注解部分的代码可以参考,我尝试用过,也可以达到目的,演练代码最好是用多种方式实现,查看其区别,这样掌握的牢固一些。
(4).视图Index列表的代码
针对列表的显示,又专门编写了ArticeView的这个ViewModel。
 - public class ArticleView
- {
- public int Id { get; set; }
- public int CategoryId { get; set; }
- public string CategoryName { get; set; }
- public string Title { get; set; }
- public int ViewCount { get; set; }
- public int Sort { get; set; }
- public string Author { get; set; }
- public string Source { get; set; }
- public int AddManagerId { get; set; }
- public DateTime AddTime { get; set; }
- }
复制代码 - @using Humanizer;
- @using RjWebCms.Db;
- @using RjWebCms.Models.Articles;
- @model PaginatedList<ArticleView>
- @{
- ViewData["Title"] = "文章列表";
- }
- @section Scripts{
- }
- @ViewData["Title"]
- @Html.AntiForgeryToken()
- <form asp-action="Index" method="get">
- <table>
- <tr><td><a asp-controller="Article" asp-action="Create">添加</a></td></tr>
- <tr>
- <td>查询关键词:<input type="text" name="SearchString" value="@ViewData["CurrentFilter"]" /></td>
- <td><input type="submit" value="查询" /></td>
- <td><a asp-action="Index">Back</a></td>
- <td><a asp-action="DeleteAll">批量删除</a></td>
- </tr>
- </table>
- </form>
- <table class="table table-hover">
- <thead>
- <tr>
- <td>✔</td>
- <td><a asp-action="Index" asp-route-sortOrder="@ViewData["NameSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">标题</a></td>
- <td>类别</td>
- <td><a asp-action="Index" asp-route-sortOrder="@ViewData["DateSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">添加时间</a></td>
- <td>作者</td>
- <td>操作</td>
- </tr>
- @foreach (var item in Model)
- {
- <tr>
- <td><input type="checkbox" class="done-checkbox" name="chk_ids" value="@item.Id"></td>
- <td>@item.Title</td>
- <td>@item.CategoryName</td>
- <td>@item.AddTime</td>
- <td>@item.Author</td>
- <td>
- <a asp-action="Details" asp-route-id="@item.Id">Details</a>
- <a asp-action="Edit" asp-route-id="@item.Id">Edit</a>
- <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
- </td>
- </tr>
- }
- </thead>
- </table>
- @{
- var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
- var nextDisabled = !Model.HasNextPage ? "disabled" : ""; ;
- }
- <a asp-action="Index"
- asp-route-sortOrder="@ViewData["CurrentSort"]"
- asp-route-pageNumber="@(Model.PageIndex - 1)"
- asp-route-currentFilter="@ViewData["CurrentFilter"]"
- class="btn btn-default @prevDisabled">
- 上一页
- </a>
- <a asp-action="Index"
- asp-route-sortOrder="@ViewData["CurrentSort"]"
- asp-route-pageNumber="@(Model.PageIndex + 1)"
- asp-route-currentFilter="@ViewData["CurrentFilter"]"
- class="btn btn-default @nextDisabled">
- 下一页
- </a>
复制代码
(5).Controller部分的全部代码,注意看代码注释- public class ArticleController : Controller
- {
- private readonly IHostEnvironment _hostEnvironment;
- private readonly IArticleService _articleService;
- private readonly IArticleCategoryService _articleCategoryService;
- private readonly AppDbContext _appDbContext;
- public ArticleController(IArticleService articleService, IArticleCategoryService articleCategoryService,AppDbContext appDbContext,IHostEnvironment hostEnvironment)
- {
- _hostEnvironment = hostEnvironment;
- _appDbContext = appDbContext;
- _articleService = articleService;
- _articleCategoryService = articleCategoryService;
- }
- public async Task<IActionResult> Index(string sortOrder, string currentFilter, string searchString, int? pageNumber)
- {
- ViewData["CurrentSort"] = sortOrder;
- ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
- ViewData["DateSortParm"] = sortOrder == "Date" ? "date_desc" : "Date";
- if (searchString != null)
- {
- pageNumber = 1;
- }
- else
- {
- searchString = currentFilter;
- }
- ViewData["CurrentFilter"] = searchString;
- var article = from s in _appDbContext.Article
- join p in _appDbContext.ArticleCategory on s.CategoryId equals p.Id
- select new ArticleView {
- Id = s.Id,
- CategoryId = s.CategoryId,
- CategoryName = p.Title,
- Title = s.Title,
- Sort = s.Sort,
- AddManagerId = s.AddManagerId,
- AddTime = s.AddTime,
- Author = s.Author,
- Source = s.Source,
- ViewCount = s.ViewCount,
- };
- if (!string.IsNullOrEmpty(searchString))
- {
- article = article.Where(s => s.Title.Contains(searchString));
- }
- switch (sortOrder)
- {
- case "name_desc":
- article = article.OrderByDescending(s => s.Title) ;
- break;
- case "Date":
- article = article.OrderBy(s => s.AddTime);
- break;
- case "date_desc":
- article = article.OrderByDescending(s => s.AddTime);
- break;
- default:
- article = article.OrderBy(s => s.Title);
- break;
- }
- int pageSize = 4;
- return View(await PaginatedList<ArticleView>.CreateAsync(article.AsNoTracking(), pageNumber ?? 1, pageSize));
- }
- [HttpGet]
- public async Task<IActionResult> CreateAsync()
- {
- #region 绑定类别下拉框
- var categories = await _articleCategoryService.GetArticleCategory();//列出文章类别字典
- var categoryItems = new List<SelectListItem>()
- {
- new SelectListItem(){ Value="0",Text="全部",Selected=true}
- };
- //全部列出并转成DropDownList对象
- List<CategorySelectItemListView> list = new List<CategorySelectItemListView>();
- foreach (var category in categories)
- {
- list.Add(new CategorySelectItemListView {
- Id=category.Id,
- Title = category.Title,
- ParentId = category.ParentId
- });
- }
- #region 循环嵌套调用
- //List<CategorySelectItemListView> list1 = GetChildCategory(list);
- //foreach (var li in list1)
- //{
- // categoryItems.Add(new SelectListItem { Value = li.Id.ToString(), Text = li.Title });
- // if (li.Children.Count > 0)
- // {
- // foreach(var t in li.Children)
- // categoryItems.Add(new SelectListItem { Value = t.Id.ToString(),Text= "|-" + t.Title });
- // }
- //}
- #endregion
- #region 递归调用
- List<CategorySelectItemListView> list1 = GetChildCategory(list, new List<CategorySelectItemListView>(), 0);
- foreach (var li in list1)
- {
- categoryItems.Add(new SelectListItem { Value = li.Id.ToString(), Text = li.Title });
- if (li.Children.Count > 0)
- {
- foreach (var t in li.Children)
- categoryItems.Add(new SelectListItem { Value = t.Id.ToString(), Text = " |-" + t.Title });
- }
- }
- #endregion
- ViewBag.database = categoryItems;
- #endregion
- return View();
- }
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task<IActionResult> CreateAsync(Article article,[FromForm]IFormCollection fromData)
- {
- //去掉对字段IsSystem的验证,IsSystem在数据库是bool类型,而前端是0和1,ModelState的验证总是报false,所以去掉对其验证
- //ModelState.Remove("IsSystem");//在View端已经解决了了bool类型,那么此行代码可以不用
- #region 下拉菜单
- string strCategoryId = Request.Form["ddl_CategoryId"];
- if (!string.IsNullOrEmpty(strCategoryId))
- article.CategoryId = int.Parse(strCategoryId);
- else
- article.CategoryId = 0;
- #endregion
- #region 复选框
- article.IsTop = fromData["IsTop"] != "false";//使用FormCollection时,可以这样
- article.IsRed = fromData["IsRed"] != "false";
- article.IsSlide = fromData["IsSlide"] != "false";
- //也可以这样取值,但要注意View内的写法
- //if (!string.IsNullOrEmpty(fromData["IsTop"]))
- // article.IsTop = true;
- //else
- // article.IsTop = false;
- #endregion
- #region 上传文件
- IFormFileCollection files = fromData.Files;
- foreach(var formFile in files)
- {
- //var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
- string webContentPath = _hostEnvironment.ContentRootPath;
- var fileExt = formFile.FileName.Substring(formFile.FileName.LastIndexOf('.'));//文件扩展名
- var fileNew = DateTime.Now.ToString("yyyyMMddHHmmss") + fileExt; //给文件重新命名
-
- //string upLoadPath = webContentPath + $@"\{fileName}";
- string upLoadPath = webContentPath + $@"\UpFiles";
- var fileUrl = upLoadPath + $@"\{fileNew}";
- if (formFile.Length > 0)
- {
- using (var stream = new FileStream(fileUrl,FileMode.Create))
- {
- await formFile.CopyToAsync(stream);
- }
- }
- article.ImageUrl = "../UpFiles/" + fileNew;
- }
- #endregion
- if (ModelState.IsValid)
- {
- var successful = await _articleService.AddArticleAysnc(article);
- if (successful)
- return RedirectToAction("Index");
- else
- return BadRequest("失败");
- }
- return View(article);
- }
- [HttpGet]
- public async Task<IActionResult> Edit(int id)
- {
- if (string.IsNullOrEmpty(id.ToString()))
- return NotFound();
- var article = await _articleService.FindArticleAsync(id);
- if (article == null)
- return NotFound();
- #region 绑定角色下拉框
- var categories = await _articleCategoryService.GetArticleCategory();//列出文章类别字典
- var categoryItems = new List<SelectListItem>()
- {
- new SelectListItem(){ Value="0",Text="全部",Selected=true}
- };
- //全部列出并转成DropDownList对象
- List<CategorySelectItemListView> list = new List<CategorySelectItemListView>();
- foreach (var category in categories)
- {
- list.Add(new CategorySelectItemListView
- {
- Id = category.Id,
- Title = category.Title,
- ParentId = category.ParentId
- });
- }
- #region 递归调用
- List<CategorySelectItemListView> list1 = GetChildCategory(list, new List<CategorySelectItemListView>(), 0);
- foreach (var li in list1)
- {
- categoryItems.Add(new SelectListItem { Value = li.Id.ToString(), Text = li.Title });
- if (li.Children.Count > 0)
- {
- foreach (var t in li.Children)
- categoryItems.Add(new SelectListItem { Value = t.Id.ToString(), Text = " |-" + t.Title });
- }
- }
- #endregion
- #region 遍历并选中
- foreach (SelectListItem item in categoryItems)
- {
- if (item.Value == article.CategoryId.ToString())
- item.Selected = true;
- }
- #endregion
- ViewBag.database = categoryItems;
- #endregion
- return View(article);
- }
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task<IActionResult> Edit(int id, [FromForm]Article article)
- {
- if (id != article.Id)
- {
- return NotFound();
- }
- #region 下拉菜单
- string strCategoryId = Request.Form["ddl_CategoryId"];
- if (!string.IsNullOrEmpty(strCategoryId))
- article.CategoryId = int.Parse(strCategoryId);
- else
- article.CategoryId = 0;
- #endregion
- #region 复选框
- if (Request.Form["IsTop"].Contains("true"))
- article.IsTop = true;
- else
- article.IsTop = false;
- if (Request.Form["IsRed"].Contains("true"))
- article.IsRed = true;
- else
- article.IsRed = false;
- if (Request.Form["IsSlide"].Contains("true"))
- article.IsSlide = true;
- else
- article.IsSlide = false;
- #endregion
- //ModelState.Remove("IsTop");
- //ModelState.Remove("IsRed");
- //ModelState.Remove("IsSlide");
- if (ModelState.IsValid)
- {
- try
- {
- var result = await _articleService.UpdateArticleAsync(id, article);
- //跳转
- if (result)
- return RedirectToAction("Index");
- else
- return BadRequest("编辑失败");
- }
- catch (Exception ex)
- {
- return BadRequest("编辑失败");
- }
- }
- else
- {
- return BadRequest("数据输入有误!");
- }
- }
- /// <summary>
- /// 递归函数,实现获取子菜单
- /// </summary>
- /// <param name="lists">递归前的列表</param>
- /// <param name="newlists">递归后的新列表</param>
- /// <param name="parentId">父Id</param>
- /// <returns></returns>
- public static List<CategorySelectItemListView> GetChildCategory(List<CategorySelectItemListView> lists, List<CategorySelectItemListView> newlists, int parentId)
- {
- newlists = new List<CategorySelectItemListView>();
- List<CategorySelectItemListView> tempList = lists.Where(c => c.ParentId == parentId).ToList();
- for (int i = 0; i < tempList.Count; i++)
- {
- CategorySelectItemListView category = new CategorySelectItemListView();
- category.Id = tempList[i].Id;
- category.ParentId = tempList[i].ParentId;
- category.Title = tempList[i].Title;
- category.Children = GetChildCategory(lists, newlists, category.Id);
- newlists.Add(category);
- }
- return newlists;
- }
- /// <summary>
- /// 循环嵌套,实现获取子菜单
- /// </summary>
- /// <param name="lists">循环遍历前的列表</param>
- /// <returns></returns>
- public static List<CategorySelectItemListView> GetChildCategory(List<CategorySelectItemListView> lists)
- {
- List<CategorySelectItemListView> categorylist = new List<CategorySelectItemListView>();
- for (int i = 0; i < lists.Count; i++)
- {
- if (0 == lists[i].ParentId)
- categorylist.Add(lists[i]);
- for (int j = 0; j < lists.Count; j++)
- {
- if (lists[j].ParentId == lists[i].Id)
- lists[i].Children.Add(lists[j]);
- }
- }
- return categorylist;
- }
- }
复制代码
(6).Service应用层代码

再谈CheckBox的使用
1.在View视图页增加的代码格式如果为:
置顶
或者是这样:
置顶
那么在生成的html代码中,都会自动成id,name,type=“checkbox” value的属性。
2.在Controller中进行取值时的代码为:
if (Request.Form["IsTop"].Contains("true"))
article.IsTop = true;
else
article.IsTop = false;
跟踪时发现,View中Checkbox选中是,会产生true和false两个值,如图跟踪变量发现:

如此,取值时,就用了Contains功能,因为View中CheckBox没选中,这只有一个false值;
3.在View视图页增加代码的格式如果为:
置顶
4.在Controller中进行取值时的代码为:
if (!string.IsNullOrEmpty(Request.Form["IsTop"]))
article.IsTop = true;
else
article.IsTop = false;
跟踪时发现,View中的CheckBox选中是,取到的值为“on”,如图跟踪发现:

所以,才用了IsNullOrEmpty这个函数,依据判空来确定是否选中。
但是这样写有个问题,在ModelState.IsValid()的模型验证中,一直无法通过,IsTop一直为false,为此,我干脆就把其去除掉验证:
ModelState.Remove("IsTop");//去除name=IsTop的checkbox的模型验证
5.使用Checkbox,还是要看给在数据表中为其定义的字段类型,Model中的指定类型和验证属性,如果你赋予了Value值,那么就在Controller中取值,Asp.Net Core中Checkbox默认是True和False的值,网上关于@Html.CheckBox()形式也行,你可以尝试跟踪变量值来判断如何处理,其宗旨就是根据具体条件来处理。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |