-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Use casing for ProblemDetails that specified by RFC #8529
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
However, wasn't ProblemDetails
released in 2.1? If so, might need a compat switch controlling the serialization
@@ -18,33 +18,33 @@ public class ProblemDetails | |||
/// (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be | |||
/// "about:blank". | |||
/// </summary> | |||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] | |||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "type")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: order PropertyName first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @glennc
We're tweaking ProblemDetails
to be more inline with the RFC. Needed your opinion on this:
public string Type { get; set; } | ||
|
||
/// <summary> | ||
/// A short, human-readable summary of the problem type.It SHOULD NOT change from occurrence to occurrence | ||
/// of the problem, except for purposes of localization(e.g., using proactive content negotiation; | ||
/// see[RFC7231], Section 3.4). | ||
/// </summary> | ||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] | ||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "title")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be construed as a breaking change from 2.1. if your app returned ProblemDetails
and used a Json.NET Contract resolver other than the default. The value specified in PropertyName
will be used ignoring the naming strategy.
e.g. If you changed MVC to use DefaultNamingStrategy
instead of CamelCase
:
In 2.1: { "Title": "Some title" }
In 2.2: { "title": "Some title" }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Json.NET is used on the client and the JSON is being deserialized then this isn't a problem. Json.NET will fallback to being case-insensitive when it can't find a match.
If JavaScript is used then this could break a user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed with @Eilon and we're OK with the breaking change here due to the rarity of the scenario, the fact that it fixes a bug, and the difficultly of providing a switch for the JSON case.
It would also be possible for someone to work around by defining their own version of ProblemDetails, and using the other features we provide to plug it in.
@@ -12,9 +12,11 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml | |||
/// <summary> | |||
/// Wrapper class for <see cref="Mvc.ProblemDetails"/> to enable it to be serialized by the xml formatters. | |||
/// </summary> | |||
[XmlRoot(nameof(ProblemDetails))] | |||
[XmlRoot("problem", Namespace = Namespace)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More of the same with Xml, although it does have more than casing changes:
2.1
<ProblemDetails>
<Title>Some title</Title>
<Status>403</Status>
<Instance>Some instance</Instance>
</ProblemDetails>
2.2
<problem xmlns="urn:ietf:rfc:7807">
<title>Some title</title>
<status>403</status>
<instance>Some instance</instance>
</problem>
Just wondering is there a reason why you're using the JSON.NET specific |
@Tornhoof the Json attribute was already there. More importantly, if it isn't JSON.NET, you almost have to write a converter of some sort to support the |
You mean the IDictionary? |
The spec requires that the property be serialized at the root level e.g. { "title": "..", "status" : 400, "keyFromDictionary": "valueFromDictionary" } and not as a property of a key named |
Duh, I forgot about that. The easiest way for the more advanced formatters is to derive from DynamicObject and simply return the "fixed properties" via Anyway it gets complicated very fast now. As long as JSON.NET is still the preferred serializer and the stuff from corefxlabs is not yet production-ready, we shouldn't really overcomplicate the problem. I rest my case. Thanks for answering my questions. |
* Use JsonProperty.MemberName to specify lowercase casing for ProblemDetails properties - https://tools.ietf.org/html/rfc7807#section-3 * Use XML NS and lowercase for Xml elements specified by RFC - https://tools.ietf.org/html/rfc7807#appendix-A Fixes #8501
ceec2a0
to
4ce807c
Compare
🆙 📅 The casing change is behind a compat flag now. |
@@ -442,6 +479,10 @@ public int MaxModelValidationErrors | |||
} | |||
} | |||
|
|||
internal event Action<MvcOptions> OnAfterPostConfigure; | |||
|
|||
internal void InvokeOnAfterPostConfigure() => OnAfterPostConfigure?.Invoke(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on our offline conversation, I tried making an MvcXmlOptions
type and putting the compat flag on it, setting up the xml formatters after the compat option was initialized. However, since nothing uses the options type, the configure never executes. Leaving the flag on MvcOptions seems like the least problematic way forward. However it also keeps this event
around and makes you 😭.
|
||
namespace Microsoft.AspNetCore.Mvc.Formatters.Json | ||
{ | ||
internal class ProblemDetailsConverter : JsonConverter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JamesNK could you review the converters?
4ce807c
to
857e664
Compare
857e664
to
6d147b0
Compare
using Microsoft.Extensions.Logging.Abstractions; | ||
using Xunit; | ||
|
||
namespace Microsoft.AspNetCore.Mvc.Formatters.Xml.Internal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type was renamed to https://github.com/aspnet/Mvc/pull/8529/files#diff-e7a152988018dcb2d8180cb94a414e95R8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🆙 📅 part duex
- Added
MvcXmlOptions
with compat flag - Added tests etc
/// higher then this setting will have the value <see langword="true"/> unless explicitly configured. | ||
/// </para> | ||
/// </remarks> | ||
public bool AllowRfc7807CompliantProblemDetailsFormat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a blurb here:
Version_2_2, |
} | ||
|
||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great 👍
https://tools.ietf.org/html/rfc7807#section-3
https://tools.ietf.org/html/rfc7807#appendix-A
Fixes #8501