使用JsonConverter處理上傳文件的路徑問題
場景
我們上傳一個(gè)文件,把文件保存到服務(wù)器上,會有一個(gè)明確的物理路徑,由于需要從前端訪問這個(gè)文件,還需要web服務(wù)器中的一個(gè)虛擬路徑。這個(gè)虛擬路徑的存儲會有一個(gè)問題,我們應(yīng)該在數(shù)據(jù)庫里存什么?是帶域名的全路徑,還是相對于web根目錄的相對路徑?
現(xiàn)在很多架構(gòu)都是前后分離的,所以前端訪問的url是全路徑比較好,不像之前前后都是一個(gè)項(xiàng)目中,數(shù)據(jù)庫存相對路徑,前端也使用相對路徑訪問沒有問題。
如果存全路徑,域名更換的時(shí)候就比較麻煩,需要手動把數(shù)據(jù)庫里的數(shù)據(jù)替換一下。如果存相對路徑,返回前端的時(shí)候需要手動的補(bǔ)全路徑,也不是太好。
解決方法
我們可以使用JsonConverter 來自動處理一下,具體方法是保存相對路徑,返回的時(shí)候自動加上前綴組成全路徑。
/// <summary>
/// 處理圖片文件前綴,數(shù)據(jù)庫中存相對路徑即可
/// </summary>
public class JsonUrlPrefixConverter : JsonConverter
{
private string urlPrefix;
public JsonUrlPrefixConverter()
{
urlPrefix ="htttp://www.abc.com"; //這里前綴可以做成配置,換域名時(shí)改一下配置即可
}
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 項(xiàng)目中需要指定一下序列話還使用 Newtonsoft.Json。
builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
{
//忽略循環(huán)引用問題
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});然后在上傳路徑的字段上加JsonUrlPrefixConverter 便可以自動處理。
如頭像字段:
/// <summary>
/// 頭像
/// </summary>
[JsonConverter(typeof(JsonUrlPrefixConverter))]
public string Avatar { get; set; } = "";如前端保存時(shí)傳給后端的是 "http://www.abc.com/upload/avatar.jpg" ,經(jīng)過 JsonUrlPrefixConverter 處理,會得到 "/upload/avatar.jpg" 保存到數(shù)據(jù)庫,當(dāng)從后端返回到前端的時(shí)候,會自動加上前綴,又變成了 "http://www.abc.com/upload/avatar.jpg" 。
這樣如果域名變了,修改一下配置的前綴即可。
到此這篇關(guān)于使用JsonConverter處理上傳文件的路徑的文章就介紹到這了,更多相關(guān)JsonConverter處理上傳文件的路徑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VS2019 找不到資產(chǎn)文件 “xxxx\obj\project.assets.json”運(yùn)行NuGet包還原以生成此文
這篇文章主要介紹了VS2019 找不到資產(chǎn)文件 “xxxx\obj\project.assets.json”運(yùn)行NuGet包還原以生成此文件,本文給大家分享解決方案,感興趣的朋友跟隨小編一起學(xué)習(xí)吧2020-08-08
C#實(shí)現(xiàn)位圖轉(zhuǎn)換成圖標(biāo)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)位圖轉(zhuǎn)換成圖標(biāo)的方法,可實(shí)現(xiàn)將bmp格式位圖轉(zhuǎn)換成ico格式圖標(biāo)的功能,需要的朋友可以參考下2015-06-06
淺談C#跨線程調(diào)用窗體控件(比如TextBox)引發(fā)的線程安全問題
下面小編就為大家分享一篇淺談C#跨線程調(diào)用窗體控件(比如TextBox)引發(fā)的線程安全問題,具有很好的參考價(jià)值,希望對大家有所幫助2017-11-11
快速解決C# android base-64 字符數(shù)組的無效長度問題
下面小編就為大家?guī)硪黄焖俳鉀QC# android base-64 字符數(shù)組的無效長度問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08
C#實(shí)現(xiàn)打開畫圖的同時(shí)載入圖片、最大化顯示畫圖窗體的方法
這篇文章主要介紹了C#實(shí)現(xiàn)打開畫圖的同時(shí)載入圖片、最大化顯示畫圖窗體的方法,涉及C#針對窗體及圖片操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08

