JSON support gets a major missing feature in .NET 7

  Рет қаралды 50,791

Nick Chapsas

Nick Chapsas

Күн бұрын

Пікірлер: 161
@andrewshirley9240
@andrewshirley9240 2 жыл бұрын
I don't like it for the same reason as everyone else- the parent needing to be aware of implemented types sounds like a huge anti-pattern and this approach probably shouldn't be supported at all. The approach with the typeinfo contract is a little better, but it's not really any less maintenance. As an example I've seen before, a video game may have an 'Item" class, that subtypes into "Consumable/Equipment/KeyItem/etc", and you may want to serialize an array of items. Having to go and catch *every single* item implementation in this registration in order to have it work properly seems awful. However, what the typeinfo contract option DOES open up is a reflection-based approach like we see in dependency injection helpers. I could totally imagine someone making a library that allows you to pass in a type and say "reflect to get all of its implementations, and register them with this serializer behavior." Then we just say "ConfigureInheritance(typeof(Item), [optionalUnmatchedBehavior], [optionalAssemblyForImplementations])" and all of the implementations are taken care of. I know why registering the parent on a child-per-child basis doesn't really work, since at the time of deserialization all the serializer knows is "parent type", and any solution involving the configuration of child elements would end up having to modify some global state or something. I DO understand why this needs to be locked down compared to how Newtonsoft does it, where they just have a single option that says "try and initialize any type I give it!" That was a big security hole and serialization attacks are a real thing, so I think making you register the exact expected types is a smart way around the issue.
@mindstyler
@mindstyler 2 жыл бұрын
this could be done with a source generator and be even better
@cverde1234
@cverde1234 2 жыл бұрын
I don't like having to couple a type to its derived types via an attribute. Decorating the sub-type with an attribute could work and be cleaner dependency-wise.
@seldomseen_78
@seldomseen_78 2 жыл бұрын
It looks like they got this one backward.
@davidmartensson273
@davidmartensson273 2 жыл бұрын
The problem with decorating the subtype is that it would need to search through all assemblies to find if there exist any type that are deriving since that cannot be found from the base type. And that could be even harder in case you have dynamic loading of assemblies for types that did not exist when you first start up the program. How often should you scan, every time you fail to find a type? That would be a performance problem very quickly. So that's why you would use you own type resolver and register that with JSON.
@ReazonIAm
@ReazonIAm 2 жыл бұрын
@@davidmartensson273 It can be code generated/cached on the startup(by just marking that some base class requires scanning) or at runtime on first type deserialization and have some support method to let the serializer know, that some(or exact) library was loaded and requires to be scanned/do it on loading if it has attributes. It might perform poorly if you have thousands of base types and you could argue this won't be convenient in case of assembly loading, but dynamic assemblies introduce enough problems (as a part of it's core desing) to be less convenient in almost all of the cases. Right now it conflicts with one the best and used design principle. I'm not sure how big of a problem this could be, but it's odd to say the least.
@davidmartensson273
@davidmartensson273 2 жыл бұрын
@@ReazonIAm I agree that is feels backwards, but I have seen the same solution in other serialisation libraries so I think its a "safe" solution. The thing with what Microsoft includes in the base libraries is that it must fit all use cases more or less unless you explicitly diverge from recommended solutions, thats why they sometimes avoid adding some convenient solution that other tool kits have so in this case I think they used this as it will work for any situation where it can be tried, it will explicitly not work for dynamically loaded types since the base type cannot know about those which solves that problem.
@davidmartensson273
@davidmartensson273 2 жыл бұрын
@@passenger9000 unless the class single purpose is serialization, in which case I think it can be appropriate.
@der.Schtefan
@der.Schtefan 2 жыл бұрын
The built-in Json was supposed to be kept very simple, fast, alloc free, etc. and now it adds more and more magic. I just hope they won't slow the core functionality down.
@Daniel-ml4jr
@Daniel-ml4jr 2 жыл бұрын
@@mw3653 You're embarrassing yourself.
@haukurorsson833
@haukurorsson833 2 жыл бұрын
@@mw3653 Are you OK?
@adinwashere
@adinwashere 2 жыл бұрын
@@haukurorsson833 nope
@haukurorsson833
@haukurorsson833 2 жыл бұрын
@@xybersurfer He said something along the lines of "It is open source so why don't you contribute to it instead of going on KZbin and posting such a lazy comment".
@Necromo7ph
@Necromo7ph 2 жыл бұрын
The solution is really simple for serialization. Point2d p = new Point3d { }; string s = JsonSerializer.Serialize(p, p.GetType());
@rxuhwxx4tmly9xvcktcn2znpsx4
@rxuhwxx4tmly9xvcktcn2znpsx4 2 жыл бұрын
right on time after a high severity vulnerability was found in Newtonsoft.Json (GHSA-5crp-9r3c-p9vr)
@VitorSubs
@VitorSubs 2 жыл бұрын
I believe this could already be "solved" by passing the type of object as a second argument on the serializer
@Omego2K
@Omego2K 2 жыл бұрын
I don't like it. With this the base type needs to be aware of the derived type
@TuxCommander
@TuxCommander 2 жыл бұрын
Actually I would like to have the same TypeHandling experience as NewtonSoft JSON offers so I can deserialze Interface objects.
@TuxCommander
@TuxCommander 2 жыл бұрын
@@mw3653 everybody who wants to easy use NewtonSoft JSON in a minimal API...
@Krimog
@Krimog 2 жыл бұрын
Would it work (and have a Point3D object in memory) if at 6:51 instead of Deserialize you used Deserialize? I hope so because I think that's the point of the feature.
@ИванБармин-ю1т
@ИванБармин-ю1т 2 жыл бұрын
the same question, since now this feature looks meaningless, since it will be necessary to study the discriminator, and only after deserialize
@nickchapsas
@nickchapsas 2 жыл бұрын
It would. That's what I actually wanted to show working but I made a mistake in the video
@christophsiebert1213
@christophsiebert1213 2 жыл бұрын
@@mw3653 Just stop it.
@TodPalin
@TodPalin 2 жыл бұрын
I'm sitting here reading how people don't want to "break polymorphism" thinking why on earth you would cast a type back to its base and expect anything to treat it like you hadn't? You cast it to Point2D it's a Point2D, I don't want to serialise it as anything else.
@shahfaisal3923
@shahfaisal3923 2 жыл бұрын
Thank you so much for this video. Love and respect from Afghanistan.
@Zapo9668
@Zapo9668 2 жыл бұрын
This is fantastic. I really need this feature asap.
@hodor2704
@hodor2704 2 жыл бұрын
Thanks Nick. probably I am missing something. why does it have to be so complex? if I serialize something, I should be able to serialize the actual instance without taking the reference type into account. If I deserialize something, I know what type I am expecting it to be. what am I missing?
@QwDragon
@QwDragon 2 жыл бұрын
6:26 Was it supposed to be Deserialize?
@nickchapsas
@nickchapsas 2 жыл бұрын
Yes
@Matt23488
@Matt23488 2 жыл бұрын
Was just about to comment that it was frustrating that such a feature needs attributes. Glad to know support is coming for an alternative approach. I prefer to use as few attributes as possible.
@nickchapsas
@nickchapsas 2 жыл бұрын
Seems to be a trend. Most libraries offer non-attribute alternatives as they should, but not all of them do which can be really annoying
@HenrryPires
@HenrryPires 2 жыл бұрын
What happen if Point2D it's in a dll that i included in my project? I can't just change it
@nickchapsas
@nickchapsas 2 жыл бұрын
That's where the solution shown in the end comes in handy
@OlegKosmakov
@OlegKosmakov 2 жыл бұрын
Cool, I was not happy when I had to implement the polymorphic deserialization myself. Had to deserialize it once just to find the type, and then deserialize it again to concrete type. I wonder how this new feature works under cover, does it always expect the type to be the first JSON node?
@nickchapsas
@nickchapsas 2 жыл бұрын
The type doesn’t have to be the first json property no since property ordering doesn’t matter in json and can’t be guaranteed between serialisers
@DmitryV_HF
@DmitryV_HF 2 жыл бұрын
What wrong with concrete deserialize? You want abstract JSON - use it, want strong type - use XML. This new feature not guaranty nothing. Only you know about target correct type, or prefix name. You use this json for self application and dont know about object type? If this external json, so you will be waiting reading prefixes inside data?
@davidmartensson273
@davidmartensson273 2 жыл бұрын
My guess is that it first deserializes to some generic dictionary/array structure and then builds an object from that. That way it can parse all properties and then decide what to do. I built something similar several years ago before we started using NewtonSoft and only had the old built in JavascriptSerializer ;).
@robslaney3729
@robslaney3729 2 жыл бұрын
@6:45 Even though you cast to a Point2D, you specified Point3D on the generic method
@zCri
@zCri 2 жыл бұрын
finally this is a thing, i was having so many issues with this
@skurtbert
@skurtbert 2 жыл бұрын
TY!
@baka_baca
@baka_baca 2 жыл бұрын
Handling JSON in .NET still doesn't look great to me here and this isn't really what I would've wanted as a priority. Honestly, I would prefer to keep things simple by looking to how JavaScript handles JSON. We could have a Json.Parse(string json), and a Json.Stringify(obj data, JsonOptions options). Parse would deserialize the relevant properties to the passed in type even if camel cased, Stringify would serialize public properties to a json string using camel case by default (because honestly that is fairly standard and has been for a while) but you could still pass in options to override this. If you're having the problem described in this video, try using interfaces instead of inheritance or just stick with making a simple class which takes care of storing the deserialized json data and nothing else. Piling on all of this mess on top of the problem makes things even more complicated than before, not really convinced this is an improvement.
@shenlong3879
@shenlong3879 2 жыл бұрын
Like many others I'm not sure how I feel about the circular dependencies in there. Having a base class refer to something of a derived class kind of breaks polymorphism. Also for the first example if I treat a variable as a Point2D instead of a Point3D I usually don't want it to have the additional information of the Point3D unless I actually treat it as a Point3D again. The way I use variables already explicitly tells the code how I want it to be treated. One more reason why I use explicit types instead of vars. It may come in handy when you want all the data of a collection of a base class or interface with a wide variety of items but that should also be more explicit.
@abj136
@abj136 2 жыл бұрын
Indeed. I want the thing to behave like myPoint.JsonSerialize() which is a virtual call that is overridden by the most dervied type. I would think a simple [JsonSeriaize] attribute in each class that has attributes that should output would be a better way. And something similar to do the reverse.
@ziauddinahmed2684
@ziauddinahmed2684 Жыл бұрын
I have a json response, it has mane nested object. The problem is it sometime give object array and sometime send just object. So its hard to deserealize. Example : Result : { Car :{ "name":" bmw" "Model":" z"} } Result : { Car :[{ "name":" bmw" "Model":" z"}, { "name":" Toyota" "Model":" sls"}] } Is there anyway easy way to solve the issue. So it can be deserilize in a specific type. What i am doing is checking if its an array or object then converting each object to an array. Thanx in advance. 😊
@bondarenkodf
@bondarenkodf 2 жыл бұрын
Great idea, but how to manage if you have configuration base class in one library and many sub-configuration classes in different DLL (including the future ones)? That attribute is a huge limitation.
@davidmartensson273
@davidmartensson273 2 жыл бұрын
That's when the resolver comes to the rescue if they implement it, or if they implement some way to directly register derived classes like JSON.RegisterDerivedClass() So all libraries then can do their own registrations
@telamarandrew2778
@telamarandrew2778 2 жыл бұрын
@@davidmartensson273 , it is so interesting that they can't implement smth working out of the box without registration. The default scenario which you can override or extend
@davidmartensson273
@davidmartensson273 2 жыл бұрын
@@telamarandrew2778 In theory they probably could but not without performance penalty. As I wrote in an other comment, when MS adds something to the base libraries they cannot leave undefined edge cases which means whatever they add either must even work for dynamically loaded assemblies or fail to compile for those cases. If you skipped those you could have something that will find any existing derived classes on compile and allow that but then if you add some new dynamically that would fail in runtime :/. And it is possible that you actually would NOT want all derived classes to serialize completely, you might have a derive class for internal use with properties you would not want stored and where you expect the current behavior of skipping all properties from derived classes. So it could also break the promise of backwards compatibility. For third party libs that could be acceptable, but not for default libs.
@davidmartensson273
@davidmartensson273 2 жыл бұрын
@@mw3653 for larger, partly legacy, you might not have the option to do the best and need to settle for good enough.
@L1da77
@L1da77 2 жыл бұрын
Not sure what I think about this. If a Point3D is also a point2D through inheritance then why not just use the Point3D as a point2D instead of serializing back and forth? If I reduce a class to something else then I'd expect the extra data to be garbage collected. I'm probably missing something but this seems like an edge case imho 🤔
@Srhyle
@Srhyle 2 жыл бұрын
3:03 "some value" huh... 🤣🤣
@SlackwareNVM
@SlackwareNVM 2 жыл бұрын
I love the type resolver. I very much prefer it over adding attributes everywhere.
@SlackwareNVM
@SlackwareNVM 2 жыл бұрын
@@mw3653 We've had some very difficult to resolve issues that have come from attributes from 3rd party libraries. If you think you'll be fine, pick whatever option you like.
2 жыл бұрын
Always nice with alternatives, but most would probably just pick one of these: Point2d point3d = new Point3d(); JsonSerializer.Serialize(point3d); JsonSerializer.Serialize((object)point3d); JsonSerializer.Serialize(point3d, point3d.GetType()); One feature I don't think to many know about that is this one: [JsonExtensionData] public Dictionary ExtensionData { get; set; }
@andytroo
@andytroo 2 жыл бұрын
is this available as a separate library, or do you have to bump your entire project to net7 to use it?
@franko6487
@franko6487 Жыл бұрын
I stumbled into this yesterday and lost 6 hours. I couldn't get arrays of types to deserialize. I was trying to couple it with StrongGrid which has a lot of polymorphic classes representing SendGrid events. I went back to rolling my own quick hack to serialize strongly typed events into my message queue and then out to Cosmos. This implementation has a lot of edges imo.
@Denominus
@Denominus 2 жыл бұрын
I get why this is useful, but more as an escape hatch/kludge. I would strongly advise designing away from needing a type discriminator in your contracts.
@AlanDarkworld
@AlanDarkworld 2 жыл бұрын
At long last, it was about time. Jackson had @JsonSubTypes for a while and it makes life so much easier. What I don't get in the video: why exactly does the *static* type of a variable matter when I pass it into the Json *serializer*? The serializer can just do a "typeof(input)" and use reflection from there. I see no reason why it would behave differently when my variable is Point2D or Point3D, it's about the content, isn't it? Deserialization is of course another matter.
@marcotroster8247
@marcotroster8247 2 жыл бұрын
What about Liskov Substitution Principle??? 😅🤔🙃
@fred.flintstone4099
@fred.flintstone4099 Жыл бұрын
Is this useful for JSON-LD?
@TheMannihilator
@TheMannihilator 2 жыл бұрын
the type distinguisher via attribute is just like putting a property with the typename into the class and switch-case again when serializing/deserializing the type still not worse than the idea of listing all derived types as an attribute
@sunefred
@sunefred 2 жыл бұрын
Wow! I have been waiting for this. One of the must haves to move away from Newtonsoft. Fluent API would be nice though in top of the resolver mechanisms.
@sunefred
@sunefred 2 жыл бұрын
@@mw3653 Yeah, right!??? 1MB man =)
@phizc
@phizc 2 жыл бұрын
Does S.T.Json have the same problem with members too? E.g. a class that has a Point2D member, but it's assigned a Point3D. Would it get serialized as a Point2D? I've been making reader/writers for the 3D formats glTF and DAZ Studio's dson format, and I know it would bite me for dson. I think glTF is not polymorphic, bit dson definitely is. Luckily I haven't gotten around to making a writer for it, and I've been doing deserializing using JsonConverters. As for attributes, they should do it like Entity Framework. All of that should be possible to with a Context class and (model)builders.
@darkelfasian
@darkelfasian 2 жыл бұрын
Hi Nick, what IDE are u using? It doesn't look like Visual Studio
@nickchapsas
@nickchapsas 2 жыл бұрын
It’s not visual studio. It’s Jebrains Rider
@leonov_am
@leonov_am 2 жыл бұрын
@@nickchapsasand it isn't for free, such a pitty
@ApacheGamingUK
@ApacheGamingUK 2 жыл бұрын
Much like everyone else here, this set off immediate alarm bells, and seems like one massive code smell. I assumed that the feature would simply allow you to add a generic type to the Serialise() method, and potentially, an optional mapping function as an optional parameter. So on line 10 in the example, you'd have "string point3dAsText = JsonSerializer.Serialize(point3d, SerialisationMapper.Default.MapImplicitly())". This would allow a lot more flexibility, whilst keeping the whole process as intuitive, and user friendly as possible. Not to mention that you resolve the backwards-heirarchy issues involved in adding volatile static annotation to what should be boilerplate code.
@glumboi9946
@glumboi9946 2 жыл бұрын
Could you make a video about copilot alternatives which are free?
@christianjansson6806
@christianjansson6806 2 жыл бұрын
What is that you say in the beginning of each video; "If you like abdobeidob content..."? Big fan of your channel and everything else is crystal clear! :-)
@GuidoSmeets385
@GuidoSmeets385 2 жыл бұрын
I wonder how many injection attacks this will cause in the next few years. Type discriminators are great vectors for attacks like that. I hope they'll have an option to turn this off. Regarding wanting to use inheritance: just don't for DTO's. I've never in the past 10 years used inheritance in DTO's and not regretted it later. You can address almost all those issues easily with composition instead of inheritance. And for those rare cases where it's useful to enforce a set of shared properties among classes, use an interface.
@eipigamma
@eipigamma 2 жыл бұрын
What about when you have to represent a union type? Afaik, this is usually achieved through inheritance since we lake proper union type, or alternatively through some of the libraries that implement union type behavior as generics, but in both case, I guess deserializing would be hard without proper type annotation?
@MaxStagsted
@MaxStagsted 2 жыл бұрын
As always good video Nick. I don't like the "feature", like others have mentioned, decorating the parent class, just seems wrong, not your fault though.
@Алексей-я7т4б
@Алексей-я7т4б 2 жыл бұрын
Nice numbers
@Алексей-я7т4б
@Алексей-я7т4б 2 жыл бұрын
@@mw3653 No
@infeltk
@infeltk 2 жыл бұрын
If JSON doesn't care about Z value that means that it is crap and they should use another lib. Point3D is new type and there is no reason to omit Z - it is normal property. And then appears Net 7 (that mean dude buy a new Visual Studio) and aaawesssome improvement - special magic @4:35. Am I wrong? Microsoft has much money I can''t write good library. It is not first time when Microsoft uses hack instead make better library in the past.
@jamirkuhn5206
@jamirkuhn5206 2 жыл бұрын
What IDE he uses?
@noctavel
@noctavel 2 жыл бұрын
I didnt like the fact that you have to specify the derived attr on the base class. Its seems really nasty to me
@noctavel
@noctavel 2 жыл бұрын
@@mw3653 i won’t ;)
@xMrMiagix
@xMrMiagix 2 жыл бұрын
X = 4 Y = 20 Z = 69. Nice
@andr6087
@andr6087 2 жыл бұрын
Thank you from Ukraine! 🇺🇦🇬🇧
@ibnfpv
@ibnfpv 2 жыл бұрын
This derived behavior of not printing the derived properties of the runtime object , is an decision behaviure the developers choose it is written on MSDN page , it was to prevent cases you print unwanted or sensitive derived class properties. The solution is very wierd to me with all the attributes /: Why there is no global / serilazation options for the expected behavior let the developer choose what good for his impl , This is the default behavior of newtonsoft for example For now in older . Net versions the solution is to specify the Type in the deserialized method / deserialized to type object only then the runtime properties of the derived class will be written
@LuigWollknaeuel
@LuigWollknaeuel 2 жыл бұрын
Since I am working with complex objects and multiple layers of inheritance in my current Blazor project, I yeeted the Blazor HTTP client and reconfigured it to request and respond in BSON instead, using the MongoDB BSON Serializer. It comes with this functionality by default, and no attributes are required on base classes to include derived types.
@carldaniel6510
@carldaniel6510 2 жыл бұрын
I love attributes in general, but I hate this use of attributes. Decorating the base class with information about the derived types is such an anti-pattern I'm surprised they even proposed it. The Type Resolver construct is essentially how Newtonsoft handles it, it's what everyone is accustomed to, and it doesn't pollute the base class with knowledge of the derived types. Win-win. If it was up to me, I'd drop the whole attribute-based approach and go with the type resolver solution alone.
@thegnosticatheist
@thegnosticatheist 2 жыл бұрын
AYFKM? And I though only Unity JSON serializer had this issue...
@egoegoone
@egoegoone 2 жыл бұрын
Still using newtonsoft in complex projects. Too many missing features missing from stjson. Though this is a Big hurdle out of the way.
@leonov_am
@leonov_am 2 жыл бұрын
Hello, I know another way to serialize derived type properly, is look like Point2D point3d = new Point3D(){ X = 10, Y = 15, Z = 20 }; string point3dstr = JsonSerializer.Serialize((object)point3d); you just must explicit your type to object type.
@gjoerulv
@gjoerulv 2 жыл бұрын
3:00 A Z value, just some value....
@joephillips6634
@joephillips6634 2 жыл бұрын
This is exactly one reason why I'm stuck using newtonsoft in some places. Glad they're making this improvement
@calebvear7381
@calebvear7381 2 жыл бұрын
@@mw3653 dude why are you so salty?
@shoutatme7362
@shoutatme7362 2 жыл бұрын
Or they could just do .GetType() on the object?? What were they thinking with this way of doing it?!?!?
@realivanjx
@realivanjx 2 жыл бұрын
this hardly any problem for me since i hardly do inheritance especially for DAO
@Servetnyk
@Servetnyk 2 жыл бұрын
What it would be, if I need to deserialize JSON that can be either type or array of type? What I mean. There is an (not mine) API and I send a Get request for items (e.g. Fruits). So if API has several items to return, it will return Fruits { { amount = 2 }, [ { item = Banana }, { item = Apple } ] }. But if API has the only one item to return, it returns Fruits { { amount = 1 }, { item = Banana } }. And you never know what result you will get.
@IbrahimKwakuDuah
@IbrahimKwakuDuah 2 жыл бұрын
Read the amount and decide what to do.
@Servetnyk
@Servetnyk 2 жыл бұрын
@@IbrahimKwakuDuah , well, I need to deserialized first. How? Then I need to create a converter to convert from type to array of type. To be possible to always return an array of type variable.
@spectrecular9721
@spectrecular9721 Жыл бұрын
4:20 - Technically, it serialized correctly because oftentimes after a lengthy 420 session, you fall asleep before you can 69 😏
@alexclark6777
@alexclark6777 2 жыл бұрын
I'm sure there's some motivation for requiring the attributes to be decorating the base type rather than individually applied to the derived types, but I'm not sure what those would be. Maybe to give ser/deser control to the author of the base type rather than letting derived consumers decide for themselves?
@GumbootMan
@GumbootMan 2 жыл бұрын
When deserializing you can pass in the base type as the type parameter, and if the JSON represents a derived type it will return that derived type. In this case the deserializer only has the base type and needs to know the possible derived types (and their discriminator strings). Attaching this information to the base type is straightforward and fast. Sure, you could fully scan the assembly for derived types, but that is slow and doesn't play well with assembly trimming. It sounds like they're planning on adding an API to register this same information, which would mean if you want the slow (but clean) way you can have it.
@alexclark6777
@alexclark6777 2 жыл бұрын
@@mw3653 Sorry for upsetting you.
@fl028
@fl028 2 жыл бұрын
Same thing I‘m using with Newtonsoft.Json TypeNameHandling and Interfaces. Very helpfull in WebApps :)
@figloalds
@figloalds 2 жыл бұрын
This is absolutely great, I might finally migrate from Newtonsoft Json after this
@BinaryReader
@BinaryReader 2 жыл бұрын
Nope, handling union data structures is actually one of the worst aspects of nominal type systems, It's nice that .NET is trying to offer something here, but discriminators defined as attributtes is highly unintuitive. I actually find TypeScript discriminated unions to be far superior as rather than pushing descriminator fields into some common base class (which would have made for a better demo btw), TypeScript's structural type system simply allows you to group many types under a common alias type (where narrowing is achieved through control flow analysis, like if/switch). This is a far more natural representation of such types (and really important if you care about representing types in the same way across TS/C#). TypeScript also supports type intersection which can't be expressed at all in C# without multiple inheritance, (another consequence of C# having a nominal type system). In this respect, combinatorial types are extremely verbose and awkward to deal with in C#. There's just no good way to handle them without hordes of duplication. C#'s type system is way behind the curve, but had wondered if perhaps something could be done to layer the C# Dynamic Language Runtime with Structural Types (where C# borrows ideas from TypeScript). I sometimes wish Microsoft would just make a new .NET language that was a mix of TypeScript (Structural Type System, Primary Constructors, First Class Functions, Conditional Type Mapping / Computed Types) and all the good language features of C# (Strong Typing, Stack Alloc, Pointers, Reflection and LINQ) and maybe hygenic macros and opt in ownership and move semantics from Rust to help ensure thread safety. A language like that would be incredible.
@Wfmike
@Wfmike 2 жыл бұрын
Yes finally. Now we need Swashbuckle and or NSwag to add support in line with openapi oneof keyword.
@psdmaniac
@psdmaniac 2 жыл бұрын
Base type now knows about derived types :/ I think adding type field to json and deserialize them manually is still a better option.
@nordgaren2358
@nordgaren2358 2 жыл бұрын
Does this mean my big class of generic lists of other big classes of generic lists/arrays will get serialized properly, now?
@nordgaren2358
@nordgaren2358 2 жыл бұрын
@@mw3653 why? Game data is just like that...
@nordgaren2358
@nordgaren2358 2 жыл бұрын
@@mw3653 For example, modding Dark Souls games, just for the material data (like buffer layouts for each material, etc) is a 28k line xml file. This isn't all the data you need just for importing a 3d model, but it's a big chunk of it. A project I am working on wants to use that data, but we are already using json for similar data, so I wanted to just reserialize that class that holds the XML data as json, and I tried to do so with JsonSerialize in .net 6 and it actually gave me an empty json, which kinda sucked. The solution was to use Newtonsoft, but it would have been cool to just use the built in .net json library so as to not have to include another library (which is the reason to not use the class that the XML originally came from) So my question was half funny, but also kinda serious.
@nordgaren2358
@nordgaren2358 2 жыл бұрын
Unfortunately, reading the comments, it seems that my problem will probably persist, though, as it might be a problem with the implementation of the serializer. bummer. Anyways, I still have this video marked for watching, later. Thanks for the continued look into new language features, Nick!
@Ozuqam
@Ozuqam 2 жыл бұрын
Good they finally solved this issue but implementation looks like some one put it together during weekend
@modernkennnern
@modernkennnern 2 жыл бұрын
Why is this not the default behaviour? If someome wanted to serialize an object, I'd imagine they'd want to get all the values inside it.
@RicusNortje
@RicusNortje 2 жыл бұрын
woohoo, been waiting literally years for this
@gdargdar91
@gdargdar91 2 жыл бұрын
That pending update button on the top right corner might trigger OCD symptoms for some.
@gdargdar91
@gdargdar91 2 жыл бұрын
@@mw3653 Nobody asks you.
@nocgod
@nocgod 2 жыл бұрын
I hate polymorphic contracts, exactly because of ser/des But this implementation is pretty inelegant in comparison to what newtonsoft does
@nocgod
@nocgod 2 жыл бұрын
@@AbNomal621 that's exactly it, people don't give enough time to think out the contracts and db models. Ending up with crap solutions to handle this magic, while it would have been much easier to pay the price of planning in the beginning
@waynehamberg9248
@waynehamberg9248 Жыл бұрын
I don't like downsizing a class and having it upsized to something else. If a Point3D is somehow cast to a Point2D, I want that Z property to disappear and want an error generated when you have .Z. The "var" keyword is nice when you don't know the object you are returning but the overuse of "var" in my opinion is lazy development. I have found it lead to more bugs and makes things more difficult to maintain especially if you have to bring on additional developers.
@samsonojetade9127
@samsonojetade9127 2 жыл бұрын
So the base type has to know all about its derived typs now. Don't like it, they got this so backward. What's wrong with serializing based on the the runtime type of the object passed to the serializer? What happens when base type is inside another assembly? Or even an assembly that isn't yours to maintain?
@nickchapsas
@nickchapsas 2 жыл бұрын
The answer is at the end of the video
@petrucervac8726
@petrucervac8726 2 жыл бұрын
Finally! Now I can delete the project I've build to solve this exact problem!
@PinheiroJaime
@PinheiroJaime Жыл бұрын
All of it is not an issue in Newtonsoft for more than a decade
@kazepis
@kazepis 2 жыл бұрын
When pretending that a string message got into the system and we want to deserialize it, I don’t understand why I have to pass the generic type to the deserializer since the string already contains the desired object type. I believe that is the case with Newtonsoft as of many years ago. You can deserialize to base class and have a derived class object.
@abj136
@abj136 2 жыл бұрын
Safety. What happens if somebody sends you an object and hacks the typename? To be safe you need to manage what type of object you accept.
@kpanufnik
@kpanufnik 2 жыл бұрын
How...how this was not a thing in native JSON... I was using newtonsoft and jackson (xml hehe) and would not think that such feature could be missing...
@dantecavallin8229
@dantecavallin8229 2 жыл бұрын
Seriously? When is microsoft gonna give up attributes? This should be the default feature at least.
@anonimzwx
@anonimzwx Жыл бұрын
Should be automatically
@RasmusSchultz
@RasmusSchultz 2 жыл бұрын
I don't know why everything has to be solved with attributes or configuration factories. We have delegates. Just give me a simple way to specify a callback. But that's not The C# Way, I suppose - every simple little problem has to get solved by some impressive, masterful, Grand Architecture or framework. I guess somebody has to sell certifications, education and literature. 🙄
@oscareriksson9414
@oscareriksson9414 2 жыл бұрын
But can't you just serialize the bytes? You are going to have to "know" the types when calling any way.. Maybe I just havent had the use case yet.
@oscareriksson9414
@oscareriksson9414 2 жыл бұрын
@@mw3653 wow. That's arrogant in so many levels, even more arrogant than the usual: 'I don't even care how a computer works'-arrogant. Using bytes to serialize to and from json with the built in tools is something I have done in .net 6, at home and at work. And like I said, the use case for the topic of the video I might just not have come across yet.
@goblelol
@goblelol 2 жыл бұрын
Why JsonDerivedType isn't generic? Since that is a new attribute, and generic attributes are introduced in .NET 7 already, then why not make a new attribute generic?
@antonmartyniuk
@antonmartyniuk 2 жыл бұрын
I want built-in JSON serializer to be able to deal with TimeSpan and other structs which Newtonsoft Json does support
@mealloc
@mealloc 2 жыл бұрын
I'm not sold on the type resolver. Seems very intense and low level. I'd rather have a configuration option on the json serializer in my startup and enable type discriminator across the board without writing extra code, even for the types that doesn't need it.
@johnnyjosep
@johnnyjosep 2 жыл бұрын
69 days since it was DNS??? XD
@DmitryV_HF
@DmitryV_HF 2 жыл бұрын
What wrong with concrete deserialize? Easy solution for problem - use overload method Serialize with concrete type of object. This is easy exctracted. JsonDerivedType attribute? Who guaranty what developer dont forget add this for all derived types? But if Point2D polimorphic too?
@DmitryV_HF
@DmitryV_HF 2 жыл бұрын
​@@mw3653 But i very sad what people like you create alot "sugars" and "features" in .NET updates. Please read much comments with crytics to this JSON attribute. You glad to see much angry peoples? :)
@T___Brown
@T___Brown 2 жыл бұрын
This is exactly why we hated xml. Namespaces and types destroy serialization.
@GreenElectricEarth
@GreenElectricEarth 2 жыл бұрын
I am not a fan of attributes specially on this case, would be preferable to have like a setup of a property of the serializer like "lookupInheritance = true" so the resolver should be already something given by the serializer
@DragonSire
@DragonSire 2 жыл бұрын
If I define something 2D from 3D value....I want only the 2D data. So if I serialize it, I want it to stay as 2d. not serialize the underlying structure. I really don't see the benefit of this.
@antti4855
@antti4855 2 жыл бұрын
A type discriminator as a property value of a JSON object is complete a bad design and the worst thing that Newtonsoft have ever introduced. The same result is complete doable with pure language independent JSON with generic polymorphic type JsonConverter. Type discriminator is totally C# centric on Newtonsoft. Fortunately, net7 do not use class names etc. or other internals to C# but still it brakes JSON's cross platform design or makes deserialization inefficient. “$type” property must be the first property of on object so that deserializer can be efficient but there is no rule on JSON that order of properties can not be changed. For an example when JSON originates from C# goes through JS (browser) and comes bac to C#. A very common use case where JS can move "$type" to anywhere in the object. With type discriminator as a $type property: { “$type”: “fooBar”, “foo”: 1, “bar”: true} MUTCH BETTER ALTERNATIVE. Type discriminator as a property name: { “fooBar”: { “foo”: 1, “bar”: true} } This is not invented by me; It can be found for example from Elasticsearch API and CloudEvent event subscription filter expressions. But I have written a polymorphic json converters for it and it really works seamlessly. Unfortunate it also require that base type “knows” all derived types.
@phizc
@phizc 2 жыл бұрын
There are json based formats that use a property based type discriminator, e.g. DAZ Studio's dson format. The program isn't C#, so I doubt it's because of Newtonsoft. Having the ability to use that without having to write custom JsonConverters to read it is a good thing. I think glTF also uses property value based polymorphism on its extensions. Heck, even json schema uses property value based type discrimination.
@Mortizul
@Mortizul 2 жыл бұрын
As you're based in the UK, you should know that it's Zed not Zee.
@domtremb5650
@domtremb5650 2 жыл бұрын
ok but honestly this version is pointless, there is no long term support for impar number versions. Latest long support would be .NET 6. Let's talk again when .NET 8 comes out
@Kokujou5
@Kokujou5 2 жыл бұрын
this is not a feature that's a bug damnit XD nice fix^^
@JustSammyyy
@JustSammyyy 2 жыл бұрын
4, 20, 69 :)
@deadsh0t625
@deadsh0t625 2 жыл бұрын
Wish they would just let me use json like this in .net json["attributename"] i have use cases where i dont want to insert it into and object and just want 1 key especially for middleware in an .net rest api
@JS-1962
@JS-1962 2 жыл бұрын
You can already do this with a json converter
@yogscastfan9876
@yogscastfan9876 2 жыл бұрын
Nice Point3D, was that on purpose? (420 69)
@yogscastfan9876
@yogscastfan9876 2 жыл бұрын
@@mw3653 Sorry to hear that you've lost your sense of humour? Just because I'm adult doesn't mean I can't point out and laugh at something that looked like an obvious (and popular) joke. Hope you're able to regain some semblance of humour in the future
@KoScosss
@KoScosss 2 жыл бұрын
It is always dns
How reflection changes will make your apps faster in .NET 7
13:15
Nick Chapsas
Рет қаралды 37 М.
The Right Way To Return API Errors in .NET
10:40
Nick Chapsas
Рет қаралды 61 М.
SIZE DOESN’T MATTER @benjaminjiujitsu
00:46
Natan por Aí
Рет қаралды 8 МЛН
Одну кружечку 😂❤️
00:12
Денис Кукояка
Рет қаралды 2,1 МЛН
Why .NET's memory cache is kinda flawed
14:13
Nick Chapsas
Рет қаралды 56 М.
The Logging Everyone Should Be Using in .NET
15:34
Nick Chapsas
Рет қаралды 86 М.
Why I won’t need constructors anymore in C# 11
9:39
Nick Chapsas
Рет қаралды 135 М.
The NEW caching you should be using in .NET 7
18:17
Nick Chapsas
Рет қаралды 78 М.
What is Span in C# and why you should be using it
15:15
Nick Chapsas
Рет қаралды 260 М.
17 Weird Things Swedish People Do
8:32
Jenny Mustard
Рет қаралды 1,4 МЛН
When You Shouldn't Use Await Async in .NET
7:51
Nick Chapsas
Рет қаралды 42 М.
The fastest way to iterate a List in C# is NOT what you think
13:42
Nick Chapsas
Рет қаралды 159 М.
Using JSON IN C#! Serialization & Deserialization made easy!
14:47
tutorialsEU - C#
Рет қаралды 35 М.
SIZE DOESN’T MATTER @benjaminjiujitsu
00:46
Natan por Aí
Рет қаралды 8 МЛН