-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[Discussion] MVC now serializes JSON with camel case names by default #4842
Comments
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. |
@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, |
@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 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
|
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 don't think it is a good or wise decision. But, I also don't have my
|
Also, the general naming convention for data names in json on the web now is |
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. 😉 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 😄 ) side inconsistent by default now. |
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. 😉
Very true! We should say they don't use JSON... YET. As .NET Core moves towards making this a requirement. 😛 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? |
I just encountered an interesting scenario with camel-cased names and wanted to ensure we account for it. The default serialization for a
However, if we serialize an upper-cased key We worked around this by creating a
We wanted to simply tell JSON.NET to use |
@bwatts did you open an issue on https://github.com/JamesNK/Newtonsoft.Json? If it's a bug, @JamesNK should be informed. I've looked quickly at the repository and it doesn't look like this issue has been logged before. |
@MaximRouiller I wasn't sure if it is a bug or just an unfortunate feature collision. I'll open an issue over there anyhow to be sure. |
@bwatts @MaximRouiller Camel-case dictionary keys is something that needs to be opted into. If you want to tweak the settings, you can set the services.AddMvc().AddJsonOptions(x =>
{
x.SerializerSettings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = false // this is the default.
}
};
}); As you can see, the MVC defaults are the same as Newtonsoft.Json defaults, which should keep dictionary keys the same. |
Thanks @khellang for the clarification! Didn't know about that specific feature. |
@khellang I found NamingStrategy and ProcessDictionaryKeys while investigating, but this fiddle seems to contradict that default. Thoughts? |
@bwatts Uuh. This fiddle shows that it works 😄 |
I'm using this: http://stackoverflow.com/a/24226442/214073. |
@khellang isn't the point of the MVC default-to-camel-casing to make the |
@bwatts No, because as you've discovered, MVC uses the |
@khellang got it - so it seems I shouldn't be using |
This change is really ridicilious. You need to tell mvc to use default serializer to get the default behavior. This is why microsoft is not liked by many. |
@gr3ysky The problem is "the default for what scenario"? It's all a matter of choices. |
The default is the f.cking default. No need to argue on what is default. It shouldnt change the property names. It is just like start menu issue. I have been developing mvc over six years. It was pascal case till now. And just check the code to get old behaviour. And thats silly to say use the default behavior. Right? |
@gr3ysky Did you read #4842 (comment)? |
Further, you're arguing defaults should never change? This is a major version. What's "right" is a judgement call, not an objective fact. |
The new "Default" for serialization in JSON is now lower case. The model binders for ASP.NET Core will interpret lower-case/upper-case without any issues so this is a non-issue for "current behavior" of the API. So let's take a look at what scenarios you would need to change it.
Here are the solutions:
It's a major rewrite of a framework. You can't expect to copy/paste your code and expect everything to be feature equal. I have more complaints about EF Core right now than the default serialization for JSON which can be reverted in one line of code. As mentioned before, there's only Microsoft that defaults the JSON serialization to Pascal Case. Now we are "back to normal" in the web sphere. If you want to go back to the good old days when you are porting an application, here's how:
|
We are closing this issue because no further action is planned for this issue. If you still have any issues or questions, please log a new issue with any additional details that you have. |
If I could, I wanted to thank everyone for the respectful and thoughtful discussion on this memorable thread, especially when it turns out I had no idea what I was talking about. 😛 (or to be more accurate, did not completely understand the issue at hand and misunderstood its actual implications). I'd also like to send a special shout out to @bwatts for his "no good deed" comment above as well. I didn't really understand it at the time, but there have been been numerous instances since then in other discussions throughout GitHub where I have been brought to bear the full appreciation of that statement, LOL. If it helps at all, rest assured that I have gotten my due on the flip side. 😆 Anyways, thought I would share. And no, I can't help it. 👍 |
It is interesting that if an object is not strong type like object or dynamic, it will not be converted to camelcase. But it can be fixed by
|
Or by using the .AddJsonFormatters(json =>
{
json.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = true
}
};
}); |
Wow! I found this ugly bug! And it is a really bug!
public class TestModel
{
public int Id { get; set;}
public Dictionary<string, string> Settings { get; set; }
} Simple method to use model <script>
var model = @Html.Raw(Json.Serialize(Model)); // case is broken there when ASP.NET Core used
// some methods to bind inputs with model
$('form').submit(function (e) {
e.preventDefault();
$.ajax({
url: this.action,
data: JSON.stringify(model),
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("Content-type", "application/json");
},
async: false
});
});
</script> Simple method which must save returned model
It is improbable to change names at serialization! Why? |
@QuAzI If you want to restore the older behavior of keeping the casing, see the comments above. They show you many ways to resolve that issue. |
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.
The text was updated successfully, but these errors were encountered: