• 企业400电话
  • 网络优化推广
  • AI电话机器人
  • 呼叫中心
  • 全 部 栏 目

    网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    ASP.NET MVC5网站开发添加文章(八)
    POST TIME:2021-10-18 02:25

    一、添加文章
    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>
      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中写现实代码

    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文件管理需要从服务器获取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;
       IQueryableAttachment> _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 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、为图片创建缩略图

    把创建缩略图的方法写着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到服务器,无法验证用户导致上传失败,暂时无法使用批量上传,希望这篇文章可以对大家的学习有所帮助,大家可以结合小编之前发的文章进行学习,相信一定会有所收获。

    您可能感兴趣的文章:
    • ASP.NET MVC5网站开发用户登录、注销(五)
    • PHP MVC模式在网站架构中的实现分析
    • ASP.NET MVC5网站开发用户注册(四)
    • ASP.NET MVC5 网站开发框架模型、数据存储、业务逻辑(三)
    • MVC4 网站发布(整理+部分问题收集和解决方案)
    • CodeIgniter php mvc框架 中国网站
    • PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
    • ASP.NET MVC5网站开发项目框架(二)
    • ASP.NET MVC5网站开发显示文章列表(九)
    • 一步步打造简单的MVC电商网站BooksStore(1)
    上一篇:asp.net验证码的简单制作
    下一篇:ASP.NET多彩下拉框开发实例
  • 相关文章
  • 

    关于我们 | 付款方式 | 荣誉资质 | 业务提交 | 代理合作


    © 2016-2020 巨人网络通讯

    时间:9:00-21:00 (节假日不休)

    地址:江苏信息产业基地11号楼四层

    《增值电信业务经营许可证》 苏B2-20120278

    X

    截屏,微信识别二维码

    微信号:veteran88

    (点击微信号复制,添加好友)

     打开微信