本文实例为大家分享了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 >
|
结果如图:
列表页
创建页:
搜索结果页:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。