最近在看一些.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. HCIA-数据链路层

    数据链路层 1.数据的差错检测 |FCS| 2.组帧|解帧 |数据帧帧头 帧尾| 3.标识身份 |MAC地址| 以太网络标准数据链路层的标准 数据链路层不仅仅只有以太网 地域来进行分类 局域网:小型地 ...

  2. Thunder DLL Hijacking

    简记 原理基础啥的俺也不写了 1.寻找DLL 生成恶意dll文件 拿calc测试 2.放入 3.打开

  3. RabbitMQ入门案例

    RabbitMQ入门案例 Rabbit 模式 https://www.rabbitmq.com/getstarted.html 实现步骤 构建一个 maven工程 导入 rabbitmq的依赖 启动 ...

  4. Git(6)-- 记录每次更新到仓库(git clone、status、add、diff、commit、rm、mv命令详解)

    @ 目录 1.克隆现有仓库:git clone 2.检查当前文件状态 :git status 3.跟踪新文件:git add 4.暂存已修改的文件:git add 5.状态简览: git status ...

  5. NOIP 模拟 $13\; \text{工业题}$

    题解 本题不用什么推式子,找规律(而且也找不出来) 可以将整个式子看成一个 \(n×m\) 矩阵 考虑 \(f_{i,j}\),它向右走一步给出 \(f_{i,j}×a\) 的贡献,向下走一步给出 \ ...

  6. SQLFlow:用户注册

    #### 一.SQLFlow是什么 随着大数据技术的发展与普及,数据治理和数据质量变得越来越重要,数据血缘分析在业界悄然兴起并得到了广泛流行,今天推荐一款专业且易用的血缘分析工具--SQLFlow.据 ...

  7. 处理URLs

    问题 你有一个包含相对URLs路径的HTML文档,需要将这些相对路径转换成绝对路径的URLs. 方法 在你解析文档时确保有指定base URI,然后 使用 abs: 属性前缀来取得包含base URI ...

  8. C++ 矩形交集和并集的面积-离散化

    //离散化,x,y坐标分别按从小到大排序 //离散化 //1.首先分离出所有的横坐标和纵坐标分别按升序存入数组X[ ]和Y[ ]中. //2. 设数组XY[ ][ ].对于每个矩形(x1,y1)(x2 ...

  9. LeetCoded第25题题解--K个一组翻转链表--java--链表

    链表 单链表:链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素的引用字段链接在一起. 双链表:与单链表不同的是,双链表的每个节点都含有两个引用字段. 链表优点 灵活分配内存空间 能在O ...

  10. session.flush与transaction.commit

    以session的save方法为例来看一个简单.完整的事务流程,如下是代码片段: ---------------------------- Session session = sessionFacto ...