I'm kind of a fresher when it comes to doing API work especially with JSON.
Here's what my code looks like...
Endpoing:
[HttpPost("postWithBody")]
public async Task<IActionResult> PostWithBody (string param1, [FromBody] object requestBody)
{
var x = JsonSerializer.Deserialize<ParamModel>(requestBody); <-- Error cannot convert from 'object' to System.ReadOnlySpan<byte>
return ok(param1); <--this here just so it doesn't bark at me
}
SO in the above code, I'm erroring out on (RequestBody) with this error:
Error cannot convert from 'object' to System.ReadOnlySpan
public class ParamModel
{
public string PName {get;set;}
public string PValue {get;set;}
}
But essentially to finish the demo of what I'm trying to accomplish is, goal is to pass JSON value to this endpoint in the body that looks like this:
{
"Param1": "XXX",
"Param2": "111"
}
and my goal would be for CustomParams model class to have the
PName = Param1
PValue = "XXX"
and
PName = "Param2"
PValue = "111"
Is this the correct approach I'm taking?
Thank you.
EDIT: I guess I could do something like: [FromBody] ParamModel requestBody
and I did try it, when I pass JSON like this, it came as null in the endpoint:
{"test":"hey"}
But also, I probably would need to do something like this, since I want to have the option of passing multiple params.
public class ParamList
{
public List<ParamModel> data {get;set;}
}
and have that be [FromBody] ParamList requestBody
First of all I would suggest that you use the model in the action parameter and let the framework do the deserialisation for you:
public async Task<IActionResult> PostWithBody(
string param1, [FromBody] ParamModel requestBody)
Now you will be able to post JSON in that matches that object, something like this for example:
{
"PName": "test",
"PValue": "hey"
}
In your update, you say that you would like instead to use the ParamList object. In that case, you would need JSON that matches, something like this:
{
"data": [
{ "PName": "test1", "PValue": "hey1" },
{ "PName": "test2", "PValue": "hey2" }
]
}
Now in your action you can loop over the list like this:
foreach(var param in requestBody.data)
{
var paramName = param.PName;
var paramValue = param.PValue;
// etc.
}
I'm trying to make my dataset correspond to this example:
var family = [{
"name" : "Jason",
"age" : "24",
"gender" : "male"
},
{
"name" : "Kyle",
"age" : "21",
"gender" : "male"
}];
I have a Map<String, HashSet<String>> of Names and unique alpha-numeric values correponding to specific entities to which those names could refer, let's call these entry items "IDs".
So for instance, Fyodor Mikhailovich Dostoyevsky would perhaps be related to the ID Q626, because that's a very specific reference, there aren't many widely known figures with that name. Whereas, Bush might be attached to G027, Q290, and Q118, referencing perhaps the man, the beer, and the shrub, in no particular order.
It looks like this (the real one is much bigger):
[Rao=[Q7293658, , Q7293657, Q12953055, Q3531237, Q4178159, Q1138810, Q579515, Q3365064, Q7293664, Q1133815], Hani Durzy=[], Louise=[, Q1660645, Q130413, Q3215140, Q152779, Q233203, Q7871343, Q232402, Q82547, Q286488, Q156723, Q3263649, Q456386, Q233192, Q14714149, Q12125864, Q57669, Q168667, Q141410, Q166028], Reyna=[Q7573462, Q2892895, Q363257, Q151944, Q3740321, Q2857439, Q1453358, Q7319529, Q733716, Q16151941, Q7159448, Q5484172, Q6074271, Q1753185, Q7319532, Q5171205, Q3183869, Q1818527, Q251862, Q3840414, Q5271282, Q5606181]]
Using Jackson I tried like this:
Map<String, HashSet<String>> map = q_valMap;
mapper.writeValue(new File("JSON_Output/user.json"), map);
But this seems wrong, as my output was all jumbled together, i.e.
{"Rao":["Q7293658","","Q7293657","Q12953055","Q3531237","Q4178159","Q1138810","Q579515","Q3365064","Q7293664","Q1133815"],"Hani Durzy":[""],"Louise":["","Q1660645","Q130413","Q3215140","Q152779","Q233203","Q7871343","Q232402","Q82547","Q286488","Q156723","Q3263649","Q456386","Q233192","Q14714149","Q12125864","Q57669","Q168667","Q141410","Q166028"],"Reyna":["Q7573462","Q2892895","Q363257","Q151944","Q3740321","Q2857439","Q1453358","Q7319529","Q733716","Q16151941","Q7159448","Q5484172","Q6074271","Q1753185","Q7319532","Q5171205","Q3183869","Q1818527","Q251862","Q3840414","Q5271282","Q5606181"]}
Do I just have to populate this JSON object iteratively?
Like the example up top, I think it should look something like this, though what follows is only a pseudocodish characterization, which is to say, not exactly this but something similar:
{
key: "Rao"
value: ["Q7293658","","Q7293657","Q12953055","Q3531237","Q4178159","Q1138810","Q579515","Q3365064","Q7293664","Q1133815"]
key: "Hani Durzy"
value: [""]
key: "Louise"
value: ["","Q1660645","Q130413","Q3215140","Q152779","Q233203","Q7871343","Q232402","Q82547","Q286488","Q156723","Q3263649","Q456386","Q233192","Q14714149","Q12125864","Q57669","Q168667","Q141410","Q166028"]
key: "Reyna"
value: ["Q7573462","Q2892895","Q363257","Q151944","Q3740321","Q2857439","Q1453358","Q7319529","Q733716","Q16151941","Q7159448","Q5484172","Q6074271","Q1753185","Q7319532","Q5171205","Q3183869","Q1818527","Q251862","Q3840414","Q5271282","Q5606181"]
}
is that not right?
UPDATE
public class JsonMapFileExample
{
public static void map(Map<String, HashSet<String>> q_valMap )
{
ObjectMapper mapper = new ObjectMapper();
ArrayNode array = mapper.createArrayNode();
for ( Entry entry: q_valMap.entrySet() )
{
ObjectNode node = mapper.createObjectNode()
.put("name", entry.getKey())
.put("ids", entry.getValue());
array.add(node);
}
mapper.writeValue("/home/matthias/Workbench/SUTD/nytimes_corpus/wdtk-parent/wdtk-examples/JSON_Output/user.json", array);
}
}
class MyEntity
{
private String name;
Set<String> value; // use names that you want in the result JSON
//constructors
public MyEntity()
{
}
public MyEntity(String name)
{
this.name = name;
}
//getters
public String getName()
{
return this.name;
}
public Set<String> getValue()
{
return this.value;
}
//setters
public void setName(String name)
{
this.name = name;
}
public void setValue(Set<String> value)
{
this.value = value;
}
}
You could manually set the key names, something like:
ArrayNode array = mapper.createArrayNode();
for (Entry entry: yourMap.entries()) {
ObjectNode node = mapper.createObjectNode()
.put("name", entry.key())
.putPOJO("ids", entry.value());
array.add(node);
}
mapper.writeValue(file, array);
Alternatively, you could create a class for your data
class MyEntity {
String name;
Set<String> ids; // use names that you want in the JSON result
// getters, setters if necessary
}
Transform your data map into a list of MyEntity, then use Jackson ObjectMapper to create JSON like mapper.writeValue(file, listOfMyEntities), the output would be like
[
{
"name": "some name here",
"ids": ["id1", "id2", ...]
}
// more elements here
]
how about this:
String name_list_file = "/home/matthias/Workbench/SUTD/nytimes_corpus/NYTimesCorpus/2005/01/02/test/people_test.txt";
String single_name;
try (
// read in the original file, list of names, w/e
InputStream stream_for_name_list_file = new FileInputStream( name_list_file );
InputStreamReader stream_reader = new InputStreamReader( stream_for_name_list_file , Charset.forName("UTF-8"));
BufferedReader line_reader = new BufferedReader( stream_reader );
)
{
while (( single_name = line_reader.readLine() ) != null)
{
//replace this by a URL encoder
//String associated_alias = single_name.replace(' ', '+');
String associated_alias = URLEncoder.encode( single_name , "UTF-8");
String platonic_key = single_name;
System.out.println("now processing: " + platonic_key);
Wikidata_Q_Reader.getQ( platonic_key, associated_alias );
}
}
//print the struc
Wikidata_Q_Reader.print_data();
}
I am using Json.net in my MVC 4 program.
I have an object item of class Item.
I did:
string j = JsonConvert.SerializeObject(item);
Now I want to add an extra property, like "feeClass" : "A" into j.
How can I use Json.net to achieve this?
You have a few options.
The easiest way, as #Manvik suggested, is simply to add another property to your class and set its value prior to serializing.
If you don't want to do that, the next easiest way is to load your object into a JObject, append the new property value, then write out the JSON from there. Here is a simple example:
class Item
{
public int ID { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Item item = new Item { ID = 1234, Name = "FooBar" };
JObject jo = JObject.FromObject(item);
jo.Add("feeClass", "A");
string json = jo.ToString();
Console.WriteLine(json);
}
}
Here is the output of the above:
{
"ID": 1234,
"Name": "FooBar",
"feeClass": "A"
}
Another possibility is to create a custom JsonConverter for your Item class and use that during serialization. A JsonConverter allows you to have complete control over what gets written during the serialization process for a particular class. You can add properties, suppress properties, or even write out a different structure if you want. For this particular situation, I think it is probably overkill, but it is another option.
Following is the cleanest way I could implement this
dynamic obj = JsonConvert.DeserializeObject(jsonstring);
obj.NewProperty = "value";
var payload = JsonConvert.SerializeObject(obj);
You could use ExpandoObject.
Deserialize to that, add your property, and serialize back.
Pseudocode:
Expando obj = JsonConvert.Deserializeobject<Expando>(jsonstring);
obj.AddeProp = "somevalue";
string addedPropString = JsonConvert.Serializeobject(obj);
I think the most efficient way to serialize a property that doesn't exist in the type is to use a custom contract resolver. This avoids littering your class with the property you don't want, and also avoids the performance hit of the extra serialization round trip that most of the other options on this page incur.
public class SpecialItemContractResolver : DefaultContractResolver {
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
var list = base.CreateProperties(type, memberSerialization);
if (type.Equals(typeof(Item))) {
var feeClassProperty = CreateFeeClassProperty();
list.Add(feeClassProperty);
}
return list;
}
private JsonProperty CreateFeeClassProperty() {
return new JsonProperty {
PropertyName = "feeClass",
PropertyType = typeof(string),
DeclaringType = typeof(Item),
ValueProvider = new FeeClassValueProvider(),
AttributeProvider = null,
Readable = true,
Writable = false,
ShouldSerialize = _ => true
};
}
private class FeeClassValueProvider : IValueProvider {
public object GetValue(object target) => "A";
public void SetValue(object target, object value) { }
}
}
To use this functionality:
// This could be put in a static readonly place so it's reused
var serializerSettings = new JsonSerializerSettings {
ContractResolver = new SpecialItemContractResolver()
};
// And then to serialize:
var item = new Item();
var json = JsonConvert.Serialize(item, serializerSettings);
I want to parse JSON string to some my custom object in Action script 3. Is there some libs to do this. Or any ideas how can I make this. Thanx!
Here is an example what I want to receive:
{
"result":{
"birthday_at":"0000-00-00",
"first_name":"Myname1",
"level":5,
"last_name":"MySurname",
"gender":0
},
"cmd":"INFO",
"service":{
"code":0,
"error_desc":""
}
}
and class UserInfo:
public class UserInfo
{
public Date birthday_at;
public String first_name;
public String last_name;
public int level;
public int gender;
}
And I want, to parse JSON string to fields of my class? How can I do this in an easiest way and in a right way? Thanx!
var obj:Object = JSON.decode( jsonString );
var user:UserInfo = new UserInfo();
for ( var prop:String in obj )
user[prop] = obj[prop];
This doesn't work for custom types with getters (read-only properties).
describeType can be used to get only the properties that can be set, but there are performance issues.
Darron Schall has a brilliant solution to take your JSON.parse(jsonString) plain object and convert it to a custom typed object.
https://github.com/darronschall/ObjectTranslator
Using the class mentioned in the previous answer, you would simply need to do the following:
var obj:Object = JSON.decode( jsonString );
var user:UserInfo = new UserInfo();
for ( var prop:String in obj )
user[prop] = obj[prop];
There is Adobe's JSON parser.
https://github.com/mikechambers/as3corelib/tree/master/
import com.adobe.serialization.json