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

结束!--QQ827937686

时间: 2024-10-27 05:09:58

ASP.NET MVC4使用MongoDB做的相册管理的相关文章

5、VS2010+ASP.NET MVC4+EF4+JqueryEasyUI+Oracle项目开发之——使用datagrid做报表统计

需要说明一点:数据库访问我使用的是EF框架,但是在报表统计着一块由于使用到了动态表,即根据每一天单独生成了一张数据表,所以不好使用EF进行预先添加,于是我在数据库访问层里面封装了两套数据库访问框架,一个就是EF,一个就是传统的ADO.NET.当设计到使用动态表时,我就调用用ADO.NET进行数据库访问操作了. 先看下View,这里我使用的是jquery easyUI里面的datagrid来做的报表.如下: 单击选中日报: 年报如下: @model YKT.Model.SubCompanyRepo

ASP.NET MVC4入门到精通系列目录汇总(转)

序言 最近公司在招.NET程序员,我发现好多来公司面试的.NET程序员居然都没有 ASP.NET MVC项目经验,其中包括一些工作4.5年了,甚至8年10年的,许多人给我的感觉是:工作了4.5年,Web开发依旧停留在拖控件的水平,最最基本的算 法,递归.排序(我不要求快速排序,你会冒泡就行了)都不会,数据库方面,很基础的SQL都写不出,分组过滤也不会,更别提性能了,问下数据优化经验,除 了回答加索引基本就没下文了.当然,一些过去N年都是做ASP.NET WebForm开发的,不熟悉MVC,那也没

[MVC4]初识ASP.NET MVC4

最近一个月都在专心做unity3d的斗地主游戏,从早到晚,最后总算是搞出来了,其中的心酸只有自己知道.最近才有功夫闲下来,还是学习学习之前的老本行--asp.net,现在用.net做项目流行MVC,而不是之前的三层,既然技术在更新,只能不断学习,以适应新的技术潮流! 创建MVC工程 1.打开Visual studio2012,新建MVC4工程 2.选择工程属性,创建MVC工程 3.生成工程的目录 App_Start:启动文件的配置信息,包括很重要的RouteConfig路由注册信息 Conten

ASP.NET MVC4中的App_start中BundleConfig的介绍使用

在BundleConfig.cs中,指定CSS和JS,主要用来压缩JS和CSS   在ASP.NET MVC4中(在WebForm中应该也有),有一个叫做Bundle的东西,它用来将js和css进行压缩(多个文件可以打包成一个文件),并且可以区分调试和非调试,在调试时不进行压缩,以原始方式显示出来,以方便查找问题. 具体优势可自行百度或参看官方介绍:http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification 这里仅简单记录下如

Asp.Net MVC4入门指南(1): 入门介绍

前言 本教程将为您讲解使用微软的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

[MVC4]ASP.NET MVC4+EF5(Lambda/Linq)读取数据

继续上一节初始ASP.NET MVC4,继续深入学习,感受了一下微软的MVC4+EF5(EntityFramework5)框架的强大,能够高效的开发出网站应用开发系统,下面就看一下如何用MVC4+EF5来实现数据的读取. 实现效果 操作步骤 1.创建数据库 --创建表格-- Create table News ( id int identity(1,1) primary key, NewsTitle varchar(100)not null, CreateTime Datetime, Conte

ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存

ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完美的句号,回顾2016年,感受颇多,感恩那些帮助我的人.展望2017年,我相信一定会遇到一个更好的自己.附上自己喜欢的一张图片: 好了~~~装逼结束,下面开始说说如何实现分布式缓存在项目中的应用. part2:先分析以下需求 软件架构从单机到分布式遇到的问题(当然这是一个很深的问题,由于能力有限今天

Asp.Net MVC4入门指南(8):给数据模型添加校验器

在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 保持事情 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(Don't Repeat Yourself)".ASP.NET MVC鼓励您指定功能或者行为,只做一次,然后将它应用到应用程序的各个地方.这可以减少您需要编写的代码量,并减少代码出错率,易于代码维护. 给ASP.NET MVC 和 Entity Framework Code First 提供验证支持是 DR

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航

本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了,最后只放出代码供大家参考,其实网上也有这方面的资料,但是不是很好用,我还是自己写了 改变后的效果 手风琴一直都是比较漂亮和受欢迎的,但是基于树多级别来说,做起来就比较麻烦,所以我这里也用了手风琴加树的模式来做 注:上面的图标都是乱添加的,并不代表意思 进入正文: 首先必须下载一些图标.可以自行百度网页小图标