当前位置:Gxlcms > asp.net > ASP.NET MVC5网站开发修改及删除文章(十)

ASP.NET MVC5网站开发修改及删除文章(十)

时间:2021-07-01 10:21:17 帮助过:45人阅读

上次做了显示文章列表,再实现修改和删除文章这部分内容就结束了,这次内容比较简单,由于做过了添加文章,修改文章非常类似,就是多了一个TryUpdateModel部分更新模型数据。
一、删除文章
由于公共模型跟,文章,附件有关联,所以这里的删除次序很重要,如果先删除模型,那么文章ModelID和附件的ModelID多会变成null,所以要先先删除文章和附件再删除公共模型。

由于公共模型和附件是一对多的关系,我们把删除公共模型和删除附件写在一起。

在BLL的BaseRepository类中有默认的Delete方法,但这个方法中仅删除模型,不会删除外键,所以在CommonModelRepository在new一个出来封印掉默认的方法。

  1. public new bool Delete(Models.CommonModel commonModel, bool isSave = true)
  2. {
  3. if (commonModel.Attachment != null) nContext.Attachments.RemoveRange(commonModel.Attachment);
  4. nContext.CommonModels.Remove(commonModel);
  5. return isSave ? nContext.SaveChanges() > 0 : true;
  6. }

这个的意思是封印掉继承的Delete方法,在新的方法中如果存在附加那么先删除附件,再删除公共模型。那么如果我们还想调用基类的Delete方法怎么办?可以用base.Delete。

好了,现在可以开始删除了。

在ArticleController中添加Delete方法

  1. /// <summary>
  2. /// 删除
  3. /// </summary>
  4. /// <param name="id">文章id</param>
  5. /// <returns></returns>
  6. public JsonResult Delete(int id)
  7. {
  8. //删除附件
  9. var _article = articleService.Find(id);
  10. if(_article == null) return Json(false);
  11. //附件列表
  12. var _attachmentList = _article.CommonModel.Attachment;
  13. var _commonModel = _article.CommonModel;
  14. //删除文章
  15. if (articleService.Delete(_article))
  16. {
  17. //删除附件文件
  18. foreach (var _attachment in _attachmentList)
  19. {
  20. System.IO.File.Delete(Server.MapPath(_attachment.FileParth));
  21. }
  22. //删除公共模型
  23. commonModelService.Delete(_commonModel);
  24. return Json(true);
  25. }
  26. else return Json(false);
  27. }

二、修改文章
这个部分跟添加文章非常类似
首先在ArticleController中添加显示编辑视图的Edit

  1. /// <summary>
  2. /// 修改
  3. /// </summary>
  4. /// <param name="id"></param>
  5. /// <returns></returns>
  6. public ActionResult Edit(int id)
  7. {
  8. return View(articleService.Find(id));
  9. }

