ASP.NET MVC5实现文件上传与地址变化处理(5)

一.上传文件和重复文件处理
文件处理的原则是:不在数据库中保存文件,只在数据库中保存文件信息(Hash值等)。采取文件的MD5重命名文件在一般情况足够处理文件的重复问题,强迫症倾向则可以考虑将MD5和其他摘要算法结合。

public static string Save(HttpPostedFileBase file, string path)
    {
      var root = "~/Upload/" + path + "/";
      var phicyPath = HostingEnvironment.MapPath(root);
      Directory.CreateDirectory(phicyPath);
      var fileName = Md5(file.InputStream) + file.FileName.Substring(file.FileName.LastIndexOf('.'));
      file.SaveAs(phicyPath + fileName);
      return fileName;
    }

二.单独文件上传
网站Logo、分类图标等各种场景需要单独文件上传的处理。通过使用UIHintAttribute或自定义继承自UIHintAttribute的特性我们将文件上传的前端逻辑的重复代码消灭,使用统一的视图文件处理。曾经使用过Uplodify和AjaxFileUploader,前者存在flash依赖和cookie问题,后者基本已经过时。此处我们采用KindEditor中的文件上传组件作为演示。非Flash的支持IE6+的方案的核心都是通过iframe方式实现伪AJax上传,核心还是通过html form post到服务器。

  public class UploadModel
  {
    [Display(Name = "图标")]
    [UIHint("Upload")]
    public string Image { get; set; }

    [Display(Name = "简单模式")]
    [UIHint("Editor")]
    [AdditionalMetadata("useSimple", true)]
    public string Text1 { get; set; }

    [Display(Name = "标准模式")]
    [UIHint("Editor")]
    public string Text2 { get; set; }
  }

在我们的实际项目中采取继承UIHintAttribute的方式,其中的path路径指定存储的下级地址,类似的还有DropDownAttribute、EditorAtrribute等等。仅供参考。

  [AttributeUsage(AttributeTargets.Property)]
  public class UploadAttribute : UIHintAttribute, IMetadataAware
  {
    public string Path { get; private set; }

    public UploadAttribute(string path = "")
      : base("Upload")
    {
      this.Path = path;
    }

    public virtual void OnMetadataCreated(ModelMetadata metadata)
    {
      metadata.AdditionalValues.Add("Path", this.Path);
    }
  }

Razor:在Shared中添加EditorTemplates文件夹,新建Upload.cshtml文件。

<script>
  KindEditor.ready(function (K) {
    var editor = K.editor({
      allowFileManager: false,
      allowImageUpload: true,
      formatUploadUrl: false,
      uploadJson: '@url',
    });
    K('#btn_@id').click(function () {
      editor.loadPlugin('insertfile', function () {
        editor.plugin.fileDialog({
          fileUrl: K('#@id').val(),
          clickFn: function (url, title) {
            K('#@id').val(url);
            $('#image_@id').attr('src', url);
            editor.hideDialog();
          }
        });
      });
    });
  });
  $('#rest_@id').click(function () {
    $('#@id').attr('value', '');
    $('#image_@id').attr('src', '@Url.Content("~/Images/default.png")');
  });
</script>

三.编辑器中的文件上传
编辑器中的文件上传和单独文件上传的主要区别是上传后返回值的处理,编辑器需要将url插入到编辑的位置。编辑器采用过CKeditor和UMeditor,两者都需要我改源代码才能处理路径问题。上传地址和返回值的配置如果不能方便的视图中调整的编辑器,我个人不认为是好编辑器,这就好比一个类库没法扩展和自定义配置一样。仍然采用KindEditor作为演示。Editor.cshtml的

<script type="text/javascript">
  var editor;
  KindEditor.ready(function (K) {
    editor = K.create('textarea[name="@Html.IdForModel()"]', {
      resizeType: 1,
      allowPreviewEmoticons: false,
      allowImageUpload: true,
      uploadJson: '@UploadManager.UploadUrl',
      formatUploadUrl: false,
      allowFileManager: false
      @if(useSimple)
      {
        <text>, items: [
            'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline',
            'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist',
            'insertunorderedlist', '|', 'emoticons', 'image', 'link']
        </text>
      }
    });
  });
