Welcome

首页 / 网页编程 / ASP.NET / ASP.NET MVC4使用MongoDB制作相册管理

ASP.NET MVC4使用MongoDB制作相册管理实例分享
TIPS:1.Image转成Base64保存到mongodb字段
         2.数据模型是嵌套的关联 

首先定义Model层: 

 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++];elsethrow new IndexOutOfRangeException();}public bool HasNext(){if (count < collection.Count - 1)return true;elsereturn false;}public Photo Next(){if (HasNext())return collection[++count];elsethrow 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;}elsethrow new ArgumentException();}public bool InsertPictures(List<Photo> photos){foreach(var photo in photos){if (!Pictures.Contains(photo)){Pictures.Add(photo);}elsethrow 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代码如下: 

 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代码如下: 
 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 

@{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数据存储结构图:



以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。