Reputation: 57
I have a Dto that looks like this:
public class CreateObjectDto
{
public Guid SomeGuid { get; set; }
}
problem I'm having is that default Guid converter does not allow values outside "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" format, so users are required to enter Guid with dashes which is not desirable. I would like an option to parse any regular Guid whether it has dashes or not.
Error if I call api with different Guid format is:
{
"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."
]
}
}
EDIT with solution (modified accepted solution a bit):
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());
});
Upvotes: 2
Views: 1162
Reputation: 642
You have to use a custom JsonConverter https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-6-0 for the given type (Guid)
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());
}
Then you can use it by annoting the wanted Guid property.
public class CreateObjectDto
{
[JsonConverter(typeof(CustomGuidJsonConverter))]
public Guid SomeGuid { get; set; }
}
Upvotes: 1