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++]; 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数据存储结构图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
相关文章
- 由于要使用mikoomi mongodb plugin插件,所以需要php对mongodb的扩展支持,默认通过源安装的php并没有mongodb的扩展支持,具体可以通过php -m|grep mongo 验证 。这里就结...2016-11-25
- 这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
- 在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
ASP.NET Core根据环境变量支持多个 appsettings.json配置文件
这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22- 这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
安装使用Mongoose配合Node.js操作MongoDB的基础教程
这篇文章主要介绍了安装使用Mongoose来让Node.js操作MongoDB的基础教程,前端js+后端node+js操作MongoDB正是所谓最流行的一种JavaScript全栈开发方案,需要的朋友可以参考下...2016-03-03详解ASP.NET Core 中基于工厂的中间件激活的实现方法
这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22- 传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关...2013-09-11
修复 Mac brew 安装 mongodb 报 Error: No available formula with the name ‘mongodb’ 问题详解
最近在同事新的 Mac 电脑上安装 mongodb,报了错误 Error: No available formula with the name ‘mongodb’,今天就说说这个问题如何解决,需要的朋友可以参考下...2020-07-11asp.net通过消息队列处理高并发请求(以抢小米手机为例)
这篇文章主要介绍了asp.net通过消息队列处理高并发请求(以抢小米手机为例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22ASP.NET单选按钮控件RadioButton常用属性和方法介绍
RadioButton又称单选按钮,其在工具箱中的图标为 ,单选按钮通常成组出现,用于提供两个或多个互斥选项,即在一组单选钮中只能选择一个...2021-09-22ASP.NET 2.0中的数据操作:使用两个DropDownList过滤的主/从报表
在前面的指南中我们研究了如何显示一个简单的主/从报表, 该报表使用DropDownList和GridView控件, DropDownList填充类别,GridView显示选定类别的产品. 这类报表用于显示具有...2016-05-19Windows10安装MongoDB4.0详细步骤及启动配置教程
这篇文章主要介绍了Windows10安装MongoDB4.0详细步骤及启动配置教程 ,本文通过图文并茂的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11- 这篇文章主要介绍了MongoDb CPU利用率过高问题如何解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-12-08
ASP.NET中iframe框架点击左边页面链接 右边显示链接页面内容
这篇文章主要介绍了ASP.NET中iframe框架点击左边页面链接,右边显示链接页面内容的实现代码,感兴趣的小伙伴们可以参考一下...2021-09-22- ASP.NET Web API具有与ASP.NET MVC类似的编程方式,ASP.NET Web API不仅仅具有一个完全独立的消息处理管道,而且这个管道比为ASP.NET MVC设计的管道更为复杂,功能也更为强大。下面创建一个简单的Web API项目,需要的朋友可以参考下...2021-09-22
- 这篇文章主要介绍了CentOS7.2 安装 MongoDB 3.4的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11
- 这篇文章主要介绍了NestJs使用Mongoose对MongoDB操作的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-22
- 这篇文章主要介绍了ASP.NET连接MySql数据库的2个方法及示例,使用的是MySQL官方组件和ODBC.NET,需要的朋友可以参考下...2021-09-22
- 这篇文章主要介绍了Asp.Net使用Bulk实现批量插入数据的方法,对于进行asp.net数据库程序设计非常有借鉴价值,需要的朋友可以参考下...2021-09-22