.NET5 Web Api 如何允许任何格式的 Guid
.NET5 Web Api how to allow Guid in any format
我有一个看起来像这样的 Dto:
public class CreateObjectDto
{
public Guid SomeGuid { get; set; }
}
我遇到的问题是默认的 Guid 转换器不允许使用“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx”格式之外的值,因此用户需要输入带破折号的 Guid,这是不可取的。我想要一个选项来解析任何常规 Guid,无论它是否有破折号。
如果我用不同的 Guid 格式调用 api,错误是:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-1714eba1650b1548afd8581204d38a0c-ffc921fac3022540-00",
"errors": {
"$.attachmentList[0].documentId": [
"The JSON value could not be converted to System.Guid. Path: $.attachmentList[0].documentId | LineNumber: 0 | BytePositionInLine: 292."
]
}
}
编辑解决方案
(稍微修改了接受的解决方案):
CustomGuidConverter:
public class CustomGuidConverter : JsonConverter<Guid>
{
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (!Guid.TryParse(reader.GetString(), out var parsedGuid))
{
throw new Exception($"Unable to parse {reader.GetString()} to GUID");
}
return parsedGuid;
}
public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString("D"));
}
startup.cs:
// add this line to apply conversion globally and not only for one property
services.AddMvc().AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.Converters.Add(new CustomGuidConverter());
});
您必须为给定类型 (Guid) 使用自定义 JsonConverter https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-6-0
public class CustomGuidJsonConverter : JsonConverter<Guid>
{
private Regex _uwCharsRegex = new Regex("[ \t-]");
private Regex _validityRegex = new Regex("[a-f0-9]{32}");
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string value = _uwCharsRegex.Replace(reader.GetString(), "").ToLower();
// Check validity
if (!_validityRegex.IsMatch(value))
{
return Guid.Empty; // or throw exception
}
return new Guid(value);
}
public override void Write(Utf8JsonWriter writer, Guid guidValue, JsonSerializerOptions options)
=> writer.WriteStringValue(guidValue.ToString());
}
然后你可以通过注释想要的Guid来使用它属性。
public class CreateObjectDto
{
[JsonConverter(typeof(CustomGuidJsonConverter))]
public Guid SomeGuid { get; set; }
}
我有一个看起来像这样的 Dto:
public class CreateObjectDto
{
public Guid SomeGuid { get; set; }
}
我遇到的问题是默认的 Guid 转换器不允许使用“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx”格式之外的值,因此用户需要输入带破折号的 Guid,这是不可取的。我想要一个选项来解析任何常规 Guid,无论它是否有破折号。
如果我用不同的 Guid 格式调用 api,错误是:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-1714eba1650b1548afd8581204d38a0c-ffc921fac3022540-00",
"errors": {
"$.attachmentList[0].documentId": [
"The JSON value could not be converted to System.Guid. Path: $.attachmentList[0].documentId | LineNumber: 0 | BytePositionInLine: 292."
]
}
}
编辑解决方案 (稍微修改了接受的解决方案):
CustomGuidConverter:
public class CustomGuidConverter : JsonConverter<Guid>
{
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (!Guid.TryParse(reader.GetString(), out var parsedGuid))
{
throw new Exception($"Unable to parse {reader.GetString()} to GUID");
}
return parsedGuid;
}
public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString("D"));
}
startup.cs:
// add this line to apply conversion globally and not only for one property
services.AddMvc().AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.Converters.Add(new CustomGuidConverter());
});
您必须为给定类型 (Guid) 使用自定义 JsonConverter https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-6-0
public class CustomGuidJsonConverter : JsonConverter<Guid>
{
private Regex _uwCharsRegex = new Regex("[ \t-]");
private Regex _validityRegex = new Regex("[a-f0-9]{32}");
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string value = _uwCharsRegex.Replace(reader.GetString(), "").ToLower();
// Check validity
if (!_validityRegex.IsMatch(value))
{
return Guid.Empty; // or throw exception
}
return new Guid(value);
}
public override void Write(Utf8JsonWriter writer, Guid guidValue, JsonSerializerOptions options)
=> writer.WriteStringValue(guidValue.ToString());
}
然后你可以通过注释想要的Guid来使用它属性。
public class CreateObjectDto
{
[JsonConverter(typeof(CustomGuidJsonConverter))]
public Guid SomeGuid { get; set; }
}