How to configure aspnet core json serialization - json

I reported this issue https://github.com/dotnet/runtime/issues/48816 and the developer that responded posted code explaining how to manually deserialize the function argument. Asp is supposed to have an automated system for this however. So if my function definition looks like:
[Authorize]
[HttpPost]
public async Task<IActionResult> Post(Session session)
{
...
then I am supposed to be able to just use session as a variable from that point without any special deserialization step. This suggests to me that there must be a way to set JsonSerializerOptions(JsonSerializerDefaults.Web) somewhere in a more global way so that it can consume the post data it is getting. Alternatively there might be a different way to serialize the post data differently on the client so that it does not get converted to camel case.
The main question is: what is the correct way to serialize and deserialize data objects for asp.net-core?

To Reproduce
Thanks for Roar S's comment, use [FromBody], it works.

Related

JsonSerializer.Serialize vs JsonResult - A possible object cycle .NET Core 3.1

I have read a few posts here and on GitHub regarding .NET Core 3.1's change in tightening of the allowance of serializing data. My actual exception is:
System.Text.Json.JsonException: 'A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 0.'
When I search the web, there are very few results, but from what I gather, it's telling me that it doesn't like the related data that is being serialized. Well, in the past, this hasn't been a problem. After reading this post, it says to install the Newtonsoft Json serializer package. I did that, and added the verbiage in Startup, but got the same result. So, I read another post here where the member who answered the question returned a JsonResult in the method. I tried this as a test and it worked just fine. Problem is, I need to return the data (serialized) to a view.
My question is, why can the standard System.Text.Json.JsonSerializer not serialize my data, yet a JsonResult can? Either way, I just need to serialize my data and cannot get past this error and any help would be greatly appreciated. If I have to return the data via an API and continue to use the JsonResult, I'm fine with that, but am concerned as to why it works.
As #poke suggested, using Json.Serialize works. I was using System.Text.Json.JsonSerializer.Serialize(Model) and for some strange reason, this throws the same exception even though the Ignore option is set in Startup. More research is required, but at least this gives me something to look into.

Grails - Do you still need parseRequest for JSON binding to work in controller?

Ok, this is my Nth question regarding this topic, and I'm getting really frustrated with Grails. Please have a quick look on one of my earlier questions for more details.
Among other things, my problem is that sending JSON formatted data to the controller when testing doesn't seem to work. The controller doesn't get null object, but the argument passed is practically empty--the JSON properties don't get set.
Aside from the controller code from the link above, I also tried,
def save() {
def model = new MyModel(request.JSON)
model.save()
}
but it still fails to set properties.
From my Web searches, I read that in older versions, parseRequest must be set to true in UrlMapping.groovy so that request data formatted in XML, JSON, etc. would automatically be parsed and passed as controller method argument. I'm working on Grails 2.3.9, and I'm not sure if it's still necessary to do that.
The time I thought I'd save if I use Grails on this project is being spent on looking for an answer to this seemingly simple task of testing a RESTful Web service.
No since 2.3.0 the parseRequest option doesn't do anything. The request is parsed lazily only when request.XML or request.JSON is accessed or when binding to a command object.

AutoBean Compile Error: "Parameterization is not simple..."

I'm trying to use AutoBean on the server and client to send and receive json data through AppEngines channel API. I don't want to store this data in the datastore. I already have a Proxy for this object that I use for the RequestFactoryServlet (which underneath just uses AutoBean anyways), so this should be doable. Instead of writing up a new Proxy for the object that exactly duplicates the Proxy for the RequestFactoryServlet, I'd like to just use the proxy that I use for the RequestFactoryServlet. The only problem is that I get an error while compiling that comes from my AutoBeanFactory.
Invoking generator
com.google.web.bindery.autobean.gwt.rebind.AutoBeanFactoryGenerator
[ERROR] The com.wmba.wmbaapp.shared.ObjectProxy parameterization is not simple, but the obj method does not provide a
delegate
So I'm not really sure what to do here. It seems like before I added the client side in, it's able to serialize the object into JSON just fine, but for some reason it doesn't like this. It sounds like it wants a delegate from me, but I can't find anything on this from the internet.
Anyone have any ideas?
Note: I also tried the same thing with EntityProxy (which is the base of the RequestFactory framework from what I read on the AutoBean page, but I get the same error).
The issue is that EntityProxy defines the stableId method which is not a getter (name doesn't start with get). That makes it a not simple bean, for which AutoBeans require a real bean instance to be wrapped in the created AutoBean (the delegate, passed as an argument of the type of the AutoBean –ObjectProxy in your case– to your obj method of the AutoBeanFactory).
In other words, AutoBeans expects your obj method to be of the form:
AutoBean<ObjectProxy> obj(ObjectProxy toWrap);
The simplest solution is to not try to reuse the entity proxy with AutoBeans.
You might be able to make it work though by annotating your AutoBeanFactory with:
#Category(EntityProxyCategory.class)
You might have to add #NoWrap(EntityProxyId.class) too, see http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestFactory.java
It turned out for me that I had a property setter that had an empty parameter list in my Ojbect interface. It didn't have anything to do with the factory, except for the interface the factory was trying to create a proxy for:
interface Factory {
AutoBeans<MyObject> createObject();
}
interface MyObject {
String getProperty();
void setProperty();
}
A bone-headed mistake but held me up with this precise compiler error. Adding the Category annotation as mentioned in the previous answer identified the faulty property setter.

OData Client for Obj-C and Parsing Out Scalar Return Values

I can't seem to find a way for the Objective-C OData client to return the value of a web service function that just returns something simple, like an integer.
For example,
[WebInvoke]
public Int32 xyx()
{
return ( 3 );
}
The proxy-generated client code generates a function that when called, returns an XML formatted NSString with the value 3 in it. Am I going to have to parse out this value and then map it to an int? I thought it would be easier. Even harder for bools. Net bools are true/false, when Obj-C are YES/NO. You would have to write code that parses the XML, finds the true/false, ifs it to YES/NO, arrgggg.
I thought the OData client would map these, am I wrong?
Just wondering if anyone has an answer on this on yet. I'm in the same boat. In my situation, I'm using the .Net client side proxy (Add Service Reference), it's very similar in this situation. I end up having to call my service method using:
context.Execute<int32>(new Uri(MyUri, UriKind.Relative)).ToList();
This gives me back an ICollection with 1 item. It works, but it's certainly not very clean! Hoping someone has a better solution.
I'm also interested in the correct way to access the "post data" from inside the service method. I haven't tried it yet, but based on other things I've done, I'm thinking something like this:
HttpRequest ThisRequest = (HttpRequest)System.Web.HttpContext.Current.Request;
string PostData = ThisRequest.Form["PostData"];
OData documentation not very clear about this stuff. Thanks!!

JSON Serialization/Deserialization mismatch (ASP.Net)

When I call a PageMethod in my page, the serialized object looks like:
{"d":{"__type":"MyAsembly.MyNamespace.Person","Name":"ulu","Age":40}}
This is ok for Javascript, but my .Net deserializer won't understand it:
var result= new JavaScriptSerializer(new SimpleTypeResolver()).Deserialize<Person>(source);
throws System.InvalidOperationException: Operation is not valid due to the current state of the object.
Now, the actual problem is that the Activator can't create the result object: it doesn't understand "MyAsembly.MyNamespace.Person" and needs "MyAsembly.MyNamespace.Person, MyAssembly".
The question is, what do I need to change so that serialization becomes compatible with deserialization?
Thanks a lot
ulu
Seems like you already know the answer: modify the value of the __type property before serializing the object on the JavaScript side. Alternatively, you could do a replace on the serialized data before pushing it through the deserializer.
Question though: where is the data being serialized? If you're doing it in .NET and then sending it to the client, it shouldn't need any modification when it gets back to the server unless something tampered with the __type property.
I am guessing that
{"d":{"__type":"MyAsembly.MyNamespace.Person","Name":"ulu","Age":40}}
should be
{"d":{"__type":"MyAssembly.MyNamespace.Person","Name":"ulu","Age":40}}