</script>

四.处理文章中的图片路径
重头戏来了,这个看似问题可以回避,其实真的无法回避。更换目录、域名和端口,使用子域名或其他域名作为图片服务器等等,这些情况让我们必须处理好这个问题,否则日后会浪费更多的时间。这不是小问题,打开支持插入图片的各个网站的编辑器,查看一下图片的路径,大多是绝对url的,又或者只基于根目录的。如果你以产品的形式提供给客户,更不可能要求客户自己挨个替换文章中的路径了。

1.在数据库中不存储文件路径,使用URL路径作为存储。

2.使用html base元素解决相对路径的引用问题。

就是base元素,可能有的人认为这个base可有可无,但在处理图片路径的问题上,没有比base更简洁更优雅的方案了。至少我没有也没找到过。其实可以把全部的静态资源都移除到外部存储,如果你需要。在测试时,我们切换回使用本地存储。

@{
  var baseUrl = UploadManager.UrlPrefix;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />

  <title>@ViewBag.Title</title>
  <base href="@baseUrl" />

  <script src="~/Scripts/jquery-1.11.2.min.js"></script>
  @RenderSection("head",false)
</head>
<body>
  @RenderBody()
</body>
</html>

五.处理上传地址的变化
我们需要独立的图片服务器处理上传或者使用第三方的图片存储服务时,我们的上传地址改变了,如果刚刚提到的图片路径一样,因此我们将上传路径和图片路径都采取配置的方式方便更改,我们就曾经切换到又拍云又切换到自有的服务器。在我的实际使用时配置在数据中使用时采用缓存。为了便于演示我们直接使用配置文件。

首先定义配置文件的处理程序

  public class UploadConfig : IConfigurationSectionHandler
  {
    public object Create(object parent, object configContext, System.Xml.XmlNode section)
    {
      var config = new UploadConfig();
      var urloadUrlNode = section.SelectSingleNode("UploadUrl");
      if (urloadUrlNode != null && urloadUrlNode.Attributes != null && urloadUrlNode.Attributes["href"] != null)
      {
        config.UploadUrl = Convert.ToString(urloadUrlNode.Attributes["href"].Value);
      }

      var urlPrefixNode = section.SelectSingleNode("UrlPrefix");
      if (urlPrefixNode != null && urlPrefixNode.Attributes != null && urlPrefixNode.Attributes["href"] != null)
      {
        config.UrlPrefix = Convert.ToString(urlPrefixNode.Attributes["href"].Value);
      }

      return config;
    }

    public string UploadUrl { get; private set; }

    public string UrlPrefix { get; private set; }
  }

在web.config中配置

 <configSections>
  <section name="UploadConfig" type="SimpleFileManager.UploadConfig, SimpleFileManager" requirePermission="false" />
 </configSections>
 <UploadConfig>
  <UploadUrl href="~/File/Upload/" />
  <UrlPrefix href="~/Upload/" />
 </UploadConfig>

使用UploadMange缓存和管理配置

  public static class UploadManager
  {
    private static string uploadUrl;
    private static string urlPrefix;

    static UploadManager()
    {
      var config = ConfigurationManager.GetSection("UploadConfig") as UploadConfig;
      var url = config != null && !string.IsNullOrEmpty(config.UploadUrl) ? config.UploadUrl : "~/File/Upload";
      uploadUrl = url.StartsWith("~") ? UploadHelper.GetUrlFromVisualPath(url) : url;
      var prefix = config != null && !string.IsNullOrEmpty(config.UrlPrefix) ? config.UrlPrefix : "~/Upload";
      urlPrefix = prefix.StartsWith("~") ? UploadHelper.GetUrlFromVisualPath(prefix) : prefix;
    }

    public static string UploadUrl
    {
      get
      {
        return uploadUrl;
      }
    }

    public static string UrlPrefix
    {
      get
      {
        return urlPrefix;
      }
    }
  }

文件Hash的Md5、返回值的Json处理、完整URL的生成和文件的保存这些具体技术的依赖为了便于演示,统一放置在UploadHelper中,因为这些不是重点。实际应用中可以采取接口隔离并通过IoC注入的方式解耦。

以上就是ASP.NET MVC5如何实现文件上传与地址变化处理的全部过程,希望对大家的学习有所帮助。

(0)

相关推荐

  • ASP.NET MVC 文件上传教程(一)

    这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看. Upload File(一) 我们在默认创建的项目中的Home控制器下添加如下: public ActionResult UploadFile() { return View(); } [HttpPost] public ActionResult UploadFile(HttpPostedFileBase file) { var fileName = file.FileName; var filePath = Server

  • ASP.NET MVC HttpPostedFileBase文件上传的实例代码

    本文介绍了ASP.NET MVC HttpPostedFileBase文件上传 ,分享给大家,希望对大家有帮助 HttpPostedFileBase文件上传,支持多文件一次上传,如有图片,则支持略缩图保存 文件传输信息封装 /// <summary> /// 文件生成方式 /// </summary> public class UpFileMessage { /// <summary> /// 文件名 /// </summary> public string

  • Asp.net实现MVC处理文件的上传下载功能实例教程

    上传于下载功能是程序设计中非常常见的一个功能,在ASP.NET程序开发中有着非常广泛的应用.本文就以实例形式来实现这一功能. 一.概述 如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个,而这个控件的缺席给我们带来一些小问题.这篇文章主要说如何在Asp.net MVC中上传文件,然后如何再从服务器中把上传过的文件下载下来. 二.实现方法 1.文件上传

  • 用Html5与Asp.net MVC上传多个文件的实现代码

    复制代码 代码如下: <form action="/Home/Upload" enctype="multipart/form-data" id="form2" method="post"> <input type="file" name="fileToUpload" id="fileToUpload2" multiple="multiple

  • ASP.NET MVC文件上传教程(二)

    上文ASP.NET MVC 文件上传教程(一)我们讲了简单的上传以及需要注意的地方,查相关资料时,感觉上传里面涉及到的内容还是比较多,于是就将上传这一块分为几节来处理,同时后续也会讲到关于做上传时遗漏的C#应该注意的地方,及时进行查漏补缺,尽量将这一块完善起来. 引入 上一节我们讲到了上传这一块,有朋友提出未涉及到大文件的上传这一块,思前想后还是来试着做做,毕竟之前没怎么去仔细考虑过这个问题,尤其还可以联系实际开发中创建文件夹等一系列问题,同时关于上传在网上随便找找都充斥着大量的组件,我们何必再

  • ASP.NET MVC4 利用uploadify.js多文件上传

    页面代码: 1.引入js和css文件 <link href="~/Scripts/uploadify/uploadify.css" rel="external nofollow" rel="stylesheet" /> <style type="text/css"> #upDiv { width: 550px; height: 400px; border: 2px solid red; margin-t

  • asp.net中MVC借助Iframe实现无刷新上传文件实例

    本文实例讲述了asp.net中MVC借助Iframe实现无刷新上传文件的方法.分享给大家供大家参考.具体实现方法如下: html: 复制代码 代码如下: <div id="uploadwindow" style="display: none;">     <form action="/ShopActivitys/ImportActivityItems" id="form1" name="form1&

  • ASP.NET MVC处理文件上传的小例子

    复制代码 代码如下: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Files uploaded to server</h2> <div id="dialog" title="Upload files"> <% using (Html.B

  • asp.net mvc 实现文件上传带进度条的思路与方法

    前言 文件上传与下载的操作在实际项目中经常是很重要的一个内容,在使用ASP.NET Web Form的时候我们可以使用诸多的服务器控件,FileIpload就是其中之一,但是在ASP.NET不建议使用那些服务器控件,因为那样违反三层架构原则.最近参考网络资料,学习了ASP.NET MVC如何上传文件. 而这篇文章主要重点是asp.net mvc 实现文件上传带进度条,下面来一起看看吧. 实现思路 ajax异步上传文件,且开始上传文件的时候启动轮询来实时获取文件上传进度.保存进度我采用的是memc

  • ASP.NET MVC5实现文件上传与地址变化处理(5)

    一.上传文件和重复文件处理 文件处理的原则是:不在数据库中保存文件,只在数据库中保存文件信息(Hash值等).采取文件的MD5重命名文件在一般情况足够处理文件的重复问题,强迫症倾向则可以考虑将MD5和其他摘要算法结合. public static string Save(HttpPostedFileBase file, string path) { var root = "~/Upload/" + path + "/"; var phicyPath = Hostin

  • ASP.NET设计FTP文件上传的解决方案

    如果要用ASP来作一个FTP文件上传的页面,我想很多人立刻就会想到要用第三方开发的组件,利用第三方的组件,虽然开发起来相对比较容易.但一般来说,免费下载的第三方的组件都有某些方面的功能限制,若要购买正版的第三方组件,对于国内的用户,花销也是一个不小的数字,就是能够承担的起,烦杂的手续也使很多人望而却步.虽然微软公司在本身的视窗系统里面也提供了一个可以用来上传文件的组件--Posting Acceptor.但用过这个组件的朋友们都有一种普遍的感觉,就是实在不好用. 现在好了,自从微软公司推出了.N

  • ASP.NET Core实现文件上传和下载

    本文实例为大家分享了ASP.NET Core实现文件上传和下载的具体代码,供大家参考,具体内容如下 一.文件上传 1.1 获取文件后缀 /// <summary> /// 获取文件后缀 /// </summary> /// <param name="fileName">文件名称</param> /// <returns></returns>         public async static Task<s

  • asp.net core实现文件上传功能

    本文实例为大家分享了单文件上传.多文件上传的功能,供大家参考,具体内容如下 单文件上传  上传文件在Web应用程序中是一个常见的功能.在asp.net core中上传文件并保存在服务器上,是很容易的.下面就来演示一下怎么样在 ASP.NET Core项目中进行文件上传.  首先,创建一个 asp.net core 项目,然后在Controller文件件添加一个HomeController,然后在 Views 文件夹的 Home 文件夹里添加一个 New.cshtml 视图文件.如下图: 添加一个

  • ASP.NET对大文件上传的解决方案

    首先,我们需要下载这个名为 RanUpLoad 的组件. 下载完成之后,两个 dll 文件添加到项目的引用中区,xml 文件也要复制在项目中的 bin 文件夹下,也就是最后三个文件都要存在于 bin 文件夹中. 接着,上传控件还是用 ASP.NET 中自带的 FileUpload 控件,需要添加的就是在 FileUpload 控件旁边加入标签: <radU:RadProgressManager ID="Radprogressmanager1" Width="100%&q

  • asp.net下大文件上传知识整理

    最近做在做ePartner项目,涉及到文件上传的问题. 以前也做过文件上传,但都是些小文件,不超过2M. 这次要求上传100M以上的东西. 没办法找来资料研究了一下.基于WEB的文件上传可以使用FTP和HTTP两种协议,用FTP的话虽然传输稳定,但安全性是个严重的问题,而且FTP服务器读用户库获取权限,这样对于用户使用来说还是不太方便. 剩下只有HTTP.在HTTP中有3种方式,PUT.WEBDAV.RFC1867,前2种方法不适合大文件上传,目前我们使用的web上传都是基于RFC1867标准的

  • asp将本地的文件上传到服务器

    今天我们讲解如何利用asp的上传功能将本地的文件上传到服务器上. 最简系统包括下面三个文件: upload.htm                         --上传口文件,选择本地文件 uploadimg.asp                  --上传程序控制文件 upload_5xsoft.inc            --无组件上传类,此文件初学者不用学习,只要会用就可以了 upload.htm内容----上传口文件,选择本地文件 <html> <head> <

  • Asp.Net 无刷新文件上传并显示进度条的实现方法及思路

    相信通过Asp.Net的服务器控件上传文件在简单不过了,通过AjaxToolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦苦来 实现呢?我并不否认"拿来主义",只是我个人更喜欢凡是求个所以然.本篇将阐述通过Html,IHttpHandler和 IHttpAsyncHandler实现文件上传和上传进度的原理,希望对你有多帮助. 效果图: 本文涉及到的知识点:1.前台用到Html,Ajax,JQuery,JQuery UI 2.后台用到一般处理程序(IHttpHandler)和

随机推荐