右键添加视图,这个跟添加类似,没什么好说的直接上代码

  1. @section scripts{
  2. <script type="text/javascript" src="~/Scripts/KindEditor/kindeditor-min.js"></script>
  3. <script type="text/javascript">
  4. //编辑框
  5. KindEditor.ready(function (K) {
  6. window.editor = K.create('#Content', {
  7. height: '500px',
  8. uploadJson: '@Url.Action("Upload", "Attachment")',
  9. fileManagerJson: '@Url.Action("FileManagerJson", "Attachment", new { id = @Model.CommonModel.ModelID })',
  10. allowFileManager: true,
  11. formatUploadUrl: false
  12. });
  13. //首页图片
  14. var editor2 = K.editor({
  15. fileManagerJson: '@Url.Action("FileManagerJson", "Attachment", new {id=@Model.CommonModel.ModelID })'
  16. });
  17. K('#btn_picselect').click(function () {
  18. editor2.loadPlugin('filemanager', function () {
  19. editor2.plugin.filemanagerDialog({
  20. viewType: 'VIEW',
  21. dirName: 'image',
  22. clickFn: function (url, title) {
  23. var url;
  24. $.ajax({
  25. type: "post",
  26. url: "@Url.Action("CreateThumbnail", "Attachment")",
  27. data: { originalPicture: url },
  28. async: false,
  29. success: function (data) {
  30. if (data == null) alert("生成缩略图失败!");
  31. else {
  32. K('#CommonModel_DefaultPicUrl').val(data);
  33. K('#imgpreview').attr("src", data);
  34. }
  35. editor2.hideDialog();
  36. }
  37. });
  38. }
  39. });
  40. });
  41. });
  42. });
  43. </script>
  44. }
  45. @model Ninesky.Models.Article
  46. @using (Html.BeginForm())
  47. { @Html.AntiForgeryToken()
  48. <div class="form-horizontal" role="form">
  49. <h4>添加文章</h4>
  50. <hr />
  51. @Html.ValidationSummary(true)
  52. <div class="form-group">
  53. <label class="control-label col-sm-2" for="CommonModel_CategoryID">栏目</label>
  54. <div class="col-sm-10">
  55. <input id="CommonModel_CategoryID" name="CommonModel.CategoryID" data-options="url:'@Url.Action("JsonTree", "Category", new { model="Article" })'" class="easyui-combotree" style="height: 34px; width: 280px;" value="@Model.CommonModel.CategoryID" />
  56. @Html.ValidationMessageFor(model => model.CommonModel.CategoryID)</div>
  57. </div>
  58. <div class="form-group">
  59. @Html.LabelFor(model => model.CommonModel.Title, new { @class = "control-label col-sm-2" })
  60. <div class="col-sm-10">
  61. @Html.TextBoxFor(model => model.CommonModel.Title, new { @class = "form-control" })
  62. @Html.ValidationMessageFor(model => model.CommonModel.Title)</div>
  63. </div>
  64. <div class="form-group">
  65. @Html.LabelFor(model => model.Author, new { @class = "control-label col-sm-2" })
  66. <div class="col-sm-10">
  67. @Html.TextBoxFor(model => model.Author, new { @class = "form-control" })
  68. @Html.ValidationMessageFor(model => model.Author)
  69. </div>
  70. </div>
  71. <div class="form-group">
  72. @Html.LabelFor(model => model.Source, new { @class = "control-label col-sm-2" })
  73. <div class="col-sm-10">
  74. @Html.TextBoxFor(model => model.Source, new { @class = "form-control" })
  75. @Html.ValidationMessageFor(model => model.Source)
  76. </div>
  77. </div>
  78. <div class="form-group">
  79. @Html.LabelFor(model => model.Intro, new { @class = "control-label col-sm-2" })
  80. <div class="col-sm-10">
  81. @Html.TextAreaFor(model => model.Intro, new { @class = "form-control" })
  82. @Html.ValidationMessageFor(model => model.Intro)
  83. </div>
  84. </div>
  85. <div class="form-group">
  86. @Html.LabelFor(model => model.Content, new { @class = "control-label col-sm-2" })
  87. <div class="col-sm-10">
  88. @Html.EditorFor(model => model.Content)
  89. @Html.ValidationMessageFor(model => model.Content)
  90. </div>
  91. </div>
  92. <div class="form-group">
  93. @Html.LabelFor(model => model.CommonModel.DefaultPicUrl, new { @class = "control-label col-sm-2" })
  94. <div class="col-sm-10">
  95. <img id="imgpreview" class="thumbnail" src="@Model.CommonModel.DefaultPicUrl" />
  96. @Html.HiddenFor(model => model.CommonModel.DefaultPicUrl)
  97. <a id="btn_picselect" class="easyui-linkbutton">选择…</a>
  98. @Html.ValidationMessageFor(model => model.CommonModel.DefaultPicUrl)
  99. </div>
  100. </div>
  101. <div class="form-group">
  102. <div class="col-sm-offset-2 col-sm-10">
  103. <input type="submit" value="保存" class="btn btn-default" />
  104. </div>
  105. </div>
  106. </div>
  107. }

