使用JsonConverter處理上傳文件的路徑問題
場景
我們上傳一個文件,把文件保存到服務器上,會有一個明確的物理路徑,由于需要從前端訪問這個文件,還需要web服務器中的一個虛擬路徑。這個虛擬路徑的存儲會有一個問題,我們應該在數(shù)據(jù)庫里存什么?是帶域名的全路徑,還是相對于web根目錄的相對路徑?
現(xiàn)在很多架構都是前后分離的,所以前端訪問的url是全路徑比較好,不像之前前后都是一個項目中,數(shù)據(jù)庫存相對路徑,前端也使用相對路徑訪問沒有問題。
如果存全路徑,域名更換的時候就比較麻煩,需要手動把數(shù)據(jù)庫里的數(shù)據(jù)替換一下。如果存相對路徑,返回前端的時候需要手動的補全路徑,也不是太好。
解決方法
我們可以使用JsonConverter
來自動處理一下,具體方法是保存相對路徑,返回的時候自動加上前綴組成全路徑。
/// <summary> /// 處理圖片文件前綴,數(shù)據(jù)庫中存相對路徑即可 /// </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 => { //忽略循環(huán)引用問題 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });
然后在上傳路徑的字段上加JsonUrlPrefixConverter
便可以自動處理。
如頭像字段:
/// <summary> /// 頭像 /// </summary> [JsonConverter(typeof(JsonUrlPrefixConverter))] public string Avatar { get; set; } = "";
如前端保存時傳給后端的是 "http://www.abc.com/upload/avatar.jpg" ,經(jīng)過 JsonUrlPrefixConverter
處理,會得到 "/upload/avatar.jpg" 保存到數(shù)據(jù)庫,當從后端返回到前端的時候,會自動加上前綴,又變成了 "http://www.abc.com/upload/avatar.jpg" 。
這樣如果域名變了,修改一下配置的前綴即可。
到此這篇關于使用JsonConverter處理上傳文件的路徑的文章就介紹到這了,更多相關JsonConverter處理上傳文件的路徑內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
c#基礎之數(shù)組與接口使用示例(遍歷數(shù)組 二維數(shù)組)
本文主要介紹了c#基礎知識中的數(shù)組與接口使用方法,結合示例,大家一看就明白2014-01-01