本文实例为大家分享了MVC4图书管理系统的制作教程,供大家参考,具体内容如下
首先项目结构图:
Model层的相关代码如下:
Book.cs代码如下:
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Book { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get ; set ; } [MaxLength(500)] [Display(Name = "标题" )] public string Title { get ; set ; } [MaxLength(5000)] [Display(Name = "前言" )] public string Foreword { get ; set ; } [Display(Name = "总页数" )] public int Pages { get ; set ; } [Display(Name = "作者" )] public string Author { get ; set ; } } |
1
|
2
3
4
5
6
7
8
|
public class AppContext:DbContext { public AppContext() { } public DbSet<Book> Books { get ; set ; } } |
ViewModels的相关:
1
|
2
3
4
5
6
7
8
9
10
11
|
public class SearchViewModel { public string Query { get ; set ; } public IEnumerable<IHit<Book>> Results { get ; set ; } public IDictionary< string , Suggest[]> Suggestions { get ; set ; } public long Elapsed { get ; set ; } } |
接下来就HomeController.cs和BooksController.cs的代码:
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
|
public class HomeController : Controller { private SearchService _searchService; public HomeController() { _searchService = new SearchService(); } public ActionResult Index() { return View(); } public ActionResult Search( string query, int page = 0, int pageSize = 10) { var result = _searchService.Find(query, page, pageSize); var suggestion = _searchService.FindPhraseSuggestion(query, 0, 3); var viewModel = new SearchViewModel { Query = query, Results = result.Item1,Elapsed = result.Item2, Suggestions = suggestion }; return View( "Index" , viewModel); } } |
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
|
public class BooksController : Controller { private AppContext db = new AppContext(); public ActionResult Index() { return View(db.Books.ToList()); } public ActionResult Details(Guid? id) { if (id == null ) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Book book = db.Books.Find(id); if (book == null ) { return HttpNotFound(); } return View(book); } public ActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include= "Id,Title,Foreword,Pages,Author" )] Book book) { if (ModelState.IsValid) { book.Id = Guid.NewGuid(); db.Books.Add(book); db.SaveChanges(); //添加书 Elasticsearch.Elasticsearch.Client.Index<Book>(book); return RedirectToAction( "Index" ); } return View(book); } public ActionResult Edit(Guid? id) { if (id == null ) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Book book = db.Books.Find(id); if (book == null ) { return HttpNotFound(); } return View(book); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include= "Id,Title,Foreword,Pages,Author" )] Book book) { if (ModelState.IsValid) { db.Entry(book).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction( "Index" ); } return View(book); } public ActionResult Delete(Guid? id) { if (id == null ) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Book book = db.Books.Find(id); if (book == null ) { return HttpNotFound(); } return View(book); } [HttpPost, ActionName( "Delete" )] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(Guid id) { Book book = db.Books.Find(id); db.Books.Remove(book); db.SaveChanges(); return RedirectToAction( "Index" ); } public JsonResult Reindex() { foreach (var book in db.Books) { //Indexing book Elasticsearch.Elasticsearch.Client.Index<Book>(book); } return Json( "OK" ,JsonRequestBehavior.AllowGet); } protected override void Dispose( bool disposing) { if (disposing) { db.Dispose(); } base .Dispose(disposing); } } |
Elasticsearch辅助类:
首先是Elasticsearch.cs
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class Elasticsearch { private static ElasticClient _client; public static ElasticClient Client { get { if (_client == null ) { //连接配置 var setting = new ConnectionSettings(ElasticsearchConfiguration.Connection,ElasticsearchConfiguration.DefaultIndex); _client = new ElasticClient(setting); } return _client; } } } |
ElasticsearchConfiguration.cs类
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public static class ElasticsearchConfiguration { public static string Host { get { return " http://localhost " ; } } public static long Port { get { return 9200; } } public static Uri Connection { get { return new Uri( string .Format( "{0}:{1}" , Host, Port)); } } public static string DefaultIndex { get { return "library" ; } } } |
SearchService.cs代码:
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
|
public class SearchService { public double MinScore { get { return 0.0005; }} //高亮标记前缀 public string PreHighlightTag { get { return @"<strong>" ; } } //高亮标记后缀 public string PostHighlightTag { get { return @"</strong>" ; } } public Tuple< IEnumerable<IHit<Book>>, long > Find( string query, int page = 0, int pageSize = 10) { var result = Elasticsearch.Elasticsearch.Client.Search<Book>(s => s .From(page * pageSize) .Size(pageSize) .MinScore(MinScore) .Highlight(h => h .PreTags(PreHighlightTag) .PostTags(PostHighlightTag) .OnFields( f => f.OnField(b => b.Foreword), f => f.OnField(b => b.Title) )) .Query(q => q.QueryString(qs => qs.Query(query).UseDisMax()))); return new Tuple<IEnumerable<IHit<Book>>, long >(result.Hits,result.ElapsedMilliseconds); } //查找短语建议 public IDictionary< string , Suggest[]> FindPhraseSuggestion( string phrase, int page = 0, int pageSize = 5) { var result = Elasticsearch.Elasticsearch.Client.Search<Book>(s => s .From(page*pageSize) .Size(pageSize) .SuggestPhrase( "did-you-mean" , ps => ps .Text(phrase) .OnField(f => f.Foreword)) .Query(q => q.MatchAll())); return result.Suggest; } public IEnumerable<IHit<Book>> FindAll() { var result = Elasticsearch.Elasticsearch.Client.Search<Book>(s => s.AllIndices()); return result.Hits; } } |
Views视图
Books文件夹下:
Index.cshtml:
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
|
@model IEnumerable< Library.Web.Models.Book > @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } < h2 >Index</ h2 > < p > @Html.ActionLink("创建新书", "Create") </ p > < table class = "table" > < tr > < th > @Html.DisplayNameFor(model => model.Title) </ th > < th > @Html.DisplayNameFor(model => model.Foreword) </ th > < th > @Html.DisplayNameFor(model => model.Pages) </ th > < th > @Html.DisplayNameFor(model => model.Author) </ th > < th ></ th > </ tr > @foreach (var item in Model) { < tr > < td > @Html.DisplayFor(modelItem => item.Title) </ td > < td > @Html.DisplayFor(modelItem => item.Foreword) </ td > < td > @Html.DisplayFor(modelItem => item.Pages) </ td > < td > @Html.DisplayFor(modelItem => item.Author) </ td > < td > @Html.ActionLink("编辑", "Edit", new { id=item.Id }) | @Html.ActionLink("详细", "Details", new { id=item.Id }) | @Html.ActionLink("删除", "Delete", new { id=item.Id }) </ td > </ tr > } </ table > |
Edit.cshtml:
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
|
@model Library.Web.Models.Book @{ ViewBag.Title = "Edit"; Layout = "~/Views/Shared/_Layout.cshtml"; } < h2 >Edit</ h2 > @using (Html.BeginForm()) { @Html.AntiForgeryToken() < div class = "form-horizontal" > < h4 >Book</ h4 > < hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.Id) < div class = "form-group" > @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Foreword, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.TextAreaFor(model => model.Foreword) @Html.ValidationMessageFor(model => model.Foreword) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Pages, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Pages) @Html.ValidationMessageFor(model => model.Pages) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Author, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Author) @Html.ValidationMessageFor(model => model.Author) </ div > </ div > < div class = "form-group" > < div class = "col-md-offset-2 col-md-10" > < input type = "submit" value = "Save" class = "btn btn-default" /> </ div > </ div > </ div > } < div > @Html.ActionLink("返回列表", "Index") </ div > @section Scripts { @Scripts.Render("~/bundles/jqueryval") } |
Details.cshtml:
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
|
@model Library.Web.Models.Book @{ ViewBag.Title = "Details"; Layout = "~/Views/Shared/_Layout.cshtml"; } < h2 >Details</ h2 > < div > < h4 >Book</ h4 > < hr /> < dl class = "dl-horizontal" > < dt > @Html.DisplayNameFor(model => model.Title) </ dt > < dd > @Html.DisplayFor(model => model.Title) </ dd > < dt > @Html.DisplayNameFor(model => model.Foreword) </ dt > < dd > @Html.DisplayFor(model => model.Foreword) </ dd > < dt > @Html.DisplayNameFor(model => model.Pages) </ dt > < dd > @Html.DisplayFor(model => model.Pages) </ dd > < dt > @Html.DisplayNameFor(model => model.Author) </ dt > < dd > @Html.DisplayFor(model => model.Author) </ dd > </ dl > </ div > < p > @Html.ActionLink("编辑", "Edit", new { id = Model.Id }) | @Html.ActionLink("返回列表", "Index") </ p > |
Delete.cshtml:
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
|
@model Library.Web.Models.Book @{ ViewBag.Title = "Delete"; Layout = "~/Views/Shared/_Layout.cshtml"; } < h2 >Delete</ h2 > < h3 >Are you sure you want to delete this?</ h3 > < div > < h4 >Book</ h4 > < hr /> < dl class = "dl-horizontal" > < dt > @Html.DisplayNameFor(model => model.Title) </ dt > < dd > @Html.DisplayFor(model => model.Title) </ dd > < dt > @Html.DisplayNameFor(model => model.Foreword) </ dt > < dd > @Html.DisplayFor(model => model.Foreword) </ dd > < dt > @Html.DisplayNameFor(model => model.Pages) </ dt > < dd > @Html.DisplayFor(model => model.Pages) </ dd > < dt > @Html.DisplayNameFor(model => model.Author) </ dt > < dd > @Html.DisplayFor(model => model.Author) </ dd > </ dl > @using (Html.BeginForm()) { @Html.AntiForgeryToken() < div class = "form-actions no-color" > < input type = "submit" value = "Delete" class = "btn btn-default" /> | @Html.ActionLink("返回列表", "Index") </ div > } </ div > |
Create.cshtml:
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
|
@model Library.Web.Models.Book @{ ViewBag.Title = "Create"; Layout = "~/Views/Shared/_Layout.cshtml"; } < h2 >创建</ h2 > @using (Html.BeginForm()) { @Html.AntiForgeryToken() < div class = "form-horizontal" > < h4 >Book</ h4 > < hr /> @Html.ValidationSummary(true) < div class = "form-group" > @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Foreword, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.TextAreaFor(model => model.Foreword) @Html.ValidationMessageFor(model => model.Foreword) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Pages, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Pages) @Html.ValidationMessageFor(model => model.Pages) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Author, new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Author) @Html.ValidationMessageFor(model => model.Author) </ div > </ div > < div class = "form-group" > < div class = "col-md-offset-2 col-md-10" > < input type = "submit" value = "创建" class = "btn btn-default" /> </ div > </ div > </ div > } < div > @Html.ActionLink("回到列表", "Index") </ div > @section Scripts { @Scripts.Render("~/bundles/jqueryval") } |
Home->Index.cshtml
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
|
@model Library.Web.ViewModels.SearchViewModel @{ ViewBag.Title = "Elasticsearch"; } < div class = "jumbotron" > < h1 >Elasticsearch入门</ h1 > < p class = "lead" >安装和配置群集</ p > < ol > < li > < a href=" http://www.oracle.com/technetwork/java/ javase/downloads/index.html">安装Java</ a > </ li > < li > < a href=" http://www.elasticsearch.org/ download/">安装Elasticsearch</ a > </ li > < li >运行Elasticsearch</ li > < li >< a href = "/Books/Create" >增加一些书籍</ a ></ li > </ ol > </ div > @if (Model == null) { return; } < div style = "margin-top: 30px;" > @if (Model.Suggestions.Any(x => x.Key == "did-you-mean")) { < span >你的意思是: </ span > foreach (var suggestions in Model.Suggestions["did-you-mean"]) { var count = 0; foreach (var suggestion in suggestions.Options) { < a href = "/Home/Search?query=@suggestion.Text" >< strong >@suggestion.Text </ strong > </ a > count++; } if (count == 0) { < span class = "alert-danger" >没有建议!</ span > } } } </ div > < h3 >< strong >Results for:</ strong > @Model.Query</ h3 > @if (Model != null) { < table class = "table table-condensed" > < thead > < tr >< th >文档的分数(排名相关度)</ th >< th >Title</ th >< th >Content</ th >< th >Author</ th ></ tr > </ thead > < tbody > @foreach (var result in Model.Results) { < tr > < td >@result.Score</ td > < td > < a href = "/Books/Details/@result.Id" > @if (result.Highlights != null && result.Highlights.Any(x => x.Key == "title")) { var hl = result.Highlights.FirstOrDefault(x => x.Key == "title"); foreach (var h in hl.Value.Highlights) { WriteLiteral(h); } } else { WriteLiteral(result.Source.Title); } </ a > </ td > < td > @if (result.Highlights != null && result.Highlights.Any(x => x.Key == "foreword")) { var hl = result.Highlights.FirstOrDefault(x => x.Key == "foreword"); foreach (var h in hl.Value.Highlights) { WriteLiteral(h + "..."); } } </ td > < td >@result.Source.Author</ td > </ tr > } @if (!Model.Results.Any()) { < tr > < td colspan = "4" class = "alert alert-danger" style = "text-align:center;" >没有结果发现:(</ td > </ tr > } </ tbody > </ table > < h4 >< span class = "label label-default" >@Model.Results.Count()</ span >搜索结果用了 @Model.Elapsed 毫秒</ h4 > } |
_Layout.cshtml
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
|
<!DOCTYPE html> < html > < head > < meta charset = "utf-8" /> < meta name = "viewport" content = "width=device-width, initial-scale=1.0" > < title >@ViewBag.Title</ title > @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </ head > < body > < div class = "navbar navbar-inverse navbar-fixed-top" > < div class = "container" > < div class = "navbar-header" > < button type = "button" class = "navbar-toggle" data-toggle = "collapse" data-target = ".navbar-collapse" > < span class = "icon-bar" ></ span > < span class = "icon-bar" ></ span > < span class = "icon-bar" ></ span > </ button > @Html.ActionLink("Elasticsearch MVC示例", "Index", "Home", null, new { @class = "navbar-brand" }) </ div > < div class = "navbar-collapse collapse" > < ul class = "nav navbar-nav" > < li >@Html.ActionLink("Home", "Index", "Home")</ li > < li >@Html.ActionLink("Books", "Index", "Books")</ li > </ ul > @using (Html.BeginForm("Search", "Home", FormMethod.Get,new {@class = "navbar-form navbar-left"})) { < div class = "form-group" > < input class = "form-control" type = "text" placeholder = "搜索" name = "query" /> </ div > < button type = "submit" class = "btn btn-default" >提交</ button > } </ div > </ div > </ div > < div class = "container body-content" > @RenderBody() < hr /> < footer > < p >© @DateTime.Now.Year - Elasticsearch, Nest, ASP.NET 应用</ p > </ footer > </ div > @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </ body > </ html > |
结果如图:
列表页
创建页:
搜索结果页:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。