一、添加文章
1、KindEditor富文本編輯器
到官方網(wǎng)站http://kindeditor.net/down.php下載最新版本,解壓后把代碼復(fù)制到項(xiàng)目的Scripts文件夾下。
2、添加界面的顯示。
在ArticleController中添加Add 方法
/// summary>
/// 添加文章
/// /summary>
/// returns>視圖頁(yè)面/returns>
public ActionResult Add()
{
return View();
}
右鍵添加Article的強(qiáng)類型視圖,代碼如下
@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、后臺(tái)接受的處理。
[ValidateInput(false)]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add(Article article)
{
if(ModelState.IsValid)
{
//設(shè)置固定值
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);
}
在做架構(gòu)的時(shí)候DAL、BLL的base類里有Add方法,我們可以直接使用ArticleService.Add方法添加到數(shù)據(jù)庫(kù)
添加文章功能就實(shí)現(xiàn)了,但是不能上傳附件,不能選擇首頁(yè)圖片,不能刪除多余的附件。下面就來(lái)實(shí)現(xiàn)附件功能。
二、附件上傳
目標(biāo)可以上傳附件(圖片,文件等),文件保存到上傳目錄中,且數(shù)據(jù)庫(kù)中保存相應(yīng)記錄,可以瀏覽文件列表,未使用的附件可以刪除記錄。
一、添加附件
在AttachmentController添加Upload()方法,方法方法把文件寫入磁盤中把附件的記錄也保存到數(shù)據(jù)庫(kù)中,中間會(huì)用到讀取配置文件,見《.Net MVC 網(wǎng)站中配置文件的讀寫》。
/// 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;
//擴(kuò)展名
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 = "請(qǐng)選擇文件" });
_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 = "文件大小超過(guò)限制" });
//檢查擴(kuò)展名
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);
//保存數(shù)據(jù)庫(kù)記錄
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接口,添加兩個(gè)方法,都進(jìn)行了注釋比較容易理解,直接上代碼。
/// summary>
/// 查找附件列表
/// /summary>
/// param name="modelID">公共模型ID/param>
/// param name="owner">所有者/param>
/// param name="type">類型/param>
/// returns>/returns>
IQueryableModels.Attachment> FindList(Nullableint> 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>
IQueryableModels.Attachment> FindList(int modelID, string owner, string type,bool withModelIDNull);
AttachmentService中寫現(xiàn)實(shí)代碼
public IQueryableModels.Attachment> FindList(Nullableint> 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 IQueryableModels.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文件管理需要從服務(wù)器獲取json格式文件列表,在Ninesky.Web.Areas.Member.Models中單獨(dú)給列表格式寫個(gè)視圖模型。AttachmentManagerViewModel
namespace Ninesky.Web.Areas.Member.Models
{
/// summary>
/// KindEditor文件管理中文件視圖模型
/// remarks>
/// 創(chuàng)建: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的文件管理器調(diào)用
/// summary>
/// 附件管理列表
/// /summary>
/// param name="id">公共模型ID/param>
/// param name="dir">目錄(類型)/param>
/// returns>/returns>
public ActionResult FileManagerJson(int? id ,string dir)
{
Models.AttachmentManagerViewModel _attachmentViewModel;
IQueryableAttachment> _attachments;
//id為null,表示是公共模型id為null,此時(shí)查詢數(shù)據(jù)庫(kù)中沒(méi)有跟模型對(duì)應(yīng)起來(lái)的附件列表(以上傳,但上傳的文章……還未保存)
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);
//循環(huán)構(gòu)造AttachmentManagerViewModel
var _attachmentList = new ListModels.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、為圖片創(chuàng)建縮略圖
把創(chuàng)建縮略圖的方法寫著Common項(xiàng)目中
在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>
/// 圖片相關(guān)
/// remarks>
/// 創(chuàng)建:2014.02.11
/// /remarks>
/// /summary>
public class Picture
{
/// summary>
/// 創(chuàng)建縮略圖
/// /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);
// 原圖使用區(qū)域
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);
//設(shè)置圖片質(zhì)量
_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>
/// 創(chuàng)建縮略圖
/// /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");
//創(chuàng)建縮略圖
if (Common.Picture.CreateThumbnail(Server.MapPath(originalPicture), Server.MapPath(_thumbnail), 160, 120))
{
//記錄保存在數(shù)據(jù)庫(kù)中
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);
}
三、整合
添加和上傳附件都做好了,現(xiàn)在把他們整合到一起,我們就可以上傳附件了。
打開Add視圖,在創(chuàng)建KindEditor位置添加腳本
現(xiàn)在打開瀏覽器就可以上傳和管理附件了
添加文章的最后一個(gè)字段是文章的默認(rèn)首頁(yè)圖片,我希望點(diǎn)擊選擇按鈕,可以在已上傳中選擇圖片,并創(chuàng)建縮略圖。
那么在Add視圖里再?gòu)棾鲆粋€(gè)文件空間讓用戶選擇已上傳的文件,用戶選擇后講選擇的地址發(fā)送到服務(wù)器創(chuàng)建縮略圖,并返回縮略圖地址,然后將地址復(fù)制給隱藏表單,CommonModel_DefaultPicUrl,同事復(fù)制個(gè)img />的src屬性用來(lái)顯示圖片。Js代碼如下:
//首頁(yè)圖片
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)
{
//設(shè)置固定值
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();
//查詢相關(guān)附件
var _attachments = _attachmentService.FindList(null, User.Identity.Name, string.Empty).ToList();
//遍歷附件
foreach(var _att in _attachments)
{
var _filePath = Url.Content(_att.FileParth);
//文章首頁(yè)圖片或內(nèi)容中使用了該附件則更改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);
}
//未使用改附件則刪除附件和數(shù)據(jù)庫(kù)中的記錄
else
{
System.IO.File.Delete(Server.MapPath(_att.FileParth));
_attachmentService.Delete(_att);
}
}
return View("AddSucess", article);
}
}
return View(article);
}
單純添加文章比較簡(jiǎn)單,復(fù)雜點(diǎn)在上傳附件,瀏覽新添加的附件,刪除文章中未使用的附件及生成縮略圖上。KindEditor還支持批量上傳附件,由于批量上傳使用的swfupload,在提交時(shí)flash沒(méi)傳輸cookie到服務(wù)器,無(wú)法驗(yàn)證用戶導(dǎo)致上傳失敗,暫時(shí)無(wú)法使用批量上傳,希望這篇文章可以對(duì)大家的學(xué)習(xí)有所幫助,大家可以結(jié)合小編之前發(fā)的文章進(jìn)行學(xué)習(xí),相信一定會(huì)有所收獲。
您可能感興趣的文章:- ASP.NET MVC5網(wǎng)站開發(fā)用戶登錄、注銷(五)
- PHP MVC模式在網(wǎng)站架構(gòu)中的實(shí)現(xiàn)分析
- ASP.NET MVC5網(wǎng)站開發(fā)用戶注冊(cè)(四)
- ASP.NET MVC5 網(wǎng)站開發(fā)框架模型、數(shù)據(jù)存儲(chǔ)、業(yè)務(wù)邏輯(三)
- MVC4 網(wǎng)站發(fā)布(整理+部分問(wèn)題收集和解決方案)
- CodeIgniter php mvc框架 中國(guó)網(wǎng)站
- PHP發(fā)明人談MVC和網(wǎng)站設(shè)計(jì)架構(gòu) 貌似他不支持php用mvc
- ASP.NET MVC5網(wǎng)站開發(fā)項(xiàng)目框架(二)
- ASP.NET MVC5網(wǎng)站開發(fā)顯示文章列表(九)
- 一步步打造簡(jiǎn)單的MVC電商網(wǎng)站BooksStore(1)