时间:2021-07-01 10:21:17 帮助过:9人阅读
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++];
- 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代码如下:
- 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数据存储结构图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。