Anonymous object blob in database not serializing as JSON when queried - json

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!

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.

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

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.

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.

Cannot get my html input array to serialize into a List<string> in Asp.Net mvc

I am attempting to implement a tagging system into my asp.net MVC project. When a user edits or adds a task, they can add any amount of tags they want before submitting. I am using the Jquery Tagit plugin, so when a user adds a new tag an input field is created that looks like:
<input type="hidden" style="display:none;" value="tag1" name="Tags[]">
When the user presses the submit button after adding a few tags, the browser sends the following querystring to the server (retrieved via fiddler):
IsNew=True&Id=2222&Title=Test+Title&Description=Test+Description&Tags%5B%5D=Tag1&Tags%5B%5D=blah&Tags%5B%5D=another-tag
Now my viewmodel that I am serializing this data into has the following structure:
public class KnowledgeBaseTaskViewModel
{
public int Id { get; set; }
[Required(AllowEmptyStrings=false, ErrorMessage="Task title is required")]
[StringLength(500)]
public string Title { get; set; }
[Required(AllowEmptyStrings=false, ErrorMessage="Task description is required")]
[StringLength(500)]
public string Description { get; set; }
public List<string> Tags { get; set; }
public bool IsNew { get; set; } // Needed to determine if we are inserting or not
}
Finally my receiving action has the following signature:
[HttpPost]
public ActionResult EditTask(KnowledgeBaseTaskViewModel task)
The issue is that my tag list is not serializing correctly, and my List Tags is null. I have looked at various questions on this site on how to serialize arrays but I still cannot see what I am doing wrong. Any help is greatly appreciated.
It sounds like what you've got should work, but try changing the type of Tags property from List to IList. the model binder might not be using the concrete List<> type.
also, check out this article by Phil Haack: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx