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

 更新时间:2021年9月22日 10:10  点击:1690

一.上传文件和重复文件处理
文件处理的原则是:不在数据库中保存文件,只在数据库中保存文件信息(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如何实现文件上传与地址变化处理的全部过程,希望对大家的学习有所帮助。

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • Php文件上传类class.upload.php用法示例

    本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
  • PHP文件上传一些小收获

    又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
  • jQuery实现简单的文件上传进度条效果

    本文实例讲述了jQuery实现文件上传进度条效果的代码。分享给大家供大家参考。具体如下: 运行效果截图如下:具体代码如下:<!DOCTYPE html><html><head><meta charset="utf-8"><title>upload</title><link rel="stylesheet...2015-11-24
  • php文件上传你必须知道的几点

    本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • 借助FileReader实现将文件编码为Base64后通过AJAX上传

    这篇文章主要介绍了借助FileReader实现将文件编码为Base64后通过AJAX上传的方法,包括后端对文件数据解码并保存的PHP代码,需要的朋友可以参考下...2015-12-25
  • js实现上传文件添加和删除文件选择框

    这篇文章主要为大家详细介绍了js实现上传文件添加和删除文件选择框 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-25
  • jQuery+ajax简单实现文件上传的方法

    这篇文章主要介绍了jQuery+ajax简单实现文件上传的方法,结合实例形式简单分析了jQuery基于ajax的post方法进行文件传输及asp.net后台处理技巧,需要的朋友可以参考下...2016-06-12
  • 适用于初学者的简易PHP文件上传类

    本文实例讲述了PHP多文件上传类,分享给大家供大家参考。具体如下:<&#63;phpclass Test_Upload{ protected $_uploaded = array(); protected $_destination; protected $_max = 1024000; protected $_messages =...2015-10-30
  • 详解ASP.NET Core 中基于工厂的中间件激活的实现方法

    这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • js 实现文件上传样式详情

    这篇文章主要介绍了js 实现文件上传样式,下面文章举例说明js 是如何实现文件上传样式的,附有代码详细解说,需要的朋友可以参考一下,希望对你有所帮助...2021-10-21
  • asp.net通过消息队列处理高并发请求(以抢小米手机为例)

    这篇文章主要介绍了asp.net通过消息队列处理高并发请求(以抢小米手机为例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • PHP利用APC模块实现大文件上传进度条的方法

    php 大文件带进度的上传,一直是一个令php程序员很苦恼的问题。查询baidu 、Google ,大体做带进度的上传方式为:flash+php,socket,apc+php等,下面我介绍了apc +php+ajax制作的带进度的上传,并贴出源码,希望对大家有用。 Altern...2015-10-30
  • ASP.NET单选按钮控件RadioButton常用属性和方法介绍

    RadioButton又称单选按钮,其在工具箱中的图标为 ,单选按钮通常成组出现,用于提供两个或多个互斥选项,即在一组单选钮中只能选择一个...2021-09-22
  • C#文件上传的简单实现

    这篇文章主要为大家详细介绍了C#文件上传的简单实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • ASP.NET 2.0中的数据操作:使用两个DropDownList过滤的主/从报表

    在前面的指南中我们研究了如何显示一个简单的主/从报表, 该报表使用DropDownList和GridView控件, DropDownList填充类别,GridView显示选定类别的产品. 这类报表用于显示具有...2016-05-19
  • ASP.NET中iframe框架点击左边页面链接 右边显示链接页面内容

    这篇文章主要介绍了ASP.NET中iframe框架点击左边页面链接,右边显示链接页面内容的实现代码,感兴趣的小伙伴们可以参考一下...2021-09-22