场景

我们上传一个文件,把文件保存到服务器上,会有一个明确的物理路径,由于需要从前端访问这个文件,还需要web服务器中的一个虚拟路径。这个虚拟路径的存储会有一个问题,我们应该在数据库里存什么?是带域名的全路径,还是相对于web根目录的相对路径?

现在很多架构都是前后分离的,所以前端访问的url是全路径比较好,不像之前前后都是一个项目中,数据库存相对路径,前端也使用相对路径访问没有问题。

如果存全路径,域名更换的时候就比较麻烦,需要手动把数据库里的数据替换一下。如果存相对路径,返回前端的时候需要手动的补全路径,也不是太好。

解决方法

我们可以使用JsonConverter 来自动处理一下,具体方法是保存相对路径,返回的时候自动加上前缀组成全路径。

/// <summary>
/// 处理图片文件前缀,数据库中存相对路径即可
/// </summary>
public class JsonUrlPrefixConverter : JsonConverter
{
private string urlPrefix;
public JsonUrlPrefixConverter()
{
urlPrefix ="htttp://www.abc.com"; //这里前缀可以做成配置,换域名时改一下配置即可
} public JsonUrlPrefixConverter(string flag)
{
if (flag == "something")
{
urlPrefix = "htttp://www.123.com";
}
} public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value != null)
{
if (value is IEnumerable<string> arr)
{
writer.WriteStartArray();
foreach (var str in arr.Select(x =>
x.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? x : urlPrefix + x))
{
writer.WriteValue(str);
}
writer.WriteEndArray();
}
else if (value is string str && !str.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
if (str.HasValue())
str = urlPrefix + str;
writer.WriteValue(str);
}
else
{
writer.WriteValue(value);
}
}
else
{
writer.WriteValue(value);
}
} public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue,
JsonSerializer serializer)
{
if (objectType == typeof(string))
{
var str = serializer.Deserialize<string>(reader);
return str;
} if (objectType == typeof(List<string>))
{
var list = serializer.Deserialize<List<string>>(reader); return list.Select(x => x.Replace(urlPrefix, "")).ToList();
} if (objectType == typeof(string[]))
{
var arr = serializer.Deserialize<string[]>(reader);
return arr.Select(x => x.Replace(urlPrefix, "")).ToArray();
} return reader.Value;
} public override bool CanConvert(Type objectType)
{
//请自觉用于 string[]、string、List<string>类型
return true;
}
}

使用

JsonUrlPrefixConverter 使用了 Newtonsoft.Json,所以在新的 dotnet 项目中需要指定一下序列话还使用 Newtonsoft.Json。

builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
//忽略循环引用问题
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

然后在上传路径的字段上加JsonUrlPrefixConverter 便可以自动处理。

如头像字段:

    /// <summary>
/// 头像
/// </summary>
[JsonConverter(typeof(JsonUrlPrefixConverter))]
public string Avatar { get; set; } = "";

如前端保存时传给后端的是 "http://www.abc.com/upload/avatar.jpg" ,经过 JsonUrlPrefixConverter 处理,会得到 "/upload/avatar.jpg" 保存到数据库,当从后端返回到前端的时候,会自动加上前缀,又变成了 "http://www.abc.com/upload/avatar.jpg" 。

这样如果域名变了,修改一下配置的前缀即可。