开始做后台接受代码,在ArticleController中添加如下代码。

  1. [HttpPost]
  2. [ValidateInput(false)]
  3. [ValidateAntiForgeryToken]
  4. public ActionResult Edit()
  5. {
  6. int _id = int.Parse(ControllerContext.RouteData.GetRequiredString("id"));
  7. var article = articleService.Find(_id);
  8. TryUpdateModel(article, new string[] { "Author", "Source", "Intro", "Content" });
  9. TryUpdateModel(article.CommonModel, "CommonModel", new string[] { "CategoryID", "Title", "DefaultPicUrl" });
  10. if(ModelState.IsValid)
  11. {
  12. if (articleService.Update(article))
  13. {
  14. //附件处理
  15. InterfaceAttachmentService _attachmentService = new AttachmentService();
  16. var _attachments = _attachmentService.FindList(article.CommonModel.ModelID, User.Identity.Name, string.Empty,true).ToList();
  17. foreach (var _att in _attachments)
  18. {
  19. var _filePath = Url.Content(_att.FileParth);
  20. if ((article.CommonModel.DefaultPicUrl != null && article.CommonModel.DefaultPicUrl.IndexOf(_filePath) >= 0) || article.Content.IndexOf(_filePath) > 0)
  21. {
  22. _att.ModelID = article.ModelID;
  23. _attachmentService.Update(_att);
  24. }
  25. else
  26. {
  27. System.IO.File.Delete(Server.MapPath(_att.FileParth));
  28. _attachmentService.Delete(_att);
  29. }
  30. }
  31. return View("EditSucess", article);
  32. }
  33. }
  34. return View(article);
  35. }

详细讲解一下吧:

1、[ValidateInput(false)] 表示不验证输入内容。因为文章内容包含html代码,防止提交失败。

2、[ValidateAntiForgeryToken]是为了防止伪造跨站请求的,也就说只有本真的请求才能通过。

见图中的红线部分,在试图中构造验证字符串,然后再后台验证。

3、public ActionResult Edit()。看这个方法没有接收任何数据,我们再方法中使用TryUpdateModel更新模型。因为不能完全相信用户,比如如果用户构造一个CateggoryID过来,就会把文章发布到其他栏目去。

这个是在路由中获取id参数

再看这两行,略有不同
第一行直接更新article模型。第一个参数是要更新的模型,第二个参数是更新的字段。
第二行略有不同,增加了一个前缀参数,我们看视图生成的代码 @Html.TextBoxFor(model => model.CommonModel.Title 是带有前缀CommonModel的。所以这里必须使用前缀来更新视图。

三、修改文章列表
写完文章后,就要更改文章列表代码用来删除和修改文章。
打开List视图,修改部分由2处。
1、js脚本部分

  1. <script type="text/javascript">
  2. $("#article_list").datagrid({
  3. loadMsg: '加载中……',
  4. pagination:true,
  5. url: '@Url.Action("JsonList","Article")',
  6. columns: [[
  7. { field: 'ModelID', title: 'ID', checkbox: true },
  8. { field: 'CategoryName', title: '栏目'},
  9. { field: 'Title', title: '标题'},
  10. { field: 'Inputer', title: '录入', align: 'right' },
  11. { field: 'Hits', title: '点击', align: 'right' },
  12. { field: 'ReleaseDate', title: '发布日期', align: 'right', formatter: function (value, row, index) { return jsonDateFormat(value); } },
  13. { field: 'StatusString', title: '状态', width: 100, align: 'right' }
  14. ]],
  15. toolbar: '#toolbar',
  16. idField: 'ModelID',
  17. onDblClickRow: function (rowIndex, rowData) { window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rowData.ModelID, "icon-page"); }
  18. });
  19. //查找
  20. $("#btn_search").click(function () {
  21. $("#article_list").datagrid('load', {
  22. title: $("#textbox_title").val(),
  23. input: $("#textbox_inputer").val(),
  24. category: $("#combo_category").combotree('getValue'),
  25. fromDate: $("#datebox_fromdate").datebox('getValue'),
  26. toDate: $("#datebox_todate").datebox('getValue')
  27. });
  28. });
  29. //修改事件
  30. function eidt() {
  31. var rows = $("#article_list").datagrid("getSelections");
  32. if (!rows || rows.length < 1) {
  33. $.messager.alert("提示", "请选择要修改的行!");
  34. return;
  35. }
  36. else if (rows.length != 1) {
  37. $.messager.alert("提示", "仅能选择一行!");
  38. return;
  39. }
  40. else {
  41. window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rows[0].ModelID, "icon-page");
  42. }
  43. }
  44. //删除
  45. function del()
  46. {
  47. var rows = $("#article_list").datagrid("getSelections");
  48. if (!rows || rows.length < 1) {
  49. $.messager.alert("提示", "未选择任何行!");
  50. return;
  51. }
  52. else if (rows.length > 0) {
  53. $.messager.confirm("确认", "您确定要删除所选行吗?", function (r) {
  54. if (r) {
  55. $.messager.progress();
  56. $.each(rows, function (index, value) {
  57. $.ajax({
  58. type: "post",
  59. url: "@Url.Action("Delete", "Article")",
  60. data: { id: value.ModelID },
  61. async: false,
  62. success: function (data) {
  63. }
  64. });
  65. });
  66. $.messager.progress('close');
  67. //清除选择行
  68. rows.length = 0;
  69. $("#article_list").datagrid('reload');
  70. }
  71. });
  72. return;
  73. }
  74. }
  75. </script>

