Converting JSON post data into array of objects - json

Server side : ASP.NET WEB-API 2.0
I am posting a bunch of name value pairs from client side to server side as JSON. On the server side (WEB API controller), I would like to convert them into array/list of object containing the name and value.
JSON post data :
[{"name":"sEcho","value":9},
{"name":"iColumns","value":6},
{"name":"sColumns","value":"Name1,Name2,Name3,Name4,Name5,Name6"},
{"name":"iDisplayStart","value":0},
{"name":"iDisplayLength","value":10},
{"name":"mDataProp_0","value":0},
{"name":"mDataProp_1","value":1},
{"name":"mDataProp_2","value":2},
{"name":"mDataProp_3","value":3}]
I tried to map it in server side using the following mode but it did not work
public IHttpActionResult Post([FromBody]GridDataModel gridData)
Models
public class GridDataModel
{
public GridData[] GridData { get; set; }
}
public class GridData
{
public string Name { get; set; }
public string Value { get; set; }
}
I am used to mapping a JSOn strcuture like this a single object with each name value mapping to an object attribute. Not sure how I can convert it into an array of objects. I need it to be an array because the number of name value pairs will be dynamic.
Any help will be appreciated!
Thanks in advance..

The method is expecting a single instance and not an array. I believe you could do 2 things
1) Change the method signature
public IHttpActionResult Post([FromBody]IEnumerable<GridData> gridData)
2) Change the json object
{"gridData": [{"name":"sEcho","value":9},
{"name":"iColumns","value":6},
{"name":"sColumns","value":"Name1,Name2,Name3,Name4,Name5,Name6"},
{"name":"iDisplayStart","value":0},
{"name":"iDisplayLength","value":10},
{"name":"mDataProp_0","value":0},
{"name":"mDataProp_1","value":1},
{"name":"mDataProp_2","value":2},
{"name":"mDataProp_3","value":3}]}

Related

Returning a Json-field from SQL to ASP.NET Core API

I'm building a relatively simple Get-method in an ASP.NET Core (3+) application. (Currently 3.1 - to be migrated to 5)
The object I need to return looks like this:
public class Data
{
public int ID { get;set;}
public string Name { get;set;}
public string Settings { get; set;}
}
And the Get-method is simply this:
public IActionResult<Data> GetData()
{
var data = _dbContext.GetData<Data>();
return Ok(data);
}
This works perfectly - except for one thing.
In SQL - the settings column (varchar(8000)), contains JSON data. In some cases, a setting can be something simple like : { "threshold": 8754 } and sometimes it can be a large complex object with many fields, but it is always valid Json.
On the ASP side, it does exactly what you would expect. It turns a serialized Json object that contains an INT and 2 x strings.
I would like for it to return an INT, ONE String and One Json Object.
Is there any way that I can tell the serializer that the Settings-property contains Json?
In a perfect world, I would love something like this:
public class Data
{
public int ID { get;set;}
public string Name { get;set;}
[SerializeContentAsJson]
public string Settings { get; set;}
}
Is there a way to do this or is there some other fairly elegant solution to this problem?
Btw. I fully realize that the caller can specify the content types that he/she will accept. In this case, the API is purely for use inside my team and we will always want JSON, so I can compromise on this being a relatively custom solution that might not work if you wanted text/html or some other content type.

how json parameter pass in asp.net web api action method

My asp.net web api is an standalone application,face problem to pass json sa a parameter.My api method is bellow
[Route("api/UniqueUser/{userInfo}")]
public HttpResponseMessage GetUniqueUserByEmail(string userInfo)
{
}
In above parameter userInfo is a josn like bellow
{"UserInfo":[{"Id":1,"UserName":"Jxj Bdn","Email":"a#a.com"}]}
When I put this in my browser url show me bellow error
JSON data should go in the body of the request for it to be deserialized, not in the query string/browser URL.
Also, 'string userInfo' will not work as you expect. You can define a class that represents the parameters of your JSON object and it will work correctly.
This would work, for example:
public class UserInfo
{
public int Id { get; set;}
public string UserName { get; set;}
public string Email { get; set;}
}
and change this line:
public HttpResponseMessage GetUniqueUserByEmail(UserInfo userInfo)
Edit:
If it's a url that someone needs to pass in you use routing:
https://site/api/UniqueUser/1/Jxj Bdn/a#a.com
And in your controller:
[Route("api/UniqueUser/{id}/{userName}/{email}")]
public HttpResponseMessage GetUniqueUserByEmail(int id, string userName, string email)
Have a look here to see how to do this with traditional query string parameters too:
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
I would strongly suggest using the first method though, it gives you a strongly type object and is a lot easier to deal with if details change, and you get the benefit of the build in model validation.
Can you not make a simple HTML form for your clients to use?

Anonymous object blob in database not serializing as JSON when queried

