posting JSON to MVC controller - String parameter is null - c#

I am intentionally trying NOT to use a binding in the controller parameter, so I have a controller that looks like:
[HttpPost]
public ActionResult UntypedForm(String serializedformdata)
{
//// ...
}
When I post serialized JSON form elements to the controller with the below code:
var formelements = $('#form').serializeArray();
$.post(url, formelements, function (data) {
}, "json").error(function () {
alert("Error posting to " + url);
});
I get a NULL value for String serializedformdata on my controller. However, when I replace String serializedformdata with a strongly-typed object, binding works properly as expected.
The whole point of my controller is generic JSON posts, where I will create a BSON document to place into a Mongo database. SO....I intentionally DO NOT want model binding and I want the serialized string as pamameter. Why is my serializedformdata string null when I post?
Note - I also tried to bind to Dictionary with
public ActionResult UntypedForm(Dictionary<string,string> serializedformdata)
{
//// ...
}
but serializedformdata is still null.

The function serializeArray creates a Javascript object with the form's key/value pairs. You don't want that, you want a single key/value with serializedformdata = (JSON string). Ie, like this;
var formelements = { serializedformdata: JSON.stringify($('#form').serializeArray()) };
This passes the raw JSON string to the controller's parameter. You can use the JavaScriptSerializer to get the object on the server:
var obj = (List<Dictionary<string,string>>)new JavaScriptSerializer().Deserialize(serializedformdata, typeof(List<Dictionary<string,string>>));
Dictionary<string,string> dict = obj.First();
string someval = dict["somekey"];

Related

Unity accessing JSON Object

