I'm stuck on something:
I deserialized a JSON file using JObject.Load:
// get the JSON into an object
JObject jsonObject = JObject.Load(new
JsonTextReader(new StreamReader("mydoc.json")));
Fine. I now have a populate jsonObject.
Now I iterate through its properties like this:
foreach (JProperty jsonRootProperty in jsonObject.Properties())
{
if (jsonRootProperty.Name=="Hotel")
{
... !!! I just want a JObject here...
}
}
Once I find a property with a Name equal to "Hotel", I want that property's value as a JObject. The catch is that the Hotel property name might be a single value (say, a string), or it might be a JSON object or a JSON array.
How can I get the property's value into a JObject variable so that I can pass it to another function that accepts a JObject parameter?
Get the Value of the JProperty, which is a JToken, and look at its Type. This property will tell you if the token is an Object, Array, String, etc. If the token type is Object, then you can simply cast it to a JObject and pass it to your function. If the token type is something other than Object and your function has to have a JObject, then you'll need to wrap the value in a JObject in order to make it work.
foreach (JProperty jsonRootProperty in jsonObject.Properties())
{
if (jsonRootProperty.Name=="Hotel")
{
JToken value = jsonRootProperty.Value;
if (value.Type == JTokenType.Object)
{
FunctionThatAcceptsJObject((JObject)value);
}
else
{
FunctionThatAcceptsJObject(new JObject(new JProperty("value", value)));
}
}
}
Related
In newtonsoft json.net when we use
JsonConvert.SerializeObject(null, Formatting.Indented)
I get "null" in the output as expected.
Now, I would like to represent objects (which can be null) with a JObject, but it throws an exception when I try to encode null this way:
(JObject.FromObject(null)).ToString(Formatting.Indented)
Is there a way to do this?
Thanks
To represent a null value with a JToken, you can use JValue.CreateNull().
JToken token = JValue.CreateNull();
string json = token.ToString();
If, like me, you are just trying to cast an object that may or may not be null to a JToken, you can use the implicit value conversion operators by just casting it to JToken.
JObject obj = new JObject();
string s = null;
int? i = null;
obj.Add("s", (JToken)s);
obj.Add("i", (JToken)i);
var serialized = obj.ToString(Formatting.Indented);
I have an object called PostMapDB and a method which retrieves a list of those objects. I would like to be able to pass this list and retrieve the data using webapi.
The code bellow gets me an error:{"":["The input was not valid."]}
[HttpGet]
public string Get(PostMapDB list)
{
IEnumerable<PostMapDB> dataOfPosts = list.getAllPosts().OrderBy(x => x.Date);
var data = JsonConvert.SerializeObject(dataOfPosts, new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = false
}
});
return data;
}
How does your request to server looks like?
What's the definition on PostMapDB?
Make sure you're passing data in a right way.
Probably the attribute FromBody would help:
public string Get([FromBody] PostMapDB list)
Reference: https://learn.microsoft.com/en-gb/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
Controller.java
#RequestMapping(value = { ControllerUriConstant.add }, method = RequestMethod.POST)
#ActivityMapping(activity = ActivityEnum.ADD)
public String addActivities(#ModelAttribute("activityForm") ActivityForm activityForm, BindingResult bindingResult, Model model,
HttpServletRequest request) throws Exception {
new ActivityFormValidator().validate(activityForm, bindingResult, request.getLocale(), getMessageSource(), null, activityService);
if (bindingResult.hasErrors()) {
model.addAttribute(Constants.ACTIVITY_FORM,activityForm );
model.addAttribute(Constants.HAS_ERROR, Boolean.TRUE);
model.addAttribute("add", true);
model.addAttribute(Constants.ERROR_MESSAGE, getMessageSource().getMessage("ulearn.messages.add.failed", activityForm.getName()));
return "activityform";
} else {
model.addAttribute(Constants.SUCCESS_MESSAGE, getMessageSource().getMessage("ulearn.messages.add.success", activityForm.getName()));
JSONArray address =new JSONArray();
JSONObject jo = new JSONObject();
jo.put("id", "1");
jo.put("name","Test");
JSONObject jo1= new JSONObject();
jo1.put("id", "1");
jo1.put("name", "Test2");
JSONObject jo2= new JSONObject();
jo2.put("id", "1");
jo2.put("name", "Test3");
address.add(jo);
address.add(jo1);
address.add(jo2);
activityForm.setInsertJsonMysql(address);
activityService.add(activityForm);
}
return getActivities( model, request);
}
Service.java
public void add(ActivityForm activityForm) throws TechnoShineException {
try {
Activity activity = new Activity();
activity.setName(activityForm.getName());
activity.setActive(activityForm.getActive());
activity.setInsertJsonMysql(activityForm.getInsertJsonMysql());
activityDAO.getMapper().insert(activity);
logAudit(getAuditableList(activity, null), getMessageSource().getMessage("ulearn.messages.add.success", activity.getName()), 0, ActivityEnum.ADD);
} catch (Exception e) {
throw new TechnoShineException(e, ActivityService.class);
}
}
Mapper.xml
<insert id="insert" parameterType="com.technoshinelabs.ulearn.persistance.bean.controlpanel.Activity">
INSERT INTO activity (activity_name,is_active,json_array)
VALUES (#{name},#{active},#{insertJsonMysql})
</insert>
// Finally got this error error Caused by: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'insertJsonMysql'. It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
[1]: https://i.stack.imgur.com/OeZeR.png
I suppose what you want to store is the actual JSON and the MySQL table column json_array is of type VARCHAR or TEXT.
JSONArray is actually but an utility class used to build the JSON.
Then you shall change the type of property insertJsonMysql of class Activity to String and set it to the String representation of the JSONArray.
activity.setInsertJsonMysql(activityForm.getInsertJsonMysql().toString());
EDIT: about inserting into enum column.
According to MySQL 5.7 Reference Manual, I would say you insert into enum typed column the same way you insert any String, the DB will check provided value against list of values declared in CREATE TABLE.
But according to the code sample you provide, the value for insertJsonMysql will be:
[{"id":"1","name":"Test1"},{"id":"1","name":"Test2"},{"id":"1","name":"Test3"}]
that means one of the enum values would have to be this exact string.
However, I feel like that's not what you expect. Maybe using a SET typed column is a closer answer.
[System.Web.Http.Route("{id}")]
[System.Web.Http.HttpPut]
public async Task<ComplaintVM> Put(int id,int? employeeId)
{
var obj = _resolver.GetService<Complaint>();
obj.FranchiseId = 1;
obj.Id = id;
await obj.GetDetailAsyc();
obj.EmployeeId = employeeId;
await obj.AllocateAndManageCallAsyc();
return obj.EntityToVM();
}
This is put method with [System.Web.Http.RoutePrefix("api/app/complaint")]
so when i call my method with a PUT request i get the following error "message: "The requested resource does not support http method 'PUT'.".
but when i make the same call when the method does not have int? employeeId parameter. The call happens fine.
I am passing the employeeId as a json formatted request. I am using fiddler to test the code
The issue with Put(int id,int? employeeId) is the variable int? employeeId, since it was not part of the URL the model binder was not able to bind the attribute and hence was not able call the method with 2 parameters.
Using the [FormBody] did not work, the value returned was null, this is because the input was in form of a json.
The issue was solved by using a parameter of type Employee which had a property of EmployeeId so the value was mapped to the EmployeeId of the employee object, the method signature is Put(int id,Employee employee),
if there is no model class to bind, a parameter of type JObject can used as a input parameter and later the value can be extracted from JObject.
In my application, I am sending a json object to a service and at the service end, I expect an object of type dynamic
public bool TestService(dynamic entity)
{
// process
}
When i debug and see the entity filled, I am not able to type cast it. Any idea how i can retrieve fields from the entity sent
I'm curious - if you're sending up a JSON formatted object, why not have your service method accept a string and then use something like JSON.net to cast it to the appropriate type?
public bool TestService(string entity)
{
var myObject = JsonConvert.DeserializeObject<MyObjectType>(entity);
//do stuff with myObject...
}
Or you could deserialize it into an anonymous object:
public bool TestService(string entity)
{
var myAnonymousObject = new { Name = String.Empty, Address = String.Empty };
var myObject = JsonConvert.DeserializeAnonymousType(entity, myAnonymousObject);
//do stuff with myObject
}
I guess I'm not sure why your JSON formatted object needs to be dynamic.