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, @"(").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="/UploadFiles/2021-04-02/@photo.ServerPath">
运行项目结果如图:
首页创建相册:
《车》相册下的图片示例,可以增加图片,删除图片
《QQ》相册下的图片示例
mongodb数据存储结构图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]



