上次做了顯示文章列表,再實現修改和刪除文章這部分內容就結束了,這次內容比較簡單,由于做過了添加文章,修改文章非常類似,就是多了一個TryUpdateModel部分更新模型數據。
一、刪除文章
由于公共模型跟,文章,附件有關聯,所以這里的刪除次序很重要,如果先刪除模型,那么文章ModelID和附件的ModelID多會變成null,所以要先先刪除文章和附件再刪除公共模型。
由于公共模型和附件是一對多的關系,我們把刪除公共模型和刪除附件寫在一起。
在BLL的BaseRepository類中有默認的Delete方法,但這個方法中僅刪除模型,不會刪除外鍵,所以在CommonModelRepository在new一個出來封印掉默認的方法。
1
2
3
4
5
6
|
public new bool Delete(Models.CommonModel commonModel, bool isSave = true) { if (commonModel.Attachment != null) nContext.Attachments.RemoveRange(commonModel.Attachment); nContext.CommonModels.Remove(commonModel); return isSave ? nContext.SaveChanges() > 0 : true; } |
這個的意思是封印掉繼承的Delete方法,在新的方法中如果存在附加那么先刪除附件,再刪除公共模型。那么如果我們還想調用基類的Delete方法怎么辦?可以用base.Delete。
好了,現在可以開始刪除了。
在ArticleController中添加Delete方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/// < summary > /// 刪除 /// </ summary > /// < param name = "id" >文章id</ param > /// < returns ></ returns > public JsonResult Delete(int id) { //刪除附件 var _article = articleService.Find(id); if(_article == null) return Json(false); //附件列表 var _attachmentList = _article.CommonModel.Attachment; var _commonModel = _article.CommonModel; //刪除文章 if (articleService.Delete(_article)) { //刪除附件文件 foreach (var _attachment in _attachmentList) { System.IO.File.Delete(Server.MapPath(_attachment.FileParth)); } //刪除公共模型 commonModelService.Delete(_commonModel); return Json(true); } else return Json(false); } |
二、修改文章
這個部分跟添加文章非常類似
首先在ArticleController中添加顯示編輯視圖的Edit
1
2
3
4
5
6
7
8
9
|
/// < summary > /// 修改 /// </ summary > /// < param name = "id" ></ param > /// < returns ></ returns > public ActionResult Edit(int id) { return View(articleService.Find(id)); } |
右鍵添加視圖,這個跟添加類似,沒什么好說的直接上代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
@section scripts{ < script type = "text/javascript" src = "~/Scripts/KindEditor/kindeditor-min.js" ></ script > < script type = "text/javascript" > //編輯框 KindEditor.ready(function (K) { window.editor = K.create('#Content', { height: '500px', uploadJson: '@Url.Action("Upload", "Attachment")', fileManagerJson: '@Url.Action("FileManagerJson", "Attachment", new { id = @Model.CommonModel.ModelID })', allowFileManager: true, formatUploadUrl: false }); //首頁圖片 var editor2 = K.editor({ fileManagerJson: '@Url.Action("FileManagerJson", "Attachment", new {[email protected] })' }); K('#btn_picselect').click(function () { editor2.loadPlugin('filemanager', function () { editor2.plugin.filemanagerDialog({ viewType: 'VIEW', dirName: 'image', clickFn: function (url, title) { var url; $.ajax({ type: "post", url: "@Url.Action("CreateThumbnail", "Attachment")", data: { originalPicture: url }, async: false, success: function (data) { if (data == null) alert("生成縮略圖失敗!"); else { K('#CommonModel_DefaultPicUrl').val(data); K('#imgpreview').attr("src", data); } editor2.hideDialog(); } }); } }); }); }); }); </ script > } @model Ninesky.Models.Article @using (Html.BeginForm()) { @Html.AntiForgeryToken() < div class = "form-horizontal" role = "form" > < h4 >添加文章</ h4 > < hr /> @Html.ValidationSummary(true) < div class = "form-group" > < label class = "control-label col-sm-2" for = "CommonModel_CategoryID" >欄目</ label > < div class = "col-sm-10" > < 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" /> @Html.ValidationMessageFor(model => model.CommonModel.CategoryID)</ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.CommonModel.Title, new { @class = "control-label col-sm-2" }) < div class = "col-sm-10" > @Html.TextBoxFor(model => model.CommonModel.Title, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.CommonModel.Title)</ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Author, new { @class = "control-label col-sm-2" }) < div class = "col-sm-10" > @Html.TextBoxFor(model => model.Author, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Author) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Source, new { @class = "control-label col-sm-2" }) < div class = "col-sm-10" > @Html.TextBoxFor(model => model.Source, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Source) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Intro, new { @class = "control-label col-sm-2" }) < div class = "col-sm-10" > @Html.TextAreaFor(model => model.Intro, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Intro) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Content, new { @class = "control-label col-sm-2" }) < div class = "col-sm-10" > @Html.EditorFor(model => model.Content) @Html.ValidationMessageFor(model => model.Content) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.CommonModel.DefaultPicUrl, new { @class = "control-label col-sm-2" }) < div class = "col-sm-10" > < img id = "imgpreview" class = "thumbnail" src = "@Model.CommonModel.DefaultPicUrl" /> @Html.HiddenFor(model => model.CommonModel.DefaultPicUrl) < a id = "btn_picselect" class = "easyui-linkbutton" >選擇…</ a > @Html.ValidationMessageFor(model => model.CommonModel.DefaultPicUrl) </ div > </ div > < div class = "form-group" > < div class = "col-sm-offset-2 col-sm-10" > < input type = "submit" value = "保存" class = "btn btn-default" /> </ div > </ div > </ div > } |
開始做后臺接受代碼,在ArticleController中添加如下代碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
[HttpPost] [ValidateInput(false)] [ValidateAntiForgeryToken] public ActionResult Edit() { int _id = int.Parse(ControllerContext.RouteData.GetRequiredString("id")); var article = articleService.Find(_id); TryUpdateModel(article, new string[] { "Author", "Source", "Intro", "Content" }); TryUpdateModel(article.CommonModel, "CommonModel", new string[] { "CategoryID", "Title", "DefaultPicUrl" }); if(ModelState.IsValid) { if (articleService.Update(article)) { //附件處理 InterfaceAttachmentService _attachmentService = new AttachmentService(); var _attachments = _attachmentService.FindList(article.CommonModel.ModelID, User.Identity.Name, string.Empty,true).ToList(); foreach (var _att in _attachments) { var _filePath = Url.Content(_att.FileParth); if ((article.CommonModel.DefaultPicUrl != null && article.CommonModel.DefaultPicUrl.IndexOf(_filePath) >= 0) || article.Content.IndexOf(_filePath) > 0) { _att.ModelID = article.ModelID; _attachmentService.Update(_att); } else { System.IO.File.Delete(Server.MapPath(_att.FileParth)); _attachmentService.Delete(_att); } } return View("EditSucess", article); } } return View(article); } |
詳細講解一下吧:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
<script type= "text/javascript" > $( "#article_list" ).datagrid({ loadMsg: '加載中……' , pagination: true , url: '@Url.Action("JsonList","Article")' , columns: [[ { field: 'ModelID' , title: 'ID' , checkbox: true }, { field: 'CategoryName' , title: '欄目' }, { field: 'Title' , title: '標題' }, { field: 'Inputer' , title: '錄入' , align: 'right' }, { field: 'Hits' , title: '點擊' , align: 'right' }, { field: 'ReleaseDate' , title: '發布日期' , align: 'right' , formatter: function (value, row, index) { return jsonDateFormat(value); } }, { field: 'StatusString' , title: '狀態' , width: 100, align: 'right' } ]], toolbar: '#toolbar' , idField: 'ModelID' , onDblClickRow: function (rowIndex, rowData) { window.parent.addTab( "修改文章" , "@Url.Action(" Edit "," Article ")/" + rowData.ModelID, "icon-page" ); } }); //查找 $( "#btn_search" ).click( function () { $( "#article_list" ).datagrid( 'load' , { title: $( "#textbox_title" ).val(), input: $( "#textbox_inputer" ).val(), category: $( "#combo_category" ).combotree( 'getValue' ), fromDate: $( "#datebox_fromdate" ).datebox( 'getValue' ), toDate: $( "#datebox_todate" ).datebox( 'getValue' ) }); }); //修改事件 function eidt() { var rows = $( "#article_list" ).datagrid( "getSelections" ); if (!rows || rows.length < 1) { $.messager.alert( "提示" , "請選擇要修改的行!" ); return ; } else if (rows.length != 1) { $.messager.alert( "提示" , "僅能選擇一行!" ); return ; } else { window.parent.addTab( "修改文章" , "@Url.Action(" Edit "," Article ")/" + rows[0].ModelID, "icon-page" ); } } //刪除 function del() { var rows = $( "#article_list" ).datagrid( "getSelections" ); if (!rows || rows.length < 1) { $.messager.alert( "提示" , "未選擇任何行!" ); return ; } else if (rows.length > 0) { $.messager.confirm( "確認" , "您確定要刪除所選行嗎?" , function (r) { if (r) { $.messager.progress(); $.each(rows, function (index, value) { $.ajax({ type: "post" , url: "@Url.Action(" Delete ", " Article ")" , data: { id: value.ModelID }, async: false , success: function (data) { } }); }); $.messager.progress( 'close' ); //清除選擇行 rows.length = 0; $( "#article_list" ).datagrid( 'reload' ); } }); return ; } } </script> |
增加了修改方法、刪除方法,在datagrid里添加行雙擊進入修改視圖的方法
onDblClickRow: function (rowIndex, rowData) { window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rowData.ModelID, "icon-page"); }
2、
四、我的文章列表
我的文章列表與全部文章類似,并簡化掉了部分內容那個,更加簡單,直接上代碼了
Article控制器中添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/// < summary > /// 文章列表Json【注意權限問題,普通人員是否可以訪問?】 /// </ summary > /// < param name = "title" >標題</ param > /// < param name = "input" >錄入</ param > /// < param name = "category" >欄目</ param > /// < param name = "fromDate" >日期起</ param > /// < param name = "toDate" >日期止</ param > /// < param name = "pageIndex" >頁碼</ param > /// < param name = "pageSize" >每頁記錄</ param > /// < returns ></ returns > public ActionResult JsonList(string title, string input, Nullable< int > category, Nullable< DateTime > fromDate, Nullable< DateTime > toDate, int pageIndex = 1, int pageSize = 20) { if (category == null) category = 0; int _total; var _rows = commonModelService.FindPageList(out _total, pageIndex, pageSize, "Article", title, (int)category, input, fromDate, toDate, 0).Select( cm => new Ninesky.Web.Models.CommonModelViewModel() { CategoryID = cm.CategoryID, CategoryName = cm.Category.Name, DefaultPicUrl = cm.DefaultPicUrl, Hits = cm.Hits, Inputer = cm.Inputer, Model = cm.Model, ModelID = cm.ModelID, ReleaseDate = cm.ReleaseDate, Status = cm.Status, Title = cm.Title }); return Json(new { total = _total, rows = _rows.ToList() }); } public ActionResult MyList() { return View(); } /// < summary > /// 我的文章列表 /// </ summary > /// < param name = "title" ></ param > /// < param name = "fromDate" ></ param > /// < param name = "toDate" ></ param > /// < param name = "pageIndex" ></ param > /// < param name = "pageSize" ></ param > /// < returns ></ returns > public ActionResult MyJsonList(string title, Nullable< DateTime > fromDate, Nullable< DateTime > toDate, int pageIndex = 1, int pageSize = 20) { int _total; var _rows = commonModelService.FindPageList(out _total, pageIndex, pageSize, "Article", title, 0, string.Empty, fromDate, toDate, 0).Select( cm => new Ninesky.Web.Models.CommonModelViewModel() { CategoryID = cm.CategoryID, CategoryName = cm.Category.Name, DefaultPicUrl = cm.DefaultPicUrl, Hits = cm.Hits, Inputer = cm.Inputer, Model = cm.Model, ModelID = cm.ModelID, ReleaseDate = cm.ReleaseDate, Status = cm.Status, Title = cm.Title }); return Json(new { total = _total, rows = _rows.ToList() }, JsonRequestBehavior.AllowGet); } 為MyList右鍵添加視圖 < div id = "toolbar" > < div > < a href = "#" class = "easyui-linkbutton" data-options = "iconCls:'icon-edit',plain:true" onclick = "eidt()" >修改</ a > < a href = "#" class = "easyui-linkbutton" data-options = "iconCls:'icon-remove',plain:true" onclick = "del()" >刪除</ a > < a href = "#" class = "easyui-linkbutton" data-options = "iconCls:'icon-reload',plain:true" onclick = "$('#article_list').datagrid('reload');" >刷新</ a > </ div > < div class = "form-inline" > < label >標題</ label > < input id = "textbox_title" class = "input-easyui" style = "width:280px" /> < label >添加日期</ label > < input id = "datebox_fromdate" type = "datetime" class = "easyui-datebox" style = "width:120px" /> - < input id = "datebox_todate" type = "datetime" class = "easyui-datebox" style = "width:120px; " /> < a href = "#" id = "btn_search" data-options = "iconCls:'icon-search'" class = "easyui-linkbutton" >查詢</ a > </ div > </ div > < table id = "article_list" ></ table > < script src = "~/Scripts/Common.js" ></ script > < script type = "text/javascript" > $("#article_list").datagrid({ loadMsg: '加載中……', pagination:true, url: '@Url.Action("MyJsonList", "Article")', columns: [[ { field: 'ModelID', title: 'ID', checkbox: true }, { field: 'CategoryName', title: '欄目'}, { field: 'Title', title: '標題'}, { field: 'Inputer', title: '錄入', align: 'right' }, { field: 'Hits', title: '點擊', align: 'right' }, { field: 'ReleaseDate', title: '發布日期', align: 'right', formatter: function (value, row, index) { return jsonDateFormat(value); } }, { field: 'StatusString', title: '狀態', width: 100, align: 'right' } ]], toolbar: '#toolbar', idField: 'ModelID', onDblClickRow: function (rowIndex, rowData) { window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rowData.ModelID, "icon-page"); } }); //查找 $("#btn_search").click(function () { $("#article_list").datagrid('load', { title: $("#textbox_title").val(), fromDate: $("#datebox_fromdate").datebox('getValue'), toDate: $("#datebox_todate").datebox('getValue') }); }); //修改事件 function eidt() { var rows = $("#article_list").datagrid("getSelections"); if (!rows || rows.length < 1 ) { $.messager.alert("提示", "請選擇要修改的行!"); return; } else if (rows.length != 1) { $.messager.alert("提示", "僅能選擇一行!"); return; } else { window.parent.addTab("修改文章", "@Url.Action("Edit","Article")/" + rows[0].ModelID, "icon-page"); } } //刪除 function del() { var rows = $("#article_list").datagrid("getSelections"); if (!rows || rows.length < 1) { $.messager.alert("提示", "未選擇任何行!"); return; } else if (rows.length > 0) { $.messager.confirm("確認", "您確定要刪除所選行嗎?", function (r) { if (r) { $.messager.progress(); $.each(rows, function (index, value) { $.ajax({ type: "post", url: "@Url.Action("Delete", "Article")", data: { id: value.ModelID }, async: false, success: function (data) { } }); }); $.messager.progress('close'); //清除選擇行 rows.length = 0; $("#article_list").datagrid('reload'); } }); return; } } </ script > |
要注意的是刪除文章時刪除的次序,修改文章時TryUpdateModel的使用,希望本文對大家的學習有所幫助。