ASP.NET MVC4使用MongoDB制作相册管理

前端技术 2023/09/02 .NET

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


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

本文地址:https://www.stayed.cn/item/4313

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。