I have a need to store an unknown data structure in a SQL Server database table field via ORMLite. This is to support a timeline feature on a website where each step on the timeline contains different information, and I want to store them as generic "Steps", with the variable data in a "StepData" property. I have the POCO set up like this:
public class ItemStep
{
public ItemStep()
{
this.Complete = false;
}
[Alias("ItemStepId")]
public Guid Id { get; set; }
[References(typeof(Item))]
public Guid ItemId { get; set; }
[References(typeof(Step))]
public int StepId { get; set; }
public object StepData { get; set; }
[Reference]
public Step Step { get; set; }
public bool Complete { get; set; }
public DateTime? CompletedOn { get; set; }
}
My front-end send a JSON object for StepData, and it's saved to the database appropriately.
{itemAmount:1000,isRed:False,isBlue:True,conversion:True}
Now, when I go to retrieve that data using...
List<ItemStep> itemSteps = Db.Select<ItemStep>(q => q.ItemId == request.ItemId).OrderByDescending(q => q.StepId).ToList<ItemStep>();
...the "StepData" node of the JSON response on the client is not a Javascript Array object as I'm expecting. So, on the client (AngularJS app using Coffeescript),
ItemStep.getItemSteps(ItemId).then((response) ->
$scope.StepData = response.data.itemSteps[0].stepData
is a double-quoted string of the JSON array.
"{itemAmount:1000,isRed:False,isBlue:True,conversion:True}"
Can anybody help me with this? I've tried parsing that string as JSON and I can't seem to get it to work:
JSON.parse($scope.StepData)
I'm using the exact same methodology in other areas of the app to store and retrieve things like addresses, with the only difference I can see being that there is a specified Address class.
Thanks!
Found this link that solved my problem: https://github.com/ServiceStackV3/mythz_blog/blob/master/pages/314.md
Essentially I added a "Type" field to the ItemStep class, and set that when I create a new row (create the next step in the timeline). Then, when I retrieve that record, I call a method like "GetBody" in the referenced link (GetStepData for me), that deserializes the object using the stored Type. I then stuff that back into a generic "object" type in the return POCO so that I can include many steps of varying types in the same call. Works great!
Thanks Mythz for the blog post!

How to validate double values in .Net using a custom validator?

I am developing an ASP.Net web api project and I want to validate my Server data model according to the JSON request I get from the Client side. In my Server Model Class, I have a double value and I am sending value from the Client Side as "12,14". I have written a custom validation class which is implemented by ValidationAttribute class of .Net and I am using IsValid(Object value) method to validate this user input.
So when I send my input as "12,14", .Net automatically converts this "12,14" to "1214" by thinking that "," is a group separator. But in this case, "," is not a group separator since this is a valid Double number for Norwaygian culture format ("no" culture).
public class Client : IClient
{
public string ClientId { get; set; }
public int EngagementId { get; set; }
[MyCustomDoubleType]
public double MyValue{ get; set; } //Notice that this is my double value to be validated.
}
This is the custom validator which I have written to validate "MyValue"
public class MyCustomDoubleTypeAttribute : ValidationAttribute
{
public override bool IsValid(object value) //When I send "12,14" from client, the value gets assigned to this value is "1214". .Net thinks "," is a group separator and removes it.
{
string doubleValue = value.ToString();
try
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("no");
double convertedDouble = double.Parse(doubleValue);
string convertedString = convertedDouble.ToString(Thread.CurrentThread.CurrentCulture);
if (convertedString.Equals(doubleValue))
{
return true;
}
return false;
}
catch (FormatException formatException)
{
return false;
}
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture,
ErrorMessageString,
name);
}
}
So this is my problem. What I want is to get the value as I enter in the client side to the input parameter of IsValid(Object value) method.
Thanks in advance.
You might be able to use a custom model binder. I know that you can use this on a regular MVC site, so I would assume that the same or similar code could be leveraged on Web API. There is a good example of using a custom binder for parsing double values at Phil Haack's site.
The culprit is probably Json.NET that's translating 12,14 into 1214 for you. You should look into writing a custom converter that is more careful about that.
You should be able to find instructions to write your own converter on the web. Here's an example:
How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?

Want to design a REST API but I have too much parameter to send , is it okay to replace them with one JSON?

I am designing a REST API one of my resources is all about to getting some basic data from user side.
Here are two points that I needs to mention:
all the user's information needs to send to server side with only one http request
the user's information is about 30 different fields.
So I think having a long list of argument in server side can not be that much good and I want to replace this part with a single argument which is accepting a JSON.
Do you think is it correct to do that?
Yes. You will want to change the method to a POST instead of a GET and in the request body send the JSON formatted data.
Example using C# syntax:
Assume you have a method that returns an object called ObjectList and in order to generate the list you the constructor requires an ObjectListRequest object -
public ObjectList GetObjectList(ObjectListRequest request)
{
return new ObjectList(request)
}
Your ObjectListRequest class could contain various different parameters that the request would use -
public class ObjectListRequest
{
public string SearchText { get; set; }
public string CreatedBy { get; set; }
public int SequenceStartRange { get; set; }
public int SequenceEndRange { get; set; }
public bool HasMetaData { get; set; }
}
Now to call this method using a POST with JSON in the body you would send the following
Method: POST
Url: http://your.service.com/GetObjectList
Headers:
Content-Type: application/json
Body:
{
"request":{
"SearchText":"test text",
"CreatedBy":"myusername",
"SequenceStartRange":0,
"SequenceEndRange":15,
"HasMetaData":"true"
}
}
This is a specific example which assumes you are using C# and built in Serialization libraries from microsoft, but if not, you can still use the same basic idea to do what you are trying to do.