我剛剛將一個dotnet core 3.1專案遷移到dotnet 5.0,從那時起我的單元測驗遇到了一個問題。我的一個單元測驗是測驗當反序列化一個AccountDto物件時回傳的錯誤(轉換器測驗)。
在我的dotnet 5.0遷移之前,我在我的單元測驗捕獲中得到了以下錯誤資訊。"記錄型別id '' 不被支持"。自從遷移后,捕獲的例外發生了變化:"記錄型別id ''不被支持。不支持的成員型別位于'System.String'型別上。Path: $.RecordTypeId | LineNumber: 0 | BytePositionInLine: 64."
。通過分析例外的內容,我注意到我的 RecordTypeConverter.Read() 中拋出的例外確實存在,但在內部例外中。
單元測驗 :
[Theory]
[InlineData("", null, "不支持記錄型別id ''。")]
protected void MapAccountRecordTypeTest(string recordTypeId, string recordTypeExpected, string errorExpected)。
{
var account = new AccountDto();
var error = string.Empty;
var accountDto = new AccountDto
{
RecordType = recordTypeId
};
var myjson = JsonSerializer.Serialize(accountDto)。
try
{
account = JsonSerializer.Deserialize<AccountDto>(myjson)。
}
catch (Exception ex)
{
error = ex.Message;
}
Assert.Equal(errorExpected, error);
}
單元測驗呼叫的代碼,并拋出我想捕捉的例外:
單元測驗呼叫的代碼,并拋出我想捕捉的例外。
public class RecordTypeConverter : JsonConverter<string>
{
private readonly Dictionary<string, string> _accountStatus = new( )
{
{ Constant.EnterPRISE_RECORD_TYPE_ID, Constant.EnterPRISE_RECORD_TYPE },
{ Constant.INDIVIDUAL_RECORD_TYPE_ID, Constant.INDIVIDUAL_RECORD_TYPE }, { Constant.INDIVIDUAL_RECORD_TYPE }.
};
public override string Read(ref Utf8JsonReader reader。Type typeToConvert, JsonSerializerOptions options)。
{
string value = reader.GetString();
if (value != null)
{
string key = value.ToUpper() 。
if (!_accountStatus.ContainsKey(key))
{
throw new NotSupportedException($"The record type id '{key}' is not supported." /span>)。
}
return _accountStatus[key];
}
return null;
}
public override void Write(Utf8JsonWriter writer。string value, JsonSerializerOptions options)
=> writer.WriteStringValue(value)。
}
捕獲的例外:
à System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& state, Utf8JsonReader& reader, NotSupportedException ex)
à System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
à System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
à System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, Type returnType, JsonSerializerOptions options)
à System.Text.Json.JsonSerializer.Deserialize[TValue](String json, Type returnType, JsonSerializerOptions options)
à System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
à tests.AccountTests.MapAccountRecordTypeTest(String recordTypeId, String recordTypeExpected, String errorExpected) dans D:XXXXXAccountTests.cs :ligne 72
在上述例外的內部出現的例外。我應該檢索的就是這個例外:
我應該檢索的是這個例外。
à SlxConnector.Helpers.Converters.RecordTypeConverter. Read(Utf8JsonReader& reader, TypeToConvert, JsonSerializerOptions options) dans d:XXXXXXXsrcHelpersConvertersRecordTypeConverter.cs :ligne 27
à System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
à System.Text.Json.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
à System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, TypeToConvert, JsonSerializerOptions options, ReadStack& State, T& value)
à System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
à System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
我知道如何調整我的單元測驗以使其作業,但我想了解為什么當我將專案遷移到.NET 5時,行為發生了變化。顯然,.NET 5 JsonSerializer引發了一個新的例外,從我的例外??
uj5u.com熱心網友回復:
在遷移到.NET 5之后,你的代碼會使用一個新版本的.NET運行時間。這個新版本提供了相同的公共介面來訪問功能("你的代碼如何請求反序列化"),但是內部實作("如何進行反序列化")卻不一樣了。 API和運行時的構建者會盡可能地保持公共介面不變,但內部實作的改變卻并不罕見。這樣做的目的是為了納入錯誤修復、改進或安全補丁。
在你的具體案例中,你得到了比以前更多的資訊--我也認為這是好的。正如您已經建議的那樣,調整您的單元測驗是處理這一問題的首選方式。
如果您想分析 .NET 運行時中的變化,您可以看看 JSON 序列化的代碼。
uj5u.com熱心網友回復:
我還沒有檢查到底是哪個版本改變了這一點,但是這個改變是在2020年3月6日進行的。現在,當你拋出一個NotSupportedException而沒有 "Path: ",它將使用ThrowHelper類來重新拋出。
來自源代碼的評論 :
。如果訊息已經包含了Path,就重新拋出。這可能發生在序列化器重新進入的情況下。 為了在重新進入的情況下獲得適當的 Path 語意,需要使用接受 "狀態 "的 API。
為了解決您的問題,您應該在例外的訊息中添加 "Path:",或者使用一個自定義的Exception。您還應該驗證JsonException是不是簡單的最合適的解決方案,因為您在反序列化之前檢查JSON的格式是否正確。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/320016.html
標籤:
下一篇:try/except和環境管理器
