场景

我们上传一个文件,把文件保存到服务器上,会有一个明确的物理路径,由于需要从前端访问这个文件,还需要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. 小程序uni-app发起网络异步请求

    // uni.request({ // url: 'api/boxs/search', // // 使用监听函数防止this指向改变 // success: res => { // // 判断是 ...

  2. OCI runtime exec failed: exec failed: unable to start container process: exec: "mongo": executable file not found in $PATH: unknown

    前言: 今天按照以往在Docker安装MongoDB的方式安装,但是到最后使用mongo命令执行mongodb命令的时候一直执行不成功,最后还是按照官网的Issues解决了. 创建并运行一个Mongo ...

  3. 怎样在GitHub上建立仓库、以及怎样实现分支代码的合并。保姆级别的教程

    GitHub官网地址:https://github.com/ 注意:前提是已经注册了GitHub 文章目录 第一步:创建一个新的仓库 第二步.创建一个分支 第三步.编辑和发布更改的内容 第四步.拉取请 ...

  4. Codeforces 1684 E. MEX vs DIFF

    题意 给你n个非负整数的数列a,你可以进行K次操作,每次操作可以将任意位置的数数更改成任意一个非负整数,求操作以后,DIFF(a)-MEX(a)的最小值:DIFF代表数组中数的种类.MEX代表数组中未 ...

  5. go-zero docker-compose 搭建课件服务(五):完善user服务

    0.转载 go-zero docker-compose 搭建课件服务(五):完善user服务 0.1源码地址 https://github.com/liuyuede123/go-zero-course ...

  6. LcdTools如何实现PX01读取SD中BIN文件并通过端口发出去

    在实际应用中我们会碰到需要下载很大容量固件,比如TP固件几百K大小BIN文件,这种情况下用LcdTools写初始化代码的方式实现就不大现实:此时我们可以通过PX01 SD来实现. 首先,把需要操作的B ...

  7. 4.httprunner-参数化和数据驱动

    前言 参数化在config中使用parameters关键字 httprunner2.x 是在testsuite中实现参数化 httprunner3.x 是在testcase中的config实现参数化 ...

  8. Vitepress搭建组件库文档(上)—— 基本配置

    在 vite 出现以前,vuepress 是搭建组件库文档不错的工具,支持以 Markdown 方式编写文档.伴随着 vite 的发展,vitepress 已经到了 1.0.0-alpha.22 版本 ...

  9. 前端监控系列4 | SDK 体积与性能优化实践

    背景 字节各类业务拥有众多用户群,作为字节前端性能监控 SDK,自身若存在性能问题,则会影响到数以亿计的真实用户的体验.所以此类 SDK 自身的性能在设计之初,就必须达到一个非常极致的水准. 与此同时 ...

  10. Scrapy 之 docker splash

    Scrapy 之 docker splash 1. ubuntu 安装docker 命令 curl -sSL https://get.daocloud.io/docker | sh 或者 curl - ...