ASP.NET MVC5網站開發添加文章(八)_實用技巧

來源:互聯網
上載者:User

一、添加文章
1、KindEditor富文字編輯器

到官方網站http://kindeditor.net/down.php下載最新版本,解壓後把代碼複製到項目的Scripts檔案夾下。

2、添加介面的顯示。

在ArticleController中添加Add 方法

/// <summary>  /// 添加文章  /// </summary>  /// <returns>視圖頁面</returns>  public ActionResult Add()  {   return View();  }

右鍵添加Article的強型別視圖,代碼如下

@section scripts{ <script type="text/javascript" src="~/Scripts/KindEditor/kindeditor-min.js"></script> <script type="text/javascript">  //編輯框  KindEditor.ready(function (K) {   window.editor = K.create('#Content', {    height: '500px'   });  }); </script>}@model Ninesky.Models.Article@using (Html.BeginForm()){ @Html.AntiForgeryToken() <div class="form-horizontal" role="form">  <h4>添加文章</h4>  <hr />  @Html.ValidationSummary(true)  <div class="form-group">   <label class="control-label col-sm-2" for="CommonModel_CategoryID">欄目</label>   <div class="col-sm-10">    <input id="CommonModel_CategoryID" name="CommonModel.CategoryID" data-options="url:'@Url.Action("JsonTree", "Category", new { model="Article" })'" class="easyui-combotree" style="height: 34px; width: 280px;" />      @Html.ValidationMessageFor(model => model.CommonModel.CategoryID)</div>  </div>  <div class="form-group">   @Html.LabelFor(model => model.CommonModel.Title, new { @class = "control-label col-sm-2" })   <div class="col-sm-10">    @Html.TextBoxFor(model => model.CommonModel.Title, new { @class = "form-control" })    @Html.ValidationMessageFor(model => model.CommonModel.Title)   </div>  </div>  <div class="form-group">   @Html.LabelFor(model => model.Author, new { @class = "control-label col-sm-2" })   <div class="col-sm-10">    @Html.TextBoxFor(model => model.Author, new { @class = "form-control" })    @Html.ValidationMessageFor(model => model.Author)   </div>  </div>  <div class="form-group">   @Html.LabelFor(model => model.Source, new { @class = "control-label col-sm-2" })   <div class="col-sm-10">    @Html.TextBoxFor(model => model.Source, new { @class = "form-control" })    @Html.ValidationMessageFor(model => model.Source)   </div>  </div>  <div class="form-group">   @Html.LabelFor(model => model.Intro, new { @class = "control-label col-sm-2" })   <div class="col-sm-10">    @Html.TextAreaFor(model => model.Intro, new { @class = "form-control" })    @Html.ValidationMessageFor(model => model.Intro)   </div>  </div>  <div class="form-group">   @Html.LabelFor(model => model.Content, new { @class = "control-label col-sm-2" })   <div class="col-sm-10">    @Html.EditorFor(model => model.Content)    @Html.ValidationMessageFor(model => model.Content)   </div>  </div>  <div class="form-group">   @Html.LabelFor(model => model.CommonModel.DefaultPicUrl, new { @class = "control-label col-sm-2" })   <div class="col-sm-10">    <img id="imgpreview" class="thumbnail" src="" />    @Html.HiddenFor(model => model.CommonModel.DefaultPicUrl)    <a id="btn_picselect" class="easyui-linkbutton">選擇…</a>    @Html.ValidationMessageFor(model => model.CommonModel.DefaultPicUrl)   </div>  </div>  <div class="form-group">   <div class="col-sm-offset-2 col-sm-10">    <input type="submit" value="添加" class="btn btn-default" />   </div>  </div> </div>}


效果如圖

3、後台接受的處理。

[ValidateInput(false)]  [HttpPost]  [ValidateAntiForgeryToken]  public ActionResult Add(Article article)  {   if(ModelState.IsValid)   {    //設定固定值    article.CommonModel.Hits = 0;    article.CommonModel.Inputer = User.Identity.Name;    article.CommonModel.Model = "Article";    article.CommonModel.ReleaseDate = System.DateTime.Now;    article.CommonModel.Status = 99;    article = articleService.Add(article);    if (article.ArticleID > 0)    {     return View("AddSucess", article);    }   }   return View(article);  }


在做架構的時候DAL、BLL的base類裡有Add方法,我們可以直接使用ArticleService.Add方法添加到資料庫

添加文章功能就實現了,但是不能上傳附件,不能選擇首頁圖片,不能刪除多餘的附件。下面就來實現附件功能。

二、附件上傳
目標可以上傳附件(圖片,檔案等),檔案儲存到上傳目錄中,且資料庫中儲存相應記錄,可以瀏覽檔案清單,未使用的附件可以刪除記錄。

一、添加附件

在AttachmentController添加Upload()方法,方法方法把檔案寫入磁碟中把附件的記錄也儲存到資料庫中,中間會用到讀取設定檔,見《.Net MVC 網站中設定檔的讀寫》。

/// <summary>  /// 上傳附件  /// </summary>  /// <returns></returns>  public ActionResult Upload()  {   var _uploadConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~").GetSection("UploadConfig") as Ninesky.Models.Config.UploadConfig;   //檔案最大限制   int _maxSize = _uploadConfig.MaxSize;   //儲存路徑   string _savePath;   //檔案路徑   string _fileParth = "~/" + _uploadConfig.Path + "/";   //檔案名稱   string _fileName;   //副檔名   string _fileExt;   //檔案類型   string _dirName;   //允許上傳的類型   Hashtable extTable = new Hashtable();   extTable.Add("image", _uploadConfig.ImageExt);   extTable.Add("flash", _uploadConfig.FileExt);   extTable.Add("media", _uploadConfig.MediaExt);   extTable.Add("file", _uploadConfig.FileExt);   //上傳的檔案   HttpPostedFileBase _postFile = Request.Files["imgFile"];   if (_postFile == null) return Json(new { error = '1', message = "請選擇檔案" });   _fileName = _postFile.FileName;   _fileExt = Path.GetExtension(_fileName).ToLower();   //檔案類型   _dirName = Request.QueryString["dir"];   if (string.IsNullOrEmpty(_dirName))   {    _dirName = "image";   }   if (!extTable.ContainsKey(_dirName)) return Json(new { error = 1, message = "目錄類型不存在" });   //檔案大小   if (_postFile.InputStream == null || _postFile.InputStream.Length > _maxSize) return Json(new { error = 1, message = "檔案大小超過限制" });   //檢查副檔名   if (string.IsNullOrEmpty(_fileExt) || Array.IndexOf(((string)extTable[_dirName]).Split(','), _fileExt.Substring(1).ToLower()) == -1) return Json(new { error = 1, message = "不允許上傳此類型的檔案。 \n只允許" + ((String)extTable[_dirName]) + "格式。" });   _fileParth += _dirName + "/" + DateTime.Now.ToString("yyyy-MM") + "/";   _savePath = Server.MapPath(_fileParth);   //檢查上傳目錄   if (!Directory.Exists(_savePath)) Directory.CreateDirectory(_savePath);   string _newFileName = DateTime.Now.ToString("yyyyMMdd_hhmmss") + _fileExt;    _savePath += _newFileName;    _fileParth += _newFileName;   //儲存檔案   _postFile.SaveAs(_savePath);   //儲存資料庫記錄   attachmentService.Add(new Attachment() { Extension = _fileExt.Substring(1), FileParth = _fileParth, Owner = User.Identity.Name, UploadDate = DateTime.Now, Type = _dirName });   return Json(new { error = 0, url = Url.Content(_fileParth) });  }


二、查詢附件列表

開啟InterfaceAttachmentService介面,添加兩個方法,都進行了注釋比較容易理解,直接上代碼。

/// <summary>  /// 尋找附件列表  /// </summary>  /// <param name="modelID">公用模型ID</param>  /// <param name="owner">所有者</param>  /// <param name="type">類型</param>  /// <returns></returns>  IQueryable<Models.Attachment> FindList(Nullable<int> modelID, string owner, string type);  /// <summary>  /// 尋找附件列表  /// </summary>  /// <param name="modelID">公用模型ID</param>  /// <param name="owner">所有者</param>  /// <param name="type">所有者</param>  /// <param name="withModelIDNull">包含ModelID為Null的</param>  /// <returns></returns>  IQueryable<Models.Attachment> FindList(int modelID, string owner, string type,bool withModelIDNull);

AttachmentService中寫現實代碼

public IQueryable<Models.Attachment> FindList(Nullable<int> modelID, string owner, string type)  {   var _attachemts = CurrentRepository.Entities.Where(a => a.ModelID == modelID);   if (!string.IsNullOrEmpty(owner)) _attachemts = _attachemts.Where(a => a.Owner == owner);   if (!string.IsNullOrEmpty(type)) _attachemts = _attachemts.Where(a => a.Type == type);   return _attachemts;  }  public IQueryable<Models.Attachment> FindList(int modelID, string owner, string type, bool withModelIDNull)  {   var _attachemts = CurrentRepository.Entities;   if (withModelIDNull) _attachemts = _attachemts.Where(a => a.ModelID == modelID || a.ModelID == null);   else _attachemts = _attachemts.Where(a => a.ModelID == modelID);   if (!string.IsNullOrEmpty(owner)) _attachemts = _attachemts.Where(a => a.Owner == owner);   if (!string.IsNullOrEmpty(type)) _attachemts = _attachemts.Where(a => a.Type == type);   return _attachemts;  }

由於KindEditor檔案管理需要從伺服器擷取json格式檔案清單,在Ninesky.Web.Areas.Member.Models中單獨給列表格式寫個視圖模型。AttachmentManagerViewModel

namespace Ninesky.Web.Areas.Member.Models{ /// <summary> /// KindEditor檔案管理中檔案視圖模型 /// <remarks> /// 建立:2014.03.09 /// </remarks> /// </summary> public class AttachmentManagerViewModel {  public bool is_dir{get;set;}  public bool has_file {get;set;}  public int filesize {get;set;}  public bool is_photo{get;set;}  public string filetype{get;set;}  public string filename{get;set;}  public string datetime { get; set; } }}

在AttachmentController添加返迴文件列表的方法FileManagerJson。方法供KindEditor的檔案管理工具調用

/// <summary>  /// 附件管理列表  /// </summary>  /// <param name="id">公用模型ID</param>  /// <param name="dir">目錄(類型)</param>  /// <returns></returns>  public ActionResult FileManagerJson(int? id ,string dir)  {   Models.AttachmentManagerViewModel _attachmentViewModel;   IQueryable<Attachment> _attachments;   //id為null,表示是公用模型id為null,此時查詢資料庫中沒有跟模型對應起來的附件列表(以上傳,但上傳的文章……還未儲存)   if (id == null) _attachments = attachmentService.FindList(null, User.Identity.Name, dir);   //id不為null,返回指定模型id和id為null(新上傳的)附件了列表   else _attachments = attachmentService.FindList((int)id, User.Identity.Name, dir, true);   //迴圈構造AttachmentManagerViewModel   var _attachmentList = new List<Models.AttachmentManagerViewModel>(_attachments.Count());   foreach(var _attachment in _attachments)   {    _attachmentViewModel = new Models.AttachmentManagerViewModel() { datetime = _attachment.UploadDate.ToString("yyyy-MM-dd HH:mm:ss"), filetype = _attachment.Extension, has_file = false, is_dir = false, is_photo = _attachment.Type.ToLower() == "image" ? true : false, filename = Url.Content(_attachment.FileParth) };    FileInfo _fileInfo = new FileInfo(Server.MapPath(_attachment.FileParth));    _attachmentViewModel.filesize = (int)_fileInfo.Length;    _attachmentList.Add(_attachmentViewModel);   }   return Json(new { moveup_dir_path = "", current_dir_path = "", current_url = "", total_count = _attachmentList.Count, file_list = _attachmentList },JsonRequestBehavior.AllowGet);  }

3、為圖片建立縮圖

把建立縮圖的方法寫著Common項目中

在Ninesky.Common的Picture類中添加方法

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Drawing;using System.Drawing.Drawing2D;using System.Security.Cryptography;namespace Ninesky.Common{ /// <summary> /// 圖片相關 /// <remarks> /// 建立:2014.02.11 /// </remarks> /// </summary> public class Picture {  /// <summary>  /// 建立縮圖  /// </summary>  /// <param name="originalPicture">原圖地址</param>  /// <param name="thumbnail">縮圖地址</param>  /// <param name="width">寬</param>  /// <param name="height">高</param>  /// <returns>是否成功</returns>  public static bool CreateThumbnail(string originalPicture, string thumbnail, int width, int height)  {   //原圖   Image _original = Image.FromFile(originalPicture);   // 原圖使用地區   RectangleF _originalArea = new RectangleF();   //寬高比   float _ratio = (float)width/height;   if(_ratio > ((float)_original.Width/_original.Height))   {    _originalArea.X =0;    _originalArea.Width = _original.Width;    _originalArea.Height = _originalArea.Width / _ratio;    _originalArea.Y = (_original.Height - _originalArea.Height) / 2;   }   else   {    _originalArea.Y = 0;    _originalArea.Height = _original.Height;    _originalArea.Width = _originalArea.Height * _ratio;    _originalArea.X = (_original.Width - _originalArea.Width) / 2;   }   Bitmap _bitmap = new Bitmap(width, height);   Graphics _graphics = Graphics.FromImage(_bitmap);   //設定圖片品質   _graphics.InterpolationMode = InterpolationMode.High;   _graphics.SmoothingMode = SmoothingMode.HighQuality;   //繪製圖片   _graphics.Clear(Color.Transparent);   _graphics.DrawImage(_original, new RectangleF(0, 0, _bitmap.Width, _bitmap.Height), _originalArea, GraphicsUnit.Pixel);   //儲存   _bitmap.Save(thumbnail);   _graphics.Dispose();   _original.Dispose();   _bitmap.Dispose();   return true;  } }}

在AttachmentController添加產生縮圖的action

/// <summary>  /// 建立縮圖  /// </summary>  /// <param name="originalPicture">原圖地址</param>  /// <returns>縮圖地址。產生失敗返回null</returns>  public ActionResult CreateThumbnail(string originalPicture)  {   //原圖為縮圖直接返回其地址   if (originalPicture.IndexOf("_s") > 0) return Json(originalPicture);   //縮圖地址   string _thumbnail = originalPicture.Insert(originalPicture.LastIndexOf('.'), "_s");   //建立縮圖   if (Common.Picture.CreateThumbnail(Server.MapPath(originalPicture), Server.MapPath(_thumbnail), 160, 120))   {    //記錄儲存在資料庫中    attachmentService.Add(new Attachment(){ Extension= _thumbnail.Substring(_thumbnail.LastIndexOf('.')+1), FileParth="~"+_thumbnail, Owner= User.Identity.Name, Type="image", UploadDate= DateTime.Now});    return Json(_thumbnail);   }   return Json(null);  }


三、整合
添加和上傳附件都做好了,現在把他們整合到一起,我們就可以上傳附件了。

開啟Add視圖,在建立KindEditor位置添加指令碼

現在開啟瀏覽器就可以上傳和管理附件了

添加文章的最後一個欄位是文章的預設首頁圖片,我希望點擊選擇按鈕,可以在已上傳中選擇圖片,並建立縮圖。

那麼在Add視圖裡再彈出一個檔案空間讓使用者選擇已上傳的檔案,使用者選擇後講選擇的地址發送到伺服器建立縮圖,並返回縮圖地址,然後將地址複製給隱藏表單,CommonModel_DefaultPicUrl,同事複製個<img />的src屬性用來顯示圖片。Js代碼如下:

//首頁圖片   var editor2 = K.editor({    fileManagerJson: '@Url.Action("FileManagerJson", "Attachment")'   });   K('#btn_picselect').click(function () {    editor2.loadPlugin('filemanager', function () {     editor2.plugin.filemanagerDialog({      viewType: 'VIEW',      dirName: 'image',      clickFn: function (url, title) {       var url;       $.ajax({        type: "post",        url: "@Url.Action("CreateThumbnail", "Attachment")",        data: { originalPicture: url },        async: false,        success: function (data) {         if (data == null) alert("產生縮圖失敗!");         else {          K('#CommonModel_DefaultPicUrl').val(data);          K('#imgpreview').attr("src", data);         }         editor2.hideDialog();        }       });      }     });    });   });


看下效果

在儲存文章的action中刪除未使用的附件

完整的Add方法代碼

[ValidateInput(false)]  [HttpPost]  [ValidateAntiForgeryToken]  public ActionResult Add(Article article)  {   if(ModelState.IsValid)   {    //設定固定值    article.CommonModel.Hits = 0;    article.CommonModel.Inputer = User.Identity.Name;    article.CommonModel.Model = "Article";    article.CommonModel.ReleaseDate = System.DateTime.Now;    article.CommonModel.Status = 99;    article = articleService.Add(article);    if (article.ArticleID > 0)    {     //附件處理     InterfaceAttachmentService _attachmentService = new AttachmentService();     //查詢相關附件     var _attachments = _attachmentService.FindList(null, User.Identity.Name, string.Empty).ToList();     //遍曆附件     foreach(var _att in _attachments)     {      var _filePath = Url.Content(_att.FileParth);      //文章首頁圖片或內容中使用了該附件則更改ModelID為文章儲存後的ModelID      if ((article.CommonModel.DefaultPicUrl != null && article.CommonModel.DefaultPicUrl.IndexOf(_filePath) >= 0) || article.Content.IndexOf(_filePath) > 0)      {       _att.ModelID = article.ModelID;       _attachmentService.Update(_att);      }      //未使用改附件則刪除附件和資料庫中的記錄      else      {       System.IO.File.Delete(Server.MapPath(_att.FileParth));       _attachmentService.Delete(_att);      }     }     return View("AddSucess", article);    }   }   return View(article);  }

單純添加文章比較簡單,複雜點在上傳附件,瀏覽新添加的附件,刪除文章中未使用的附件及產生縮圖上。KindEditor還支援批量上傳附件,由於批量上傳使用的swfupload,在提交時flash沒傳輸cookie到伺服器,無法驗證使用者導致上傳失敗,暫時無法使用批量上傳,希望這篇文章可以對大家的學習有所協助,大家可以結合小編之前發的文章進行學習,相信一定會有所收穫。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.