I am using Unity and Gamesparks. I am getting a Gamesparks object return but I am unable to access the data inside using C#.
private void OnScriptMessage(ScriptMessage message)
{
switch (message.ExtCode)
{
case "EndTurnMessage":
{
var data = message.Data;
string playerID = data.GetString("playerID");
print(message.JSONString);
break;
}
print(message.JSONString); displays
{"#class":".ScriptMessage","data":{"player":{"status":"win","choice":"scissors","newScore":1},"opponent":{"status":"lost","choice":"paper","newScore":0}},"extCode":"roundWonMessage","messageId":"5c74b1a8bcb1b604f0275ed5","notification":true,"playerId":"5c5b5823642c55481643846d","summary":"ScriptMessage"}
UnityEngine.MonoBehaviour:print(Object)
I wish to get newScore etc but I am confused with C# JSON
Your data is as follows:
"#class":".ScriptMessage","data":{"player":{"status":"win","choice":"scissors","newScore":1},"opponent":{"status":"lost","choice":"paper","newScore":0}},"extCode":"roundWonMessage","messageId":"5c74b1a8bcb1b604f0275ed5","notification":true,"playerId":"5c5b5823642c55481643846d","summary":"ScriptMessage"}
You need to deserialize it using ->
JsonUtility.FromJsonOverwrite(json, #class);
But to just get that one value you'd probably just need a good way of parsing your JSON. Under the base JSON root node is data, playerId, extCode, messageId, notification, summary. You need to treat the field "data" as a JSONObject and then both "player" and "opponent" as JSON Objects. Parse the value within it for
newScore.
Your data looks like this:
So your code would look something like this (this is to be used as a general guideline):
var data = message.Data;
string playerID = data.GetString("playerID");
var _data = data.GetObject("data"); //whatever to get data as JSON or Object
var _player = _data.GetObject("player"); //whatever to get data as JSON or Object
var _opponent= _data.GetObject("opponent"); //whatever to get data as JSON or Object
int _mscorePlayer = _player.GetInteger("newScore"); //Whatever the getter is for JSON Number it could be GetNumber or something comparable.
int _mscoreOpponent= _opponent.GetInteger("newScore"); //Whatever the getter is for JSON Number it could be GetNumber or something comparable.
print(message.JSONString);
print("your playerId:\t" + playerId);
print("your newScore:\t" + _mscorePlayer);
print("opponent newScore:\t" + _mscoreOpponent);
break;

How to fix JSON output for consumption by jquery Ajax

I'm trying to get JSON out of a webforms.cs page to .aspx page. It's relatively easy to do with JSONResult in MVC but it seems to be a pain with webforms.
So I have [WebMethod] function in my cs file like below.
This method is returning really weird json.
Fiddler's raw result looks like below.
{"d":"[[{\"name\":\"Label1\",\"y\":28....
Is there something like JsonResult for webforms? I guess since method return is of type string it's messing up the result and I don't know why it's coming up as array inside array and with name d.
I need this in [{name: "Label1", "y":28},{...] format.
How do i get it in this format?
[WebMethod]
public static string GetData()
{
JavaScriptSerializer json = new JavaScriptSerializer();
var myTable= DataTable.AsEnumerable().Where(x => x.Field<int>(1) == 2018)
.Select(x => new[]
{
new { name = "LABEl 1", y = x[2] },
new { name = "Label 2", y = x[3] },
});
String export= json.Serialize(myTable);
return export;
}
You could easily convert it back to json inside success method of your Ajax call using
var obj = JSON.parse(response.d);

Custom Type Deserialize to 'object' results in extra curly brackets

I have a class like this:
class Document
{
public string id {get;set;}
public string name {get;set;}
}
var doc = new Document() { id= "1", name = "Doc1" };
var docs = new List<Document>() { doc };
...
I am sending docs through HTTP post to my backend service.
In my controller, I am receiving it as List docs.
The reason for this is, I want to use one controller to accept any Custom Types.
The trouble is, that, each item in List docs are wrapped inside extra curly braces
"{{\"id\":\"1\", \"name\":\"Doc1\"}}"
How to prevent extra curly braces? Can it be prevented?
If cannot be prevented, is there a way to extra the object removing the extra "{" and "}" ?
There is something called Newtonsoft.Json. It has whole lot of methods like Serialize and Deserialize objects. Check the link. Specially when you are sending values to the Api, The Api should accept the same thing as you are sending. If you are sending List then Api should accept same class List in its parameter.
If you are receiving some result from the API/you are consuming the API you should deserialize the string received in result.
To do this you can use -:
JObject,JToken
Newtonsoft.Json.JsonConvert.Deserialize
The actual output of serializing the list of documents would be:
[{"id":"1","name":"Doc1"}]
The outer [] is an array, and each object inside {id: number, name: string} is your document.
var doc = new Document { id = "1", name = "Doc1" };
var docs = new List<Document> { doc };
var result = Newtonsoft.Json.JsonConvert.SerializeObject(docs);
Console.WriteLine(result);

ASP.NET getting indexed values when deserializing JSON into a dynamic object

So I have a JSON string that I am passing from an AJAX call to my controller. I have a list of indexed values that I am passing into a dynamic object.
I deserialize the JSON with
JsonConvert.DeserializeObject<dynamic>(s)
This is the output from that dynamic object:
"RolePermissions[0].RolePermissionId": "269",
"RolePermissions[0].HasAccess": "false",
"RolePermissions[1].RolePermissionId": "270",
"RolePermissions[1].HasAccess": "false",
"RolePermissions[2].RolePermissionId": "271",
"RolePermissions[2].HasAccess": "true",
"RolePermissions[3].RolePermissionId": "272",
"RolePermissions[3].HasAccess": "false"
When I try to access the a property of the object with
ssObj.RolePermissions[0].RolePermissionId
I get a RuntimeBinderException. I have tried to use JObject.Parse, which works great, but for some reason, the values in the array become out of order.
Any help would be greatly appreciated. Thanks!
When you try to do RolePermissions[0].RolePermissionId you are trying to access a nested collection containing an object with a property RolePermissionId at index 0. But your JSON doesn't represent a hierarchy of objects, it represents a single flat object with key/value pairs whose keys contain periods and brackets. Since c# identifiers don't allow such characters so you have no way to access such property values using dynamic directly.
Instead, your options include:
Take advantage of the fact that JsonConvert.DeserializeObject<dynamic>(s) actually returns a JObject and use its dictionary indexer:
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
var rolePermissionId = (string)ssObj["RolePermissions[0].RolePermissionId"];
If you prefer a slightly more typed solution, you could deserialize to a Dictionary<string, dynamic>:
var ssDict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(s);
var rolePermissionId = (string)ssDict["RolePermissions[0].RolePermissionId"];
Or for a much more statically typed solution, parse explicitly to a JObject and use LINQ to JSON:
var jObj = JObject.Parse(s);
var rolePermissionId = (string)jObj["RolePermissions[0].RolePermissionId"];
Sample fiddle showing the various options.
If you are in control of the data being sent via AJAX then make sure the data sent is properly formatted.
In order to be able to deserialize variable s like:
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
and access the resulting object in this manner:
ssObj.RolePermissions[0].RolePermissionId
then the JSON value in s, based on your sample and desired behavior, would have to look like this:
{
"RolePermissions": [
{
"RolePermissionId": "269",
"HasAccess": "false"
},
{
"RolePermissionId": "270",
"HasAccess": "false"
},
{
"RolePermissionId": "271",
"HasAccess": "true"
},
{
"RolePermissionId": "272",
"HasAccess": "false"
}
]
}
This quick unit test showed that it is possible to get indexed values when deserializing JSON into a dynamic object
[TestClass]
public class UnitTest1 {
[TestMethod]
public void GetIndexedValuesWhenDeserializingJSONIntoDynamicObject() {
var s = #"
{
'RolePermissions': [
{
'RolePermissionId': '269',
'HasAccess': 'false'
},
{
'RolePermissionId': '270',
'HasAccess': 'false'
},
{
'RolePermissionId': '271',
'HasAccess': 'true'
},
{
'RolePermissionId': '272',
'HasAccess': 'false'
}
]
}
";
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
var result = ssObj.RolePermissions[0].RolePermissionId;
Assert.AreEqual("269", (string)result);
}
}
So you need to make sure you are sending well formatted JSON to your controller to achieve desired behavior.

Serializing JS Functions into JSON for a JsonResult MVC

I am writing a backend for SlickGrid. I have an AJAX call that loads the column definitions from my MVC Controller. The controller looks like this:
Public ActionResult GetColumns(...){
List<object> columns;
foreach(var col in MyColumns){
columns.Add(new { id = col.id, name = col.name, width = col.width});
}
return Json(new { columns = columns });
}
One of the column attributes that slickgrid accepts is formatter, which takes a js function name.
Unfortunately, MVC puts that name in double quotes. I need to figure out if there is a way to serialize just that one field without quotes.
eg (this is what I want)
[{"id":1,"Name":"FirstName","width":50,"formatter":NameFormater},...]
vs (ths is what I am getting now)
[{"id":1,"Name":"FirstName","width":50,"formatter":"NameFormater"},...]
I know this isn't proper JSON Format to pass JS Code in it(Proper JS Format though). But I have a valid use case here and am trying not to add too much complexity.
You could wrap the word NameFormater with special characters such as
[{"id":1,"Name":"FirstName","width":50,"formatter":"#NameFormater#"},...]
and when you get your results back, if you are using javascript
function(result){
result = result .replace(/"#/g, "");
result = result .replace(/#"/g, "");
// result now = [{"id":1,"Name":"FirstName","width":50,"formatter":NameFormater},...]
// ...Pass result to SlickGrid
}

Categories