增加了修改方法、删除方法,在datagrid里添加行双击进入修改视图的方法

onDblClickRow: function (rowIndex, rowData) { window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rowData.ModelID, "icon-page"); }

2、

四、我的文章列表
我的文章列表与全部文章类似,并简化掉了部分内容那个,更加简单,直接上代码了
Article控制器中添加

  1. /// <summary>
  2. /// 文章列表Json【注意权限问题,普通人员是否可以访问?】
  3. /// </summary>
  4. /// <param name="title">标题</param>
  5. /// <param name="input">录入</param>
  6. /// <param name="category">栏目</param>
  7. /// <param name="fromDate">日期起</param>
  8. /// <param name="toDate">日期止</param>
  9. /// <param name="pageIndex">页码</param>
  10. /// <param name="pageSize">每页记录</param>
  11. /// <returns></returns>
  12. public ActionResult JsonList(string title, string input, Nullable<int> category, Nullable<DateTime> fromDate, Nullable<DateTime> toDate, int pageIndex = 1, int pageSize = 20)
  13. {
  14. if (category == null) category = 0;
  15. int _total;
  16. var _rows = commonModelService.FindPageList(out _total, pageIndex, pageSize, "Article", title, (int)category, input, fromDate, toDate, 0).Select(
  17. cm => new Ninesky.Web.Models.CommonModelViewModel()
  18. {
  19. CategoryID = cm.CategoryID,
  20. CategoryName = cm.Category.Name,
  21. DefaultPicUrl = cm.DefaultPicUrl,
  22. Hits = cm.Hits,
  23. Inputer = cm.Inputer,
  24. Model = cm.Model,
  25. ModelID = cm.ModelID,
  26. ReleaseDate = cm.ReleaseDate,
  27. Status = cm.Status,
  28. Title = cm.Title
  29. });
  30. return Json(new { total = _total, rows = _rows.ToList() });
  31. }
  32. public ActionResult MyList()
  33. {
  34. return View();
  35. }
  36. /// <summary>
  37. /// 我的文章列表
  38. /// </summary>
  39. /// <param name="title"></param>
  40. /// <param name="fromDate"></param>
  41. /// <param name="toDate"></param>
  42. /// <param name="pageIndex"></param>
  43. /// <param name="pageSize"></param>
  44. /// <returns></returns>
  45. public ActionResult MyJsonList(string title, Nullable<DateTime> fromDate, Nullable<DateTime> toDate, int pageIndex = 1, int pageSize = 20)
  46. {
  47. int _total;
  48. var _rows = commonModelService.FindPageList(out _total, pageIndex, pageSize, "Article", title, 0, string.Empty, fromDate, toDate, 0).Select(
  49. cm => new Ninesky.Web.Models.CommonModelViewModel()
  50. {
  51. CategoryID = cm.CategoryID,
  52. CategoryName = cm.Category.Name,
  53. DefaultPicUrl = cm.DefaultPicUrl,
  54. Hits = cm.Hits,
  55. Inputer = cm.Inputer,
  56. Model = cm.Model,
  57. ModelID = cm.ModelID,
  58. ReleaseDate = cm.ReleaseDate,
  59. Status = cm.Status,
  60. Title = cm.Title
  61. });
  62. return Json(new { total = _total, rows = _rows.ToList() }, JsonRequestBehavior.AllowGet);
  63. }
  64. 为MyList右键添加视图
  65. <div id="toolbar">
  66. <div>
  67. <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true" onclick="eidt()">修改</a>
  68. <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true" onclick="del()">删除</a>
  69. <a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-reload',plain:true" onclick="$('#article_list').datagrid('reload');">刷新</a>
  70. </div>
  71. <div class="form-inline">
  72. <label>标题</label> <input id="textbox_title" class="input-easyui" style="width:280px" />
  73. <label>添加日期</label>
  74. <input id="datebox_fromdate" type="datetime" class="easyui-datebox" style="width:120px" /> -
  75. <input id="datebox_todate" type="datetime" class="easyui-datebox" style="width:120px; " />
  76. <a href="#" id="btn_search" data-options="iconCls:'icon-search'" class="easyui-linkbutton">查询</a>
  77. </div>
  78. </div>
  79. <table id="article_list"></table>
  80. <script src="~/Scripts/Common.js"></script>
  81. <script type="text/javascript">
  82. $("#article_list").datagrid({
  83. loadMsg: '加载中……',
  84. pagination:true,
  85. url: '@Url.Action("MyJsonList", "Article")',
  86. columns: [[
  87. { field: 'ModelID', title: 'ID', checkbox: true },
  88. { field: 'CategoryName', title: '栏目'},
  89. { field: 'Title', title: '标题'},
  90. { field: 'Inputer', title: '录入', align: 'right' },
  91. { field: 'Hits', title: '点击', align: 'right' },
  92. { field: 'ReleaseDate', title: '发布日期', align: 'right', formatter: function (value, row, index) { return jsonDateFormat(value); } },
  93. { field: 'StatusString', title: '状态', width: 100, align: 'right' }
  94. ]],
  95. toolbar: '#toolbar',
  96. idField: 'ModelID',
  97. onDblClickRow: function (rowIndex, rowData) { window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rowData.ModelID, "icon-page"); }
  98. });
  99. //查找
  100. $("#btn_search").click(function () {
  101. $("#article_list").datagrid('load', {
  102. title: $("#textbox_title").val(),
  103. fromDate: $("#datebox_fromdate").datebox('getValue'),
  104. toDate: $("#datebox_todate").datebox('getValue')
  105. });
  106. });
  107. //修改事件
  108. function eidt() {
  109. var rows = $("#article_list").datagrid("getSelections");
  110. if (!rows || rows.length < 1) {
  111. $.messager.alert("提示", "请选择要修改的行!");
  112. return;
  113. }
  114. else if (rows.length != 1) {
  115. $.messager.alert("提示", "仅能选择一行!");
  116. return;
  117. }
  118. else {
  119. window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rows[0].ModelID, "icon-page");
  120. }
  121. }
  122. //删除
  123. function del()
  124. {
  125. var rows = $("#article_list").datagrid("getSelections");
  126. if (!rows || rows.length < 1) {
  127. $.messager.alert("提示", "未选择任何行!");
  128. return;
  129. }
  130. else if (rows.length > 0) {
  131. $.messager.confirm("确认", "您确定要删除所选行吗?", function (r) {
  132. if (r) {
  133. $.messager.progress();
  134. $.each(rows, function (index, value) {
  135. $.ajax({
  136. type: "post",
  137. url: "@Url.Action("Delete", "Article")",
  138. data: { id: value.ModelID },
  139. async: false,
  140. success: function (data) {
  141. }
  142. });
  143. });
  144. $.messager.progress('close');
  145. //清除选择行
  146. rows.length = 0;
  147. $("#article_list").datagrid('reload');
  148. }
  149. });
  150. return;
  151. }
  152. }
  153. </script>

要注意的是删除文章时删除的次序,修改文章时TryUpdateModel的使用,希望本文对大家的学习有所帮助。

人气教程排行