Closed dougbu closed 7 years ago
This is the discussion issue for aspnet/Announcements#194.
See also the original issue we fixed in 1.0.0: #4283
What would this mean if we use a JavaScript framework like Knockout.js to map JSON inputs to view models in our client side code? And is there a way to change this back to Json.NET's default?
@clarkis117 , yes there is :
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
This is already available so you can define your settings right now.
I like this change, but -
I think it needs to be configurable to allow developers to choose the serialization naming convention to be used.
@brent-russell this is configurable ;)
@brent-russel, as @sandorfr showed, this is quite configurable. What exactly is missing from your perspective?
@sandorft @dougbu Oh, that's great!
Just communication and documentation then I guess. The announcement didn't hint at configuration at all. Most other announcements that introduce breaking changes provide instructions on how to implement or obtain pre-existing behavior.
Thanks!
hmmm ... I use typescript and tools like create intellisense file from web essentials to map automatically a csharp in the backend to a interface definition in the client. If you use whatever tool to make automatically server-client entities in typescript, this way by default are not going to work
@lucamorelli Yes, this is one of the problems that I foresee running into with using Typescript tools like Typewriter. Potentially I'd have to change to change parts of my Typewriter model generation code to camel case, which would break significant portions of the manually written client side code.
I really don't like this change, it will effect thousand of developers. I suggestion some feature like this:
[camelCase] // provide by json.net
public class Person
{
public int Id { get; set; }
public string FullName { get; set; }
}
this will give us more controllable of our code.
Json is not javascript, and it not only use by javascipt. It's a data formate now use in many languages, Please rethink about it.
@John0King As shown above, this is already controllable. You can always revert to the old behavior if you prefer that, or go the explicit route and annotate the class with serialization attributes.
This change of the default behavior does make a lot of sense. Most other languages nowadays consistenly prefer camel casing for all members; it’s just C# that’s odd here with its pascal case properties. So languages consuming JSON are more likely to feel familar with camel cased JSON properties.
I welcome this change, thanks!
@John0King from my experience the Attribute thing is to be kept minimal, it's easily forgotten. The way to go is AddJsonOptions.
For the "I like this better", I personally don't care, but I think using AddJsonOptions should be a recommend practice not matter you want the default or another behavior.
Looks good to me. Saves having to set CamelCasePropertyNamesContractResolver
in Web API.
Here is an example of doing this from the old Web API on the full .NET Framework, but I'm planning on porting this to Core after it RTMs.
Buggah... I suck at life, and replied to the wrong thread on #4283. Boh.
Anyways, I again find myself in the minority here. I also believe I speak for a lot of the native/Xamarin/enterprise developers that wish to keep consistency between code (C#) and the data that represents that code.
I would feel better if this change default was hinged to a particular "style" setting/attribute somehow, meaning that in native/enterprise applications, PascalCase is the default, and in web applications camelCase is the default.
It basically is, though. It's literally one line of code to switch it around. On Jun 10, 2016 8:49 AM, "Mike-EEE" notifications@github.com wrote:
Buggah... I suck at life, and replied to the wrong thread on #4283 https://github.com/aspnet/Mvc/issues/4283. Boh.
Anyways, I again find myself in the minority here. I also believe I speak for a lot of the native/Xamarin/enterprise developers that wish to keep consistency between code (C#) and the data that represents that code.
I would feel better if this change default was hinged to a particular "style" setting/attribute somehow, meaning that in native/enterprise applications, PascalCase is the default, and in web applications camelCase is the default.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/aspnet/Mvc/issues/4842#issuecomment-225186624, or mute the thread https://github.com/notifications/unsubscribe/AAavtJZY3M0r8OFfYHyUPPNBLU0OeC8Sks5qKWtVgaJpZM4IyfXK .
Yes indeed @ciel I understand that, but what this decision says is that by default the camelCase is the better/preferred format, whereas PascalCase is not. So what does this say about C#, upon which (ironically) the serializer is written in?
This introduces confusion and context-switching into the process. I hope that you can understand my viewpoint and concern here.
I understand your standpoint and concern, and to an extent I share it. But I also see the ease of switching makes it a non-issue overall. It could be even further remedied by just including the code to control the format as part of the default templates. On Jun 10, 2016 8:54 AM, "Mike-EEE" notifications@github.com wrote:
Yes indeed @ciel https://github.com/ciel I understand that, but what this decision says is that by default the camelCase is the better/preferred format, whereas PascalCase is not. So what does this say about C#, upon which (ironically) the serializer is written in?
This introduces confusion and context-switching into the process. I hope that you can understand my viewpoint and concern here.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aspnet/Mvc/issues/4842#issuecomment-225187992, or mute the thread https://github.com/notifications/unsubscribe/AAavtK-sPphSFo0gUngfnPV2Foy7oE8fks5qKWyegaJpZM4IyfXK .
I don't think it is a good or wise decision. But, I also don't have my fingers in dozens of projects. I have faith that the people who do made this change for a good reason. That's all. I'm not discounting what you're saying. On Jun 10, 2016 8:56 AM, "Stacey Lynn" stacey.cielia.lynn@gmail.com wrote:
I understand your standpoint and concern, and to an extent I share it. But I also see the ease of switching makes it a non-issue overall. It could be even further remedied by just including the code to control the format as part of the default templates. On Jun 10, 2016 8:54 AM, "Mike-EEE" notifications@github.com wrote:
Yes indeed @ciel https://github.com/ciel I understand that, but what this decision says is that by default the camelCase is the better/preferred format, whereas PascalCase is not. So what does this say about C#, upon which (ironically) the serializer is written in?
This introduces confusion and context-switching into the process. I hope that you can understand my viewpoint and concern here.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aspnet/Mvc/issues/4842#issuecomment-225187992, or mute the thread https://github.com/notifications/unsubscribe/AAavtK-sPphSFo0gUngfnPV2Foy7oE8fks5qKWyegaJpZM4IyfXK .
Also, the general naming convention for data names in json on the web now is snake_case
, and not camelCase
. Seems a little weird to set the default to be something that is in the middle of the c#'s naming convention, and the most common json naming convention.
That's all. I'm not discounting what you're saying.
Cool thank you for that @ciel. :)
And yes, I can see why it's a non-issue. I mean, people say the same thing about xml vs. json. :wink: To me it all comes down to consistency. That is why I wonder if Xamarin/enterprise side of the aisle was consulted with this as this makes their (or our :smile: ) side inconsistent by default now.
Seems a little weird to set the default to be something that is in the middle of the c#'s naming convention, and the most common json naming convention
I hear you @0xdeafcafe (awesome name btw LOL!), but what we seems to get lost here is that there is a history and legacy -- not to mention an entire enterprise -- that you also have to consider here with MSFT. This should be the learning lesson of project.json (as I tried to point this out back in the day, as well).
By itself, in the ".NET Core" or "web" way of things, this makes sense. But when you shine this through the prism of MSFT's history and other commitments, you run into problems.
I think this just goes to further the need to recognize the schism/chasm that is within MSFT at present: enterprise (legacy/native) and web (new and shiny). I don't want to infringe upon your standards (or creativity/innovation as what is going on here is great!), but let's not infringe upon others while we're at it.
@Mike-EEE I guess, I just don't get why they didn't leave it as is, and not annoy anyone (as we're all used to writing custom converts/setting attributes/custom serialization settings). Instead of changing it to something in the middle that is just going to irritate both sides, and only really please those few in the middle. On top of that, most "enterprise" companies either don't use JSON, or use PascalCase if they do.
You know @0xdeafcafe ... I actually just re-read what you wrote and have to say that I totally misunderstood you! Yes, you are correct. This does seem to be a "middle" ground play, for lack of a better word.
And the web evolves so fast, who knows what format will be the flavor of the month, next. :wink:
Most "enterprise" companies either don't use JSON, or use PascalCase if they do.
Very true! We should say they don't use JSON... YET. As .NET Core moves towards making this a requirement. :stuck_out_tongue: But I am very much a proponent of enabling developers and organizations to "bring your own serializer" and allow them to use the data formats (and corresponding tools) that make them the most productive. A notion that hasn't quite caught on here yet.
My position is that all decisions should "protect the investment" and brand of MSFT. That means innovate and appeal to other methods/technologies (as VS Code is doing a great job of doing), but do so in light of the history and tech that got us here.
This change is probably correct. However the execution of this is absolutely insane. Right in the middle of RC2 and RTM is when you decide you're going to break every single application that uses C# Pascal cased property names because that's what the data serialized as.
Is this the decision making process going there?
Although the new behavior is what I'd like by default and this change would be reasonable in the beta fase, I don't think this kind of change should be done now (RC to RTM).
Indeed, it's very easy to roll back to the previous behavior, but you are requiring every application do to it. Plus, it's not hard to change to camelCase now.
I think the aspnet team should consider the impact of requiring every app out there to do it and other breaking changes like that.
Upgrading our app from RC1 to RC2 was a PITA. Among other things (like tooling, defaults, namespaces, etc.), we couldn't made our migrations work without deleting them all and creating again. We read the docs (which were very helpful), but it's a lot of work that don't necessarily add real value to our app.
I really hope that upgrading to new versions will be more easy to do than RC1 to RC2. We're not in beta anymore, we should be more restrictive in breaking changes. It's not even close to semver.
Updated description to show the configuration one-liner.
Hi all, this is indeed a significant change at a late stage in the product. No doubt about it. We've been working with @JamesNK (author of Json.NET) on this change and this is the quickest we could get it done. And it's pretty much a "now or never" kind of change. We recognize that this type of change can be painful for early adopters such as those here on this thread.
We feel that it is the right overall thing to do for the product, and though there is some short-term pain, there are long-term benefits that outweigh it. The general consensus on both this issue and on the original issue requesting the change (https://github.com/aspnet/Mvc/issues/4283) is quite clearly in favor of this change. We of course announce these types of breaking changes on the Announcements repo to mitigate the pain. And thanks to a simple, straight-forward design in Json.NET and ASP.NET Core MVC, it's quite easy to change the behavior back.
Thanks, Eilon
Thank you @Eilon for taking the time to explain this. My concern of course still stands, and it doesn't seem like you spoke to it, unfortunately. Timing aside, can you speak to why you are choosing to inject a fundamental inconsistency in casing defaults between code and data for .NET solutions? I understand that there was a general (overwhelming, even!) consensus in favor of this direction, but that was the case for project.json, too. :wink:
(too soon? haha)
can you speak to why you are choosing to inject a fundamental inconsistency in casing defaults between code and data for .NET solutions?
No good deed goes unpunished.
can you speak to why you are choosing to inject a fundamental inconsistency in casing defaults between code and data for .NET solutions?
No good deed goes unpunished.
My thoughts exactly
Hahaha... geeze, tough crowd. Although I shouldn't be surprised. I concede that I am in the minority here (at present). Again, if all of your great work here was done in a vacuum this all makes sense and no problem. But unfortunately since this is under the MSFT brand we do have to lend consideration to legacy/history and overall ecosystem. These are exactly the same concerns I expressed with project.json over a year ago and no one paid notice to (or flat-out disregarded) my input then. And wouldn't you know it, they eventually bore out into the costly about-face we're all (or really, you all :stuck_out_tongue: ) are having to endure at present. Maybe I will be patient and wait another year before someone with some clout can reverse the course of this questionable decision, too. :stuck_out_tongue:
@Mike-EEE My problem is that from my prospective this happened out of the blue. I understand that there were a significant number of core collaborators involved in the decision making process for this; however, it is a significant breaking change. For context, when I first saw the announcement issue it didn't even have a breaking change label nor the options code snippet to change it back. I was also unware that camel case is the "convention" for JSON data naming. I even went as far to talk to some friends who are now enterprise devs working with other web stacks, and even they were unware that camel case was the "convention". The feedback I got was it was whatever naming convention they were using for objects in their code was the same convention they were using for JSON. In addition, this has to be in the documentation for MVC. I remember starting out with MVC over a year and a half ago and expecting it to respect the naming conventions that I used in my code. Therefore, I strongly feel that this should be added to the documentation; that by default MVC won't respect the naming conventions you used for your objects. This could be a potential point of frustration when onboarding new developers, as many people have said, paraphrasing, the defaults are important for an ecosystem... and if they suck it's a major turn off. For example, all the people who advocated for this change have enough experience and knowledge to know what value it may add to the ecosystem/product, but beginners will definitely not know that information. I myself still don't know the value this change adds other than supposedly everyone else is doing it.
Thanks for explaining @clarkis117. That is some really great feedback and insight.
From my perspective, this issue is complicated by three factors:
While your concerns are primarily short term (and it's great to see you appreciate the long-term as well), I think this goes to show that we as a community need to start thinking in terms of profiles when we design features -- at least in the short to medium term. This approach is not unlike the coding profiles you are introduced with in Visual Studio when you first install it. This, however, affects the actual code and how it is initially configured before you actually get to coding it.
So in this case if you are a "native" developer, you get PascalCase
by default, and a "web" developer gets camelCase
by default. And a "hack" developer gets snake_case
. I kid I kid... sorta. :smile:
Ultimately, however, the (long-term) root of the problem is that we are touching JavaScript (or non-MSFT/.NET languages) at all. In fact, ASP.NET is the only primary product/group in MSFT that introduces and requires JavaScript for .NET applications, which is extremely disruptive. What we should really be focused on is bridging the divide between "native" and "web" developers so that we are all working from the same conceptual client development model and as a result from top-to-bottom, through-and-through, we are all using the same constructs and idioms, and therefore, conventions.
Call me an idealist, though. :smile:
Again, if all of your great work here was done in a vacuum this all makes sense and no problem.
The irony here being that PascalCase is the result of decisions in a vacuum. Looking at literally the rest of the world, and seeing that you're doing JSON in what amounts to a proprietary way, should give pause and invite change. Not more myopia.
Not more myopia.
Haha! Well again I am seeing your side, but it doesn't sound like you are seeing mine. Well really not mine, but over 15 years of yes, living in a vacuum. You're not really speaking to me, but hundreds of thousands of .NET developers and organizations who have spent their time loving their vacuum-sealed paradigm.
This is this history that continues to seem lost with some of the decisions made here. I say some because what has been accomplished here is really great. I am definitely a fan and big supporter. .NET needed something like this in a big way. We simply need to find a better way to make the decisions that "play nice with others" (e.g. EVERYONE ELSE BUT .NET LOL) gel well with the rest of the ecosystem that this product is a part of.
I am definitely open to ideas and dialogue here, I hope that is clear!
JSON in what amounts to a proprietary way.
Is that before or after we modified the serializer to accept inline comments? :smile:
Well again I am seeing your side, but it doesn't sound like you are seeing mine. Well really not mine, but over 15 years of yes, living in a vacuum. You're not really speaking to me, but hundreds of thousands of .NET developers and organizations who have spent their time loving their vacuum-sealed paradigm.
I do see that side - .NET Core had brought it into sharp focus.
If we'd done things the way they'd always been done, we'd still be squatting in the woods. There will always be those squatters for whom change is simply what jingles in their pockets. The world has gotten bigger since 2001; like it or not, the ostrich defense is paying less dividends now.
Optimizing for those static opinions, those immovable rocks in the river of innovation, is a recipe for staleness and irrelevance. Weep for those losing their capital letters; lament the death of their representational privilege; then step aside and let evolution happen.
Dang @bwatts that has got to be the most metaphoric reply/answer/contribution I have ever seen in a discussion. Ever. Kudos to you, sir. :+1: :smile:
Also, there's an inherent naming disparity in the options setting now. If the default is now camel case and you're telling devs to set it to something with default in its name inorder to change it back; some are going to look at that and say, "bro, can you even name" :p
I must say I agree with the points raised by @Mike-EEE and @clarkis117 .
@obraunsys
camelCase is not a JSON naming convention. it's a Javascript naming convention.
So nothing to do with JavaScript Object Notation? Ok... :wink:
@MaximRouiller You are of course right about the origin of the name, and I know this statement can be controversial (which is why I started with "in my opinion"), however, I would argue that JSON has become a language-agnostic serialization format.
Please note that I agree that camelCase is the proper format when using JSON with JavaScript, but some of us also work with C# code on both sides of the pipe, and I have never seen anybody use camelCase in this situation (not saying it doesn't happen, I just haven't worked on any project where this was required or desired).
@MaximRouiller
So nothing to do with JavaScript Object Notation? Ok... :wink:
It's based off of JavaScript, but there is no official naming convention definied in the JSON spec. The fact of the matter is, It's entirely up to your use case/preference.
However, as I previously said, I think it was a bad idea to make this change. Keep it PascalCase by default, as that's the languages naming convention. Let people apply custom rules as and when they see fit. This is just going to cause a literal fuck-ton of questions on SO, as newer people move to this framework and start wondering why their API is outputting data that doesn't reflect the format of their data/view models.
@0xdeafcafe
As with every breaking changes, if we don't change it now... when will we? Probably never.
The good news is that new development will adopt the camelCase and those in a different casing scenario are literally just one line away from reverting back to the old behavior.
Damned if you do, damned if you don't. It's been the same reaction from everyone for everything that moves a previous default.
@MaximRouiller I agree that now is the time to introduce breaking changes and start with a clean slate, but this is probably the wrong default for .NET serialization.
As with every breaking changes, if we don't change it now... when will we? Probably never.
While I respect that viewpoint (as it is rather accurate), I would like to point out @obraunsys's excellent observation about WebAssembly (which is really the "missing link" from a ubiquitous .NET client development model). Once that kicks in this issue will indeed be a thorn in our collective sides.
There are, however (trying to be objective here -- and also maybe beat an objector to the punch :grin: ) a couple considerations:
@Mike-EEE
So the positions against are the following:
Problem: We already have apps that use PascalCase!!! Solution: One liner to change the default. People go back to life a happy and uneventful life.
Problem: It should be up to us to decide! Solution: You already are. The defaults are just changed and can be changed.
Problem: WebAssembly might be a thing within the next 5 years. Let's no hurry too much. Solution: Unless it's shipping now (or the next 6 months) and an issue in the very near future, let's not worry about this. Otherwise, we end up in a paralysis in case something important might be hindered by today's choices.
That's it. It's a non-argument. Defaults can be changed. Even in the case of WebAssembly, it's a non-issue since the default can be changed in literally one line.
Hahah I agree @MaximRouiller, it's all so very complicated! :smile:
The biggest problem to me personally (that isn't in your list) is the inconsistency with established (and continuing) standards from over 15 years of .NET development. This change as designed at present simply introduces inconsistency (and resulting confusion) in light of .NET's storied history.
WebAssembly simply adds another dynamic to this, much like introducing a breaking change before RTM. :stuck_out_tongue:
Just think... if MSFT had done the right thing and simply gone the JSIL route rather than trying to introduce a completely incompatible language and client application development paradigm into .NET solutions, we wouldn't even be having this discussion in the first place. #cryingoverspiltmilk :grin:
@Mike-EEE This has nothing to do with "established .NET standards". The rest of .NET can and will go on with its existing defaults. This is MVC, a single .NET-based web framework, changing its defaults. Other frameworks, like Nancy, has changed these defaults a long time ago.
There is, of course, no standard when it comes to JSON property names, but AFAIK, the rest of the (web) world uses either pascalCased
(most common), kebab-cased
or snake_cased
naming for JSON representations. After all, it isn't called JavaScript Object Notation for nothing. Google even has a JSON "style guide" suggesting you use camelCase.
Because we've wanted to follow the rest of the world, we've always been forced to change MVC's defaults, until now. As I mentioned in the other issue that suggested this change; this has always been the first thing I've had to change when setting up every single MVC/WebAPI application I've ever made. It's (about) time MVC changed to a more sensible default. Who do you want to optimize for? The 20% or the 80%?
If you want to use XAML, or keep the "old" defaults, it's completely up to you. These are just defaults, you're free to change them. Let's not keep bad defaults around because of a minority.
The rest of .NET can and will go on with its existing defaults
You mean with its existing inconsistent, conflicting, and contradictory defaults.
Google even has a JSON "style guide" suggesting you use camelCase.
Does that same style guide suggest comments in its JSON? :angel:
I mentioned in the other issue that suggested this change; this has always been the first thing I've had to change when setting up every single MVC/WebAPI application I've ever made.
And who's fault is that? :smile: Again is this a MSFT product or a product that is developed outside of MSFT? If it's a MSFT product, it should (ideally) adhere to MSFT standards, of which we know that PascalCase is indeed the default casing for all of .NET's languages. Getting back to the unfortunate developer divide we find ourselves in, if we never had to deal with JavaScript, we never would have to deal with this discussion. This is the only product/project/group that requires JavaScript for proper operation. Now it seems all other MSFT groups/products/projects will suffer from an inconsistent default because of it.
It's (about) time MVC changed to a more sensible default.
It's about time MVC ditched the JavaScript. :stuck_out_tongue:
If you want to use XAML, or keep the "old" defaults, it's completely up to you. These are just defaults, you're free to change them.
The same case can be made for the reverse. :) And they aren't just old defaults, they are established and ingrained. This whole issue/approach/attitude sort of makes me want to say "MAKE MSFT GREAT AGAIN" or "MSFT First" as what is taking place here certainly isn't that. :stuck_out_tongue:
Again, this is a MSFT product based in MSFT history and this must be accounted for when considering these sorts of changes. Has project.json taught us nothing? :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue:
In previous milestones, MVC's JSON serialization used Json.NET's default naming convention. This maintained C# property names in the JSON.
In 1.0.0, MVC uses camel case names by default. This matches most JSON naming conventions.
Potential compatibility breaks
Applications which depend on the exact bytes sent over the wire or that include code such as
may need to be adjusted.
To restore previous naming strategy
If you have case-sensitive clients that cannot be easily updated, change your
Startup
fromto
Example
Before
Would serialize to
After
The same model will serialize to
Note the initial lowercase letters.