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

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

(0)

相关推荐

  • .NET连接MongoDB数据库实例教程

    使用代码 让我们从Mongo数据库的一些细节和基本命令开始,并最终介绍如何创建一个可连接至Mongo数据库的.NET Windows应用. Mongo数据库 MongoDB 是一个跨平台.文档导向的数据库系统,它被归类为"NoSQL"数据库.MongoDB避开了传统的基于表的关系数据库结构,而是使用了带动态模式的类JSON文档.MongoDB将这种格式称为BSON(二进制JSON).这种动态模式使得特定类型应用中的数据整合更简单.更快速.MongoDB是自由且开源的软件. Mongo数

  • MongoDB.NET 2.2.4驱动版本对Mongodb3.3数据库中GridFS增删改查

    本文实例为大家分享了针对Mongodb3.3数据库中GridFS增删改查,供大家参考,具体内容如下 Program.cs代码如下: internal class Program { private static void Main(string[] args) { GridFSHelper helper = new GridFSHelper("mongodb://localhost", "GridFSDemo", "Pictures"); #re

  • 在.Net中使用MongoDB的方法教程

    什么是MongoDB MongoDB是基于文档的存储的(而非表),是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型.Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引.Mongo主要解决的是海量数据的访问效率问题.因为Mongo主要是支持海量数据存储的,所以M

  • 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; } pub

  • ASP.NET MVC4异步聊天室的示例代码

    本文介绍了ASP.NET MVC4异步聊天室的示例代码,分享给大家,具体如下: 类图: Domain层 IChatRoom.cs using System; using System.Collections.Generic; namespace MvcAsyncChat.Domain { public interface IChatRoom { void AddMessage(string message); void AddParticipant(string name); void GetM

  • 基于Asp.Net MVC4 Bundle捆绑压缩技术的介绍

    很高兴,最近项目用到了Asp.Net MVC4 + Entity Framework5,发现mvc4加入了Bundle.Web API等技术,着实让我兴奋,以前是用第三方的,这里主要说说Bundle技术. 很多大网站都没有用Bundle技术造成很多资源浪费与性能的牺牲,别小瞧 用上了你会发现他的好处: 将多个请求捆绑为一个请求,减少服务器请求数 没有使用Bundle技术,debug下看到的是实际的请求数与路径 使用Bundle技术,并且拥有缓存功能调试设置为Release模式并按F5或修改web

  • javaWEB实现相册管理的简单功能

    这仅仅只是一个小小的相册管理,主要实现的功能:能够实现对图片的上传,统一浏览,单个下载,单个删除,只能删除自己上传的文件. 现在对每个功能进行单个的解释: 图片的上传  图片的上传在之前的文章中写的很清楚了,点击打开链接:<JavaEE实现前后台交互的文件上传与下载> . 在这个相册管理中,就不是单一的文件传了,还需要涉及到很多参数供其他功能模块的使用 <span style="font-size:24px;">//上传文件一般采用外面的 apache的上传工具

  • Asp.Net MVC4通过id更新表单内容的思路详解

    用户需求是:一个表单一旦创建完,其中大部分的字段便不可再编辑.只能编辑其中部分字段. 而不可编辑是通过对input输入框设置disabled属性实现的,那么这时候直接向数据库中submit表单中的内容就会报错,因为有些不能为null的字段由于disabled属性根本无法在前端被获取而后更新至数据库. 有下面两种思路: 1.通过创建隐藏表单,为每一个disabled控件分别创建一个隐藏控件,但是这样的问题是工作量太大(如果表单有一千个属性,你懂的) 2.通过获取该表单在数据库中的id,把该id和可

  • ASP.NET MVC4 利用uploadify.js多文件上传

    页面代码: 1.引入js和css文件 <link href="~/Scripts/uploadify/uploadify.css" rel="external nofollow" rel="stylesheet" /> <style type="text/css"> #upDiv { width: 550px; height: 400px; border: 2px solid red; margin-t

  • ASP.NET MVC4中使用Html.DropDownListFor的方法示例

    本文实例讲述了ASP.NET MVC4中使用Html.DropDownListFor的方法.分享给大家供大家参考,具体如下: 一.控制器部分: public ActionResult PageDetail() { var thisList = _sysDepartmentBll.GetAllDepartmentList();//数据源 //添加一条默认数据 var resultList = new List<SelectListItem> { new SelectListItem {Text

  • MongoDB快速入门笔记(七)MongoDB的用户管理操作

    MongoDB 简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 1.修改启动MongoDB时要求用户验证 加参数 --auth 即可. 现在我们把MongoDB服务删除,再重新添加服务 复制代码 代码如下: mongod --dbpath "D:\work\MongoDB\data" --

  • Html5+jQuery+CSS制作相册小记录

    本文主要讲述采用Html5+jQuery+CSS 制作相册的小小记录. 主要功能点: Html5进行布局 调用jQuery(借用官网的一句话:The Write Less, Do More)极大的简化了JavaScript编程 CSS 样式将表现与内容分离 话不多说,先上效果图: 代码如下: <!DOCTYPE html> <html> <head> <title>The second html page</title> <style ty

  • ASP.NET MVC4入门教程(一):入门介绍

    前言 本教程将为您讲解使用微软的Visual Studio Express 2012或Visual Web Developer 2010 Express Service Pack 1 来建立一个ASP.NET MVC4 Web应用程序所需要的基础知识.建议您使用Visual Studio 2012,你将不再需要安装任何组件,来完成此教程.如果您使用的是Visual Studio 2010,您必须安装下面的组件.您可以通过点击下面的链接,来安装所需的所有组件: Visual Studio Web

随机推荐