ASP.NET MVC4使用MongoDB制作相册管理实例分享
TIPS:1.Image转成Base64保存到mongodb字段
2.数据模型是嵌套的关联
首先定义Model层:
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
158
159
160
161
162
163
164
165
166
167
168
|
public class Photo : IEquatable<Photo> { [Required] public string PhotoName { get ; set ; } [Required] public string PhotoDescription { get ; set ; } public string ServerPath { get ; set ; } public Photo() { } public Photo( string name, string desc) { PhotoName = name; PhotoDescription = desc; } public bool Equals(Photo other) { return string .Equals(PhotoName, other.PhotoName); } } public interface IAlbumIterable { bool HasNext(); Photo Current(); Photo Next(); } public interface IPhotosAggregable { IAlbumIterable GetIterator(); } public class AlbumIterator : IAlbumIterable { private Album collection; private int count; public AlbumIterator(Album album) { collection = album; } public Photo Current() { if (count < collection.Count) return collection[count++]; else throw new IndexOutOfRangeException(); } public bool HasNext() { if (count < collection.Count - 1) return true ; else return false ; } public Photo Next() { if (HasNext()) return collection[++count]; else throw new IndexOutOfRangeException(); } } public class Album : IPhotosAggregable { [BsonId] public ObjectId Id { get ; set ; } [Required] public string Name { get ; set ; } [Required] public string Description { get ; set ; } public string Owner { get ; set ; } public Photo TitlePhoto { get ; set ; } [BsonDateTimeOptions(Kind = DateTimeKind.Local,Representation =BsonType.DateTime)] public DateTime CreationTime { get ; set ; } public IList<Photo> Pictures { get ; set ; } public Album() { Pictures = new List<Photo>(); TitlePhoto = new Photo(); } public Album( string name, string owner, Photo pic) { Name = name; Owner = owner; TitlePhoto = pic; Pictures = new List<Photo>(); TitlePhoto = new Photo(); } public bool InsertPicture(Photo pic) { if (!Pictures.Contains(pic)) { Pictures.Add(pic); return true ; } else throw new ArgumentException(); } public bool InsertPictures(List<Photo> photos) { foreach (var photo in photos) { if (!Pictures.Contains(photo)) { Pictures.Add(photo); } else throw new ArgumentException(); } return true ; } public bool RemovePicture(Photo pic) { Pictures.Remove(pic); return true ; } public int Count { get { return Pictures.Count; } } public Photo this [ int index] { get { return Pictures[index]; } set { Pictures[index] = value; } } public IAlbumIterable GetIterator() { return new AlbumIterator( this ); } } |
Services层的MongoAlbumPerformer.cs和ServerPathFinder.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
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
|
public class MongoAlbumPerformer { protected static IMongoClient client; protected static IMongoDatabase database; private static IMongoCollection<Album> collection; private string collectionName; public MongoAlbumPerformer( string databaseName, string collectionName) { client = new MongoClient(ConfigurationManager.ConnectionStrings[ "mongoDB" ].ConnectionString); database = client.GetDatabase(databaseName); this .collectionName = collectionName; collection = database.GetCollection<Album>(collectionName, new MongoCollectionSettings { AssignIdOnInsert = true }); } public void SetCollection( string collectionName) { this .collectionName = collectionName; collection = database.GetCollection<Album>(collectionName); } public void CreateAlbum(Album album) { var document = new Album { Name = album.Name, Owner = HttpContext.Current.User.Identity.Name, Description = album.Description, CreationTime = DateTime.Now, TitlePhoto = album.TitlePhoto, Pictures = album.Pictures }; collection.InsertOne(document); } public List<Album> GetAlbumsByUserName( string username) { var projection = Builders<Album>.Projection .Include(a => a.Name) .Include(a => a.Description) .Include(a => a.TitlePhoto) .Include(a=>a.CreationTime); var result = collection .Find(a => a.Owner == HttpContext.Current.User.Identity.Name) .Project<Album>(projection).ToList(); return result; } public Album GetPicturesByAlbumName( string albumName) { var projection = Builders<Album>.Projection .Include(a => a.Pictures); var result = collection .Find(a => a.Owner == HttpContext.Current.User.Identity.Name & a.Name == albumName) .Project<Album>(projection).FirstOrDefault(); return result; } public void UpdateAlbumAddPhoto( string albumName, Photo photo) { var builder = Builders<Album>.Filter; var filter = builder.Eq(f => f.Name, albumName) & builder.Eq(f => f.Owner, HttpContext.Current.User.Identity.Name); var result = collection.Find(filter).FirstOrDefault(); if (result == null ) throw new ArgumentException( "No album of supplied name: {0}" , albumName); else { var picture = new Photo { PhotoName = photo.PhotoName, PhotoDescription = photo.PhotoDescription, ServerPath = photo.ServerPath, }; var update = Builders<Album>.Update.Push(a => a.Pictures, picture); collection.UpdateOne(filter, update, new UpdateOptions { IsUpsert= true }); } } public void DeletePhotoFromAlbum( string albumName, string photoName) { var builder = Builders<Album>.Filter; var filter = builder.Eq(f => f.Name, albumName) & builder.Eq(f => f.Owner, HttpContext.Current.User.Identity.Name); var result = collection.Find(filter).SingleOrDefault(); if (result == null ) throw new ArgumentException( "No album of supplied name: {0}" , albumName); else { var update = Builders<Album>.Update .PullFilter(a => a.Pictures, Builders<Photo>.Filter.Eq(p => p.PhotoName, photoName)); long count = collection.UpdateOne(filter, update).MatchedCount; } } } public class ServerPathFinder { public string GetBase64ImageString(HttpPostedFileBase file) { string mime = Regex.Match(file.ContentType, @"(?<=image/)\w+" ).Value; byte [] bytes = new byte [file.ContentLength]; file.InputStream.Read(bytes, 0, file.ContentLength); return string .Format( "data:image/{0};base64,{1}" ,mime, Convert.ToBase64String(bytes)); } } |
AlbumController.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
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
|
public class AlbumController : Controller { MongoAlbumPerformer mongod = new MongoAlbumPerformer( "test" , "albums" ); [HttpPost] public ActionResult AlbumPreview(Photo model, HttpPostedFileBase file, string albumName, string delete, string phot) { if (delete == "false" ) { if (file != null ) { if (!file.ContentType.StartsWith( "image" )) { ModelState.AddModelError( "file" , "选择正确的格式照片!" ); } else { ServerPathFinder finder = new ServerPathFinder(); model.ServerPath = finder.GetBase64ImageString(file); } if (ModelState.IsValid) { mongod.UpdateAlbumAddPhoto(albumName, model); ModelState.Clear(); } } } else { mongod.DeletePhotoFromAlbum(albumName, phot); foreach (var error in ModelState.Values) { error.Errors.Clear(); } } ViewBag.AlbumTitle = albumName; ViewBag.PhotoList = mongod.GetPicturesByAlbumName(albumName).Pictures; return View(); } public ActionResult AlbumPreview( string Name) { var album = mongod.GetPicturesByAlbumName(Name); ViewBag.AlbumTitle = Name; ViewBag.PhotoList = album.Pictures; return View(); } [HttpPost] public ActionResult Create(Album model, HttpPostedFileBase file) { if (!file.ContentType.StartsWith( "image" )) { ModelState.AddModelError( "file" , "选择正确的格式照片!" ); } else { ServerPathFinder finder = new ServerPathFinder(); model.TitlePhoto.ServerPath = finder.GetBase64ImageString(file); } if (ModelState.IsValid) { model.Owner = HttpContext.User.Identity.Name; mongod.CreateAlbum(model); } var albums = mongod.GetAlbumsByUserName(HttpContext.User.Identity.Name); ViewBag.Albums = albums; return View(); } public ActionResult Create() { var albums = mongod.GetAlbumsByUserName(HttpContext.User.Identity.Name); ViewBag.Albums = albums; return View(); } } |
部分view视图:
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
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
|
@{ ViewBag.Title = "Create"; } < h2 >我的相册</ h2 > @Html.Partial("_MyAlbums", (List< Album >)ViewBag.Albums) @using (Html.BeginForm("Create", "Album", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.AntiForgeryToken() < div class = "form-horizontal" > < h4 >创建新相册: </ h4 > < hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) < div class = "form-group" > @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" }) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.TitlePhoto, htmlAttributes: new { @class = "control-label col-md-2" }) < div class = "col-md-10" > < input type = "file" name = "file" id = "file" style = "width: 100%;" data-val = "true" data-val-required = "要求标题图片." /> @Html.ValidationMessage("file",new { @class = "text-danger" }) </ div > </ div > < div class = "form-group" > < div class = "col-md-offset-2 col-md-10" > < input type = "submit" value = "Create" class = "btn btn-default" /> </ div > </ div > </ div > } @section scripts{ @Scripts.Render("~/bundles/jqueryval") < script type = "text/javascript" > $('img').click(function (data) { }); </ script > }AlbumPreview.cshtml @{ ViewBag.Title = "AlbumPreview"; } @using (Html.BeginForm("AlbumPreview", "Album", FormMethod.Post, new { enctype = "multipart/form-data"})) { @Html.AntiForgeryToken() {Html.RenderPartial("_Preview", (List< Photo >)ViewBag.PhotoList);} < div class = "form-horizontal" > < br /> < h4 >添加新的照片:</ h4 > < hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) < div class = "form-group" > @Html.LabelFor(model => model.PhotoName, htmlAttributes: new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.PhotoName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.PhotoName, "", new { @class = "text-danger" }) </ div > </ div > < div class = "form-group" > @Html.LabelFor(model => model.PhotoDescription, htmlAttributes: new { @class = "control-label col-md-2" }) < div class = "col-md-10" > @Html.EditorFor(model => model.PhotoDescription, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.PhotoDescription, "", new { @class = "text-danger" }) </ div > </ div > < div class = "form-group" > < label class = "control-label col-md-2" >选择照片:</ label > < div class = "col-md-10" > < input type = "file" name = "file" id = "file" style = "width: 100%;" data-val = "true" data-val-required = "请选择图像" /> @Html.ValidationMessage("file", new { @class = "text-danger" }) </ div > </ div > < div class = "form-group" > < div class = "col-md-offset-2 col-md-10" > < input type = "submit" value = "Create" class = "btn btn-default" /> </ div > </ div > </ div > < input type = "hidden" name = "albumName" id = "albumName" value = "@ViewBag.AlbumTitle" /> < input type = "hidden" name = "delete" id = "delete" value = "false" /> < input type = "hidden" name = "phot" id = "phot" value = "sraka" /> } @section scripts{ @Scripts.Render("~/bundles/jqueryval") < script type = "text/javascript" > $(document).ready(function () { var elements = document.getElementsByClassName("btn btn-xs btn-warning cancel"); for (var i = 0, len = elements.length; i < len ; i++) { elements[i].addEventListener("click", function () { $('#delete').val(true); var name = $(this).attr("id"); $('#phot').val(name); $('#' + name).click(); }); } }) </script> }_Preview.cshtml @{ ViewBag.Title = "_Preview"; } < h2 >Album < span style = "color:royalblue;font-style:italic" >@ViewBag.AlbumTitle</ span ></ h2 > < div class = "row" > @foreach (var photo in Model) { < div class = "col-md-3" > < input type = "submit" id = "@photo.PhotoName" value = "删除" class = "btn btn-xs btn-warning cancel" style = "text-align:center;float:right" /> < img src = "@photo.ServerPath" class = "img-responsive img-thumbnail col-md-3" style = "width:100%;height:180px" /> < label style = "text-align:center;width:100%" >@Html.DisplayNameFor(phot=>phot.PhotoName): @photo.PhotoName</ label > < label style = "text-align:center;width:100%;font-weight:100" >@photo.PhotoDescription</ label > </ div > } </ div > |
运行项目结果如图:
首页创建相册:
《车》相册下的图片示例,可以增加图片,删除图片
《QQ》相册下的图片示例
mongodb数据存储结构图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。