.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; }
}