Want to design a REST API but I have too much parameter to send , is it okay to replace them with one JSON? - 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.

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!

Converting JSON post data into array of objects

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}]}

Share Json data between Asp.Net MVC 2 and Asp.Net server side C# code?

I created and love my Asp.Net MVC2 application. It's a very nice DDD app with Domain Model classes, View Model classes, a repository, and Json action methods to expose data.
My coworker wants to share my data with his Asp.Net Forms based C# code. He wants to pull through the Internet a class definition (like a Data Contract), then fill it with my Json results, effectively using something like a remote repository.
Any links or ideas on how to provide him with data contracts and data?
Darin Dimitrov had an excellent idea of consuming JSON data using data contracts here. Just wondering if it's possible to use MVC as the source for these items, then let him create the objects on his side, filled with data from my side.
The key to this question is how to send him my data classes, then send him my data.
class Program
{
[DataContract]
class Person
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "surname")]
public string Surname { get; set; }
[DataMember(Name="age")]
public int Age { get; set; }
}
static void Main(string[] args)
{
var json = #"{""name"" : ""michael"", ""surname"" : ""brown"", ""age"" : ""35""}";
var serializer = new DataContractJsonSerializer(typeof(Person));
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var person = (Person)serializer.ReadObject(stream);
Console.WriteLine("Name : {0}, Surname : {1}, Age : {2}",
person.Name, person.Surname, person.Age);
}
}
}
Write an OData service. The format is JSON, but the tools to consume it easily -- from many languages -- are already written for you.
The nice thing about this is that your data is now not only consumable by your JS and your friend's ASP.NET app, it's consumable by Excel, PHP, etc.