Thanks.
","upvoteCount":1,"answerCount":3,"acceptedAnswer":{"@type":"Answer","text":"Ah... I see the issue. This is because the JsonSerializerContext is defined by a source code generator. The Error Object types are protected to the writer itself, but are internal for the JsonSerializerContext. Once you inherit from it, they aren't visible in your derived implementation. The types themselves are structs so you can't inherit from them (which might have been a sleezy trick). The only thing you really need is the JsonSerializerContext, but since it's internal and the only thing that uses it is IConfigureOptions<T>, which is also internal, there's no way to access it without resorting to Reflection. 🤮
Arguably, this is a design flaw. It wasn't really clear to me how this might ever be extended. The correct, long-term library solution here is to simply provide a way to access or create the associated JsonSerializerContext; for example, some method or property on ErrorObjectWriter. That would certainly address your scenario. I'll queue that up for the next release. Unfortunately, that affects the public surface area and will require a minor version bump (but, that's not really a huge deal).
In the meantime, the best, most flexible option is to simply fork the entire implementation of ErrorObjectWriter verbatim. It's up to you if you want to use an alternate name (e.g. ConditionalErrorObjectWriter). Your implementation can be sealed and even internal if you like. No need for virtual members. The only difference in the fork will be the condition in CanWrite (as shown above in the original override). It's a bit unfortunate, but this approach seems to be the one with least amount of other weirdness. This type is already for backcompat. I don't expect this to ever change so you shouldn't have to worry about keeping your fork up-to-date. The only way I foresee that happening would be a bug in the implementation. Possible, but unlikely. Once there is a way to access ErrorObjectWriter.JsonSerializerContext in some future release, you can opt to replace the fork with the originally proposed subclass if you wish. The net result will be same though.
I don't have a better answer at the moment, but that should unblock you and get you back on your way.
","upvoteCount":0,"url":"https://github.com/dotnet/aspnet-api-versioning/discussions/1072#discussioncomment-8671227"}}}-
|
Hi. I am porting a legacy API from .NET 4.X to .NET 8. As part of this process, I am adding API versioning and updating to use the new standards (ProblemDetails, etc). I need to maintain input and output format fidelity to the existing API. I have already determined how to make the original API the default, when a version is not specified. I have also determined that I can provide my own InvalidModelStateResponseFactory to handle custom format of the 400 response when the model fails validation. However, when the new V2 API, I don't want to use the custom format for the V2 API calls. I would like to use the ProblemDetails response type. What is the recommended approach to use switch between the two response formats at runtime depending upon what version of the API was called? Do I just do something like this: Thanks. |
Beta Was this translation helpful? Give feedback.
-
|
There's certainly some complexity if you're running both scenarios in the same application, but it's possible. I haven't done this myself, but I'm pretty sure what would work for you is something like this: Extend
|
Beta Was this translation helpful? Give feedback.
-
|
@commonsensesoftware, thank you. Not a lot of complexity, as the existing service only has one controller with one method, but two routes configured. Easy enough. I just know there are changes coming later this year where I will need to extended the API. Since I currently porting this to .NET 8 from 4.7+ and migrating from RavenDB to Sqllite/SqlExpress and I have the time with no hard deadline, now is the time for me to get this code structured for the future changes. Including updating the code to use the new problem details format for model/request validation, exceptions. A few questions:
Can you please let me know where I can read more about how ProblemDetails is implemented in .Net 8. Thanks -marc |
Beta Was this translation helpful? Give feedback.
-
|
My apologues for the delayed response. When I drop the above code into my project (just copy and paste, no changes) and compile, I'm getting the following errors: I am going to assume that this has something to do with STJ converting the object serialization code at compile time and avoid the reflection based serialization. (As an aside, these errors are why I haven't turned this on for my own projects. Never seem to have figured out why there are errors being raised.). Thanks -marc |
Beta Was this translation helpful? Give feedback.
Ah... I see the issue. This is because the
JsonSerializerContextis defined by a source code generator. The Error Object types areprotectedto the writer itself, but areinternalfor theJsonSerializerContext. Once you inherit from it, they aren't visible in your derived implementation. The types themselves are structs so you can't inherit from them (which might have been a sleezy trick). The only thing you really need is theJsonSerializerContext, but since it'sinternaland the only thing that uses it isIConfigureOptions<T>, which is alsointernal, there's no way to access it without resorting to Reflection. 🤮Arguably, this is a design flaw. It wasn't really clear to me how this migh…