最近在看一些.Net5的内容,于是就想将之前Spring写的一个项目迁移到.Net上来看看。

不得不说.Net这几年发展的确实挺好的,超快的启动速度,极佳的性能让它一点不比Java差,但确实在国内生态有一些问题,一些问题的答案确实不那么好找,就比如我先在遇到的这个问题。

问题一:如何修改Content-Disposition属性

一个简单下载查看文件的功能,我可以选择下载还是查看本地的文件,代码非常简单,就像这样:

        /// <summary>
/// 加载文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="type">加载模式</param>
/// <returns>文件</returns>
[Route("file")]
[HttpGet]
public async Task<IActionResult> DownloadFile(string path, string type)
{
if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(path))
{
return Content("404 for not found!");
} try
{
var filePath = PathFilterUtil.PathFilter(RUN_PATH, path); var memoryStream = new MemoryStream();
using (var stream = new FileStream(filePath, FileMode.Open))
{
await stream.CopyToAsync(memoryStream);
} memoryStream.Position = 0;
// 获取文件的ContentType
string fileExt = Path.GetExtension(path);
var provider = new FileExtensionContentTypeProvider();
var memi = provider.Mappings[fileExt];
if (type == "inline")
{
Response.Headers.Add("Content-Disposition", $"inline; filename={Path.GetFileName(filePath)}");
return File(memoryStream, memi, Path.GetFileName(filePath));
}
return File(memoryStream, memi, Path.GetFileName(filePath));
}
catch (DirectoryNotFoundException e)
{
_logger.LogError($"文件:{path},没有找到!\n{e.Message}");
return Content("404 for not found!");
} }

我需要修改 HttpHeadersContent-Disposition 属性,将默认的 attachment 根据需要变成 inline,但是我按照上面的说法,怎么都改不了它的 Content-Disposition属性,不论则样它永远返回的是Content-Disposition: attachment; filename=appsettings.json; filename*=UTF-8''appsettings.json这样。

通过查找资料

期间我尝试了将Response.Headers.Add()方法变成Response.Headers.Append(),我甚至在百度看见了 Response.AddHeader()这种早已过时的方法,真滴离谱。

后来我终于在stackoverflow上找到了答案,不得不说还是stackoverflow强。

                if (type == "inline")
{ Response.Headers.Add("Content-Disposition", $"inline; filename={Path.GetFileName(filePath)}");
return File(memoryStream, memi);
}

方法很简单,删除return File(memoryStream, memi, Path.GetFileName(filePath)); 后面 Path.GetFileName(filePath)这个获取文件名的方法就好。

问题二:中文文件下载报InvalidOperationException: Invalid non-ASCII or control character in header:

这个不多说了,就是编码的问题,在Response.Headers.Add("Content-Disposition", $"inline; filename={Path.GetFileName(filePath)}");写入文件名时,不能直接写入文件,需要进行转码,这个转码的方法我又查了好久,最后还是在stackoverflow找到的,这两个问题真的是体现出了.Net在国内发展不咋地。

这要是Java,随便一查答案就出来了。

具体解决就是使用System.Net.WebUtility.UrlEncode()对文件名进行重新编码。像这样

                if (type == "inline")
{ Response.Headers.Add("Content-Disposition", $"inline; filename={System.Net.WebUtility.UrlEncode(Path.GetFileName(filePath))}");
return File(memoryStream, memi);
}

完整代码

        /// <summary>
/// 加载文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="type">加载模式</param>
/// <returns>文件</returns>
[Route("file")]
[HttpGet]
public async Task<IActionResult> DownloadFile(string path, string type)
{
if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(path))
{
return Content("404 for not found!");
} try
{
var filePath = PathFilterUtil.PathFilter(RUN_PATH, path); var memoryStream = new MemoryStream();
using (var stream = new FileStream(filePath, FileMode.Open))
{
await stream.CopyToAsync(memoryStream);
} memoryStream.Position = 0;
// 获取文件的ContentType
string fileExt = Path.GetExtension(path);
var provider = new FileExtensionContentTypeProvider();
var memi = provider.Mappings[fileExt];
_logger.LogInformation($"当前请求访问下载文件目录:{filePath} {Path.GetFileName(filePath)}");
if (type == "inline")
{ Response.Headers.Add("Content-Disposition", $"inline; filename={System.Net.WebUtility.UrlEncode(Path.GetFileName(filePath))}");
return File(memoryStream, memi);
}
return File(memoryStream, memi, Path.GetFileName(filePath));
}
catch (DirectoryNotFoundException e)
{
_logger.LogError($"文件:{path},没有找到!\n{e.Message}");
return Content("404 for not found!");
} }

版权

