I have the following type of message (JSON) for over 100k records in one of the columns of the excel sheet
string message = "{'id': '01','name': 'Rockey','details': 'He is the number one student and a great sports person. ðŸ\u008f´\\U000e0067\\U000e0062\\U000e0073\\U000e0063\\U000e0074\\U000e007f #blackandwhite'}";
I am trying to deserialize them but I am getting following error.
Bad JSON escape sequence: \U
My code is as follows
public class Person
{
public string id { get; set; }
public string name { get; set; }
public string details { get; set; }
}
static void Main(string[] args)
{
string message = "{'id': '01','name': 'Rockey','details': 'He is the number one student and a great sports person. ðŸ\u008f´\\U000e0067\\U000e0062\\U000e0073\\U000e0063\\U000e0074\\U000e007f #blackandwhite'}";
message = message.Replace("\\", "\\\\");
var person=JsonConvert.DeserializeObject<Person>(message);
}
If I write like above it is working for certain records but fails for other records basically what I observed is the JSON in the excel column is sometimes not in exact valid format and if I did as above some of the other JSON which are not required to replace also replacing and those are failing to Deserialize.
I want to use message.Replace if required only otherwise wanted to Deserialize directly.
How do I know whether or not it is required to replace before converting?
What is the role played by UTF-8 here some developers are saying I need to use UTF-8?
Note:
The Excel sheet is coming from a client we have no authority on that we need to use as it is and they are generating that excel sheet using some tool and column data is JSON only
Related
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.
Update: After all day messing with this, I fixed it.
I Changed my mobileserviceclient URL to include https instead of HTTP.
I think this was causing my post to instead be a get request that returned an array of "Comment" and tried to parse it to a single "Comment" therefore the error.
Having trouble debugging this, I have the following table/class:
public class Comment
{
public string Content { get; set; }
public string UserId { get; set; }
public string MenuItemId { get; set; }
}
Using AzureMobileServiceClient I can get data from the Azure Mobile App into my Xamarin App so the JSON returned from the client must be getting deserialized into my Comment type but when I try to add data using the following code:
var comment = new Comment
{
Content = NewComment,
MenuItemId = Item.Id,
UserId = App.CloudService.CurrentUser.UserId
};
await App.CloudService.client.GetTable<Comment>().InsertAsync(comment);
I get the error "Cannot populate JSON array onto type 'Comment'"
I can insert the data fine using postman definitely something wrong on the client-side. I saw one other question on this and they said they fixed it by deleting the project and remaking but I'd rather figure out what is actually happening.
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!
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}]}
When writing up the title to this question, I happened upon this answer. However I'm looking for a way to do this in a WCF client. Is there a way to plug JSON.Net into a WCF client?
Yahoo! just changed its PlaceFinder service a couple of days ago. One change is that responses no longer contain a Results node, instead they now contain a Result node. Another change is that sometimes this node contains an array of result objects (when there are 2 or more results) and other times it contains a single result object (when there is only 1 result).
Is there a way to use WCF DataMemberAttributes to deserialize this kind of structure, accommodating for both scenarios?
[DataContract]
public class PlaceFinderResultSet : IEnumerable<PlaceFinderResult>
{
// this works for 1 result, but fails when it is an array
[DataMember(Name = "Result")]
public PlaceFinderResult Result { get; set; }
// this works for an array of results, but fails when it is a single
[DataMember(Name = "Result")]
public List<PlaceFinderResult> { get; set; }
// note I do not use these together at the same time, but comment one out
// at a time. Other members in this class work as expected and are omitted
}
Here are 2 example responses as seen in Fiddler2 (again, some parts of the result are omitted):
JSON (here is a response with 1 result)
|--ResultSet
|--|--Found=1
|--|--Quality=37
|--|--Result
|--|--|city=city name
|--|--|country=country name
|--|--|otherprops=other values
JSON (here is a response with many results)
|--ResultSet
|--|--Found=2
|--|--Quality=40
|--|--Result
|--|--|{}
|--|--|--|city=city name1
|--|--|--|country=country name1
|--|--|--|otherprops=other values1
|--|--|{}
|--|--|--|city=city name2
|--|--|--|country=country name2
|--|--|--|otherprops=other values2