使用JsonConverter处理上传文件的路径的更多相关文章

  1. ie下获取上传文件全路径

    ie下获取上传文件全路径,3.5之后的火狐是没法获取上传文件全路径的 /*获取上传文件路径*/ function getFilePath(obj) { var form = $(this).paren ...

  2. asp.net 客户端上传文件全路径获取方法

    asp.net  获取客户端上传文件全路径方法: eg:F:\test\1.doc 基于浏览器安全问题,浏览器将屏蔽获取客户端文件全路径的方法,只能获取到文件的文件名,如果需要获取全路径则需要另想其他 ...

  3. Atitit.js获取上传文件全路径

    Atitit.js获取上传文件全路径 1. 默认的value只能获取文件名..安全原因.. 1 2. Firefox浏览器的读取 1 3. Html5 的file api 2 4. 解决方法::使用a ...

  4. 20160620001 FileUpload控件获取上传文件的路径

    参考地址: http://bbs.csdn.net/topics/350051517 —————————————————————————————— 用js实现 <%@ Page Language ...

  5. 【django】本地开发media用户上传文件访问路径找不到

    当我们在本地开发的时候,会碰到static可以访问,但是用户上传的文件设置在media下不可访问怎么办?settings配置: 接着在你的urls文件添加: from . import setting ...

  6. SpringMVC上传文件后返回文件服务器地址路径

    先写一个表单: <%@ page language="java" contentType="text/html; charset=UTF-8" pageE ...

  7. input[type='file']获取上传文件路径案例

    最近在项目时,需要获取用户的上传文件的路径,便写了一个demo: <body> <input type="file" name="" valu ...

  8. 通过cmd完成FTP上传文件操作

    一直使用 FileZilla 这个工具进行相关的 FTP 操作,而在某一次版本升级之后,发现不太好用了,连接老是掉,再后来完全连接不上去. 改用了一段时间的 Web 版的 FTP 工具,后来那个页面也 ...

  9. FTP上传文件到服务器

    一.初始化上传控件. 1.我们这里用dropzone.js作为上传控件,下载地址http://www.dropzonejs.com/ 2.这里我们使用一个div元素作为dropzone载体. < ...

  10. Jmeter上传文件

    Jmeter上传文件 一.Fiddler抓包获取表单信息 操作被测系统,上传文件,Fiddler抓包获取提交表单信息如下:

随机推荐

  1. NSIS Studio2.1汉化版

    这个东西早些时候是我从老外那里下载回来后放在了群共享里面,中间跟着作者的节奏更新了几次,后来和LmTec聊这个软件的时候提出了汉化的设想,可能是LmTec兄弟看这个软件确实不错,就一口答应了下来,结果 ...

  2. Go的网络编程详解

    一 互联网协议介绍 1.1互联网分层模型 互联网的逻辑实现被分为好几层.每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持.用户接触到的只是最上面的那一层,根本不会感觉到下面的几层.要理解互联 ...

  3. <一>关于进程虚拟地址空间区域内存划分和布局

    C++代码在编译完成后会生产.exe程序(windows平台), .EXE以文件的形式存储在磁盘上,当运行.exe程序的时候 操作系统会将磁盘上的.exe文件加载到内存中,那么在加载到内存中的时候,操 ...

  4. Python地图栅格化实例

    Python地图栅格化实例 引言 shapefile是GIS中的一种非常重要的数据类型,由ESRI开发的空间数据开放格式,目前该数据格式已经成为了GIS领域的开放标准.目前绝大多数开源以及收费的GIS ...

  5. Spring的同一个服务为什么会加载多次?

    问题现象 最近在本地调试公司的一个Web项目时,无意中发现日志中出现了两次同一个服务的init记录,项目都是基于Spring来搭建的,按理说服务都是单例的,应该只有一次服务加载日志才对,本着对工作认真 ...

  6. Blazor组件自做十一 : File System Access 文件系统访问 组件

    Blazor File System Access 文件系统访问 组件 Web 应用程序与用户本地设备上的文件进行交互 File System Access API(以前称为 Native File ...

  7. 一天五道Java面试题----第八天(怎么处理慢查询--------->简述Myisam和innodb的区别)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1.怎么处理慢查询 2.ACID靠什么保证的 3.什么是MVCC 4.mysql主从同步原理 5.简述Myisam和inn ...

  8. nrf9160做modem——测试连接阿里云

    简介:在前面有讲过如何使用nrf9160去连接一个云,然后进行发布订阅信息,但是当时连接的是一个免费的测试云,在国内的话许多人想要连接阿里云或者华为云,下面就来测试一下连接阿里云.这里为什么要和上一篇 ...

  9. v-for中key的作用与原理

    一.虚拟DOM中key的作用 key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue会对新虚拟DOM与旧虚拟DOM的差异进行比较. 二.如何选择key 最好使 ...

  10. Mysql InnoDB Redo log

    一丶什么是redo innodb是以也为单位来管理存储空间的,增删改查的本质都是在访问页面,在innodb真正访问页面之前,需要将其加载到内存中的buffer pool中之后才可以访问,但是在聊事务的 ...