本文首发于https://www.buguagaoshu.com/archives/net%E5%A6%82%E4%BD%95%E4%BF%AE%E6%94%B9heepheaders,转载请注明来源

.Net 如何修改 HttpHeaders 中的 Content-Disposition的更多相关文章

  1. 菜单导航/URHere/面包屑,通过CSS中的content简洁表达代码

    比如我们要写一个菜单导航/URHere/面包屑,如: 首页 > 个人中心 > 修改密码 代码: <ul> <li><a href="javascri ...

  2. C#操作Kentico cms 中的 content(winform环境)

    前段时间做了个winform程序,去管理kentico网站的content,包括content节点的增删改查,以及相应节点内容的修改.现在将对content的操作方法简单的介绍一下. 我们想要操作ke ...

  3. iOS开发之AutoLayout中的Content Hugging Priority和 Content Compression Resistance Priority解析

    本篇博客的内容也不算太复杂,算是AutoLayout的一些高级的用法.本篇博客我们主要通过一些示例来看一下AutoLayout中的Content Hugging Priority以及Content C ...

  4. 不修改模板的前提下修改VisualState中的某些值

    原文链接:不修改模板的前提下修改VisualState中的某些值 - 超威蓝火 UWP里有一件非常令人不爽的事,大部分控件只提供了Normal状态下的Background,Foreground,Bor ...

  5. Java中如何修改Jar中的内容

    一.摘要 好长时间没写blog了,之前换了一家公司.表示工作更有战斗力了,可惜就是没时间写文章了.在这段时间其实是遇到很多问题的,只是都是记录下来,并没有花时间去研究解决.但是这周遇到这个问题没办法让 ...

  6. 爬虫技术 -- 进阶学习(十一)【补充】获取html中meta标签中的content的内容

    上一篇网易新闻页面信息抓取 -- htmlagilitypack搭配scrapysharp中提及了很多如何快速抓取html中的文本的语句, 但是meta标签中的content内容的抓取,没有提及到! ...

  7. Map java中的map 如何修改Map中的对应元素

    Map java中的map 如何修改Map中的对应元素 Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.         Map的接口         Map ...

  8. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  9. 何修改WAMP中mysql默认空密码--转

    何修改WAMP中mysql默认空密码  http://www.cnblogs.com/hooray/archive/2011/07/23/2114792.html WAMP安装好后,mysql密码是为 ...

随机推荐

  1. Mybatis-初见

    目录 介绍 示例 搭建环境 创建一个模块 CURD 万能Map 配置解析 环境配置 environments 属性 properties 类型别名 typeAliases 其他配置 映射器 mappe ...

  2. 庆FastGithub加入.NET Core Community

    .NET Core Community .NET Core Community是一个基于并围绕着 .NET 技术栈展开组织和活动的非官方.非盈利性的民间开源社区,提供了很多优秀的 .NET 开源项目. ...

  3. JUC学习笔记(二)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html 1.Lock接口 1.1.Synchronized 1.1.1.Synchronized关 ...

  4. Java面向对象12——static详解

    static  package oop.demon01.demon07; ​ // static : public class Student { ​     private static int a ...

  5. SunOS与Solaris系统的对应关系

    下文绝大部分译自维基百科Solaris词条的"历史"部分: http://en.wikipedia.org/wiki/Solaris_(operating_system)#Hist ...

  6. arraycopy将数组分为两部分时游标的设置方法

    System.arraycopy是复制数组的一个常用工具,它在游标处如何分为两个是一个需要注意的问题,例如下面的示例代码: byte [] src = { 104, 101, 108, 108, 11 ...

  7. 能够进行多段文本匹配的NFA改良算法

    下面的代码基于NFA算法实现了在多段字符串中匹配正则表达式,对比NFA算法可以看到它将pc由局部变量提升为类成员,以保存中间匹配状态,另外在匹配成功后将pc恢复到null状态.实际使用中,此类还应该增 ...

  8. Spring学习01(IOC)

    1.Spring概述 简介 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架. 2004年3月24日,Spring框架以interface21框架为基础,经过 ...

  9. SpringBoot开发十六-帖子详情

    需求介绍 实现帖子详情,在帖子标题上增加访问详情页面的链接. 代码实现 开发流程: 首先在数据访问层新增一个方法 实现查看帖子的方法 业务层同理增加查询方法 最后在表现层处理查询请求 数据访问层增加根 ...

  10. 【原创】深入分析Ubuntu本地提权漏洞CVE-2017-16995

    *本文首发阿里云先知安全技术社区,原文链接https://xz.aliyun.com/t/2212 前言: 2018年3月中旬,Twitter 用户 @Vitaly Nikolenko 发布消息,称 ...