I'm writing a Spring application with Hibernate framework.
In my application there is a JSON call. In that JSON response returns object hierarchy like below:
Object
SupplyBatch
Farmer
This farmer has attributes such as ID, Name, Address and contact.
First object of array list it returns all there attributes and child objects are filled with relevant data. But the problem is that farmer is in second or third or in any other supply batch, that farmer is returned as an attribute in supply batch called "Farmer" with value of farmer's ID.
But when I loop that object in controller it print all the farmer's name. I can't figure out what is this behavior. Here are the screenshots of sample objects.
This is the json response in my controller
#RequestMapping(value = {"admin/getTaskByDate","user/getTaskByDate"}, method = RequestMethod.GET)
public #ResponseBody List<Task> getTaskByDate(#RequestParam("date") String date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dat = null;
try {
dat = sdf.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<Task> tasksByDate = taskService.getFeedIssueTasksByDate(dat);
for(Task t : tasksByDate)
{
System.out.println("Farmers-"+t.getSupplyBatch().getFarmer().getName());
}
return tasksByDate;
}
and following is the code in jsp page which calls this json response
<script>
function getTaskById(){
var date = $('#inputDate').val();
$("#tblTask").find("tr:gt(0)").remove();
var sid = this.value;
$.ajax({
url : 'http://localhost:8080/jp/user/getTaskByDate.json?date='+date+'',
success : function(data) {
console.log(data);
for(var i = 0; i < data.length; i++) {
var obj = data[i];
var act;
var dt = new Date(obj.duedate);
if(obj.type == "Feed Issuing")
{
act='<td>Issue Feed</td>'
}
else
{
act='<td>Catch</td>';
}
$('#tblTask tr:last').after('<tr><td>'+obj.taskId+'</td><td>'+dt+'</td><td>'+obj.status+
'</td><td>'+obj.supplyBatch.supplyBatchId+'</td><td>'+obj.supplyBatch.farmer.name+'</td><td>'+obj.feedType+'</td><td>'+obj.quantity+'</td>'+act+'</tr>');
}
}
});
return false;
}
Related
I have a method that receives an object of type IFormCollection because I need to process files.
[HttpPost]
[AllowAnonymous]
[Route("StoreData")]
public async Task<IActionResult> StoreDataX(IFormCollection obj)
{
var item = FormCollectionToJson(obj);
var id = this.Service.SaveDynamicData(item, "");
return StatusCode(200, JObject.FromObject(new
{
message = "Registration included and workflow started."
}));
}
I convert the IFormCollection keys to a JObject
private JObject FormCollectionToJson(IFormCollection obj)
{
dynamic json = new JObject();
if (obj.Keys.Any())
{
foreach (string key in obj.Keys)
{
var value = obj[key][0];
json.Add(key, value);
}
}
return json;
}
But I am not able to do the conversion when I receive an array, how could I handle this type of data?
[Postman Request]
return of FormCollectionToJson
{
"companies[0]": "1-1"
}
Expected return
{
"companies": [
"1-1"
]
}
Where am I going wrong? How to process the array or how to send it?
If you want to store array in the JObject, you could use the JArray Class to represent a Json array.
Please refer to the following code:
[HttpPost]
public async Task<IActionResult> Post(IFormCollection obj)
{
var item = FormCollectionToJson(obj);
return StatusCode(200, JObject.FromObject(new
{
message = "Registration included and workflow started."
}));
}
private JObject FormCollectionToJson(IFormCollection obj)
{
dynamic json = new JObject();
if (obj.Keys.Any())
{
foreach (string key in obj.Keys)
{ //check if the value is an array
if (obj[key].Count > 1)
{
JArray array = new JArray();
for (int i = 0; i < obj[key].Count; i++)
{
array.Add(obj[key][i]);
}
json.Add(key, array);
}
else
{
var value = obj[key][0];
json.Add(key, value);
}
}
}
return json;
}
The test result as below:
I am calling and displaying a java web service using ASP.NET Web API. How do i make it such that when i run my ASP.NET Web API, the page shows JSON data instead of HTML?
Here are my codes:
DemoRestfulClient.cs
public class DemoRestfulClient
{
private string BASE_URL = "http://localhost:8080/";
public Task<string> AdditionJava2()
{
{
try
{
var client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("AdditionJava2").Result;
return response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
HttpContext.Current.Server.Transfer("ErrorPage.html");
}
return null;
}
}
}
DemoController.cs
public class DemoController : Controller
{
private DemoRestfulClient demoRestfulClient = new DemoRestfulClient();
public ActionResult Index()
{
var Result1 = demoRestfulClient.AdditionJava2().Result;
return Content(Result1);
}
}
Someone please help me. Thank you so much in advance.
public class DemoController : Controller
{
private DemoRestfulClient demoRestfulClient = new DemoRestfulClient();
public ActionResult Index()
{
var Result1 = demoRestfulClient.AdditionJava2().Result;
return Json(Result1);
}
}
The above method will return a json object .
You have wanted to get the json object, right? :)
You have to parse the Json object in order to separately view the content in json.
By using ajax, you can get the content of the json object separately.
For an example,
$.ajax({
url: $("#head").val() + "/Template/updatedTmpltView",
dataType: "html",
data: {},
type: "POST",
success: function (msg) {
data = $.parseJSON(msg)
var name = data.FieldName;
var type = data.FieldType;
var id = data.FieldId;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
In the success (msg), you get the json object as **msg**.
data will include the parsed json object and you can obtain necessary data by data.yourFieldName
Hope this helped you! :)
I want to access a JSON of this structure in firebase
The structure
{
"questions":{
"English":{
"English_2002":[
{
"correct_ans":"A",
"OptionA":"a coder",
"OptionB":"a hacker",
"OptionC":"a writer",
"OptionD":"a programmer",
"Question":"Who build software"
},
{},
{}
],
"English_2003":[],
}
}
}
I want this structure. In the subject structure, other subjects will come after I exhaust 9 years of English.
My confusion is how to logically get each subject since firebase will only accept the root name questions.
Please I may sound dumb, but I have a very long questions thread almost 55000 lines. Because firebase accept one JSON tree.
Sorry i wasn't very clear i was asking from the stack phone app:
I have a question json tag of the structure above; my question is how will i be able to access the object subject like "english":{
// then accessing the first english array "english":[]
//since am now using firebase.
}
initially each array was individual json file, i have to recreate them into one for firebase sake. this is how i was parsing it then.
public class QuestionParser {
Context context;
public QuestionParser(Context c) {
this.context = c;
}
public ArrayList<Question> getJsonFromUrl(String url, String arrayName)
{
ArrayList<Question> arrayofQuestion = new ArrayList<>();
return arrayofQuestion;
}
// Processing question from JSon file in res > raw folder
public ArrayList<Question> parseQuestionJson(int rawJsonFileId, String arrayName) {
ArrayList<Question> questionList = new ArrayList<>();
String jsonstr = null;
try {
InputStream in = context.getResources().openRawResource(rawJsonFileId);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
jsonstr = sb.toString();
Log.d("REEEEADDD" + this.toString(), jsonstr);
//System.out.println(jsonstr);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(jsonstr)) {
return null;
}
try {
JSONObject jsonObject = new JSONObject(jsonstr);
JSONArray jsonArray = jsonObject.getJSONArray(arrayName);
JSONObject jobject;
for (int i = 0; i < jsonArray.length(); i++) {
// TEST
jobject = jsonArray.getJSONObject(i);
String ans = jobject.getString("correct_answer");
String graphic_name = jobject.getString("question_image");
String optionA = jobject.getString("optiona");
String optionB = jobject.getString("optionb");
String optionC = jobject.getString("optionc");
String optionD = jobject.getString("optiond");
String questionNo = jobject.getString("question_number");
String question = jobject.getString("question");
questionList.add(new Question(questionNo, graphic_name, question, optionA, optionB, optionC, optionD, ans));
Log.d("DDD" + this.toString(), String.valueOf(questionList.get(i)));
}
Log.i("ONE QUESTION", questionList.get(50).getQuestion());
} catch (Exception e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
return questionList;
}
}
So how can i parse it from firebase because initially, if a student chooses question and year i passes those value as parameter and use them for parsing. but in firebase now i have access to only root firebase name in the get reference e method
To access for example "correct_ans":"A" you would query your firebase like so:
your.firebase.domain/questions/English/English_2002/0/correct_ans
Notice that each level in the json object is represented by a / and the key you want to access whereas in case of an array you simple add the array index. JSON's simple structure also allows simple REST like access
I have a async method in a pcl:
public async Task<T> Get<T>(string method) where T : EntityBase
{
try
{
Log.Info($"RequestURL {_client.BaseAddress}{method}");
var response = await _client.GetAsync(method);
var content = await response.Content.ReadAsStringAsync();
if (response.StatusCode != HttpStatusCode.OK)
{
return HandleResponse<T>(response); //this method just handles failures and logs the info in aspecial way
}
Log.Info($"Response {content}");
return JsonConvert.DeserializeObject<T>(content);
}
catch (Exception ex)
{
Log.Error($"Making api request to {method}. --- {ex.ToString()}");
return default(T);
}
}
my handleresponse method:
private T HandleResponse<T>(HttpResponseMessage responseMessage) where T : EntityBase
{
var resultType = RequestResultType.Success;
var message = "OK";
switch (responseMessage.StatusCode)
{
case HttpStatusCode.Unauthorized:
resultType = RequestResultType.Failure;
message = "Unauthorised";
break;
}
Log.Info($"StatusCode: {responseMessage.StatusCode}");
Log.Info($"ResultType: {resultType}");
Log.Info($"Message: {message}");
return (T)Activator.CreateInstance(typeof(T), resultType, message);
}
The object represented in T above:
public class TaskItemList: EntitBase
{
public List<TaskItem> Tasks { get; set; }
}
The problem I have, is that this same method, when called, randomly returns T as null. Sometimes T is partially populated, with some of the properties being null
When i call the API via the browser, there is always a value.
I suspect that the response content is not yet completely formed by the time json is trying to deserialize it, but how does one handle this?
I'm having problems when I try to deserialize json into a object in MVC4.
I have a Viewmodel:
public class TestViewModel
{
public string Code { get; set; }
}
On the view I get the model and serialize the object using Json.net
var Vm = function(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.GetResults = function() {
$.ajax({
type: "POST",
url: '#Url.Action("Action", "Controller")',
data: ko.mapping.toJSON(self),
success: function(data) {
alert('OK');
}
});
};
};
var viewModel = new Vm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
ko.applyBindings(viewModel);
My problem is when I call GetResults the action in the controller, all properties are null.
My Json is:
{"Code":"TestCode"}
I have the same structure in a MVC3 project and works fine. I'm missing something in MVC4?
Cheers!
We've noticed that in some scenarios jQuery will embed the data in a Form in the Request. When this happens, the values are not automatically mapped to the object type in the Controller method.
To get around this, you need to do two things:
1) Check to see if the data is serialized. I found an easy way to do this and dumped it in an extension method:
public static class WebContextExtensions
{
public static bool IsDataSerialized(this HttpContext context)
{
return context.Request.Params.AllKeys[0] == null;
}
}
2) IF IsDataSerialized returns true, you need to deserialize the data into your object type. We wrote a GenericDeserializer method to do that as well:
public class GenericContextDeserializer<T> where T : new()
{
public T DeserializeToType(HttpContext context)
{
T result = new T();
if (context != null)
{
try
{
string jsonString = context.Request.Form.GetValues(0)[0].ToString();
Newtonsoft.Json.JsonSerializer js = new Newtonsoft.Json.JsonSerializer();
result = js.Deserialize<T>(new Newtonsoft.Json.JsonTextReader(
new System.IO.StringReader(jsonString)));
}
catch (Exception ex)
{
throw ex;
}
}
else
throw new NullReferenceException();
return result;
}
}
Now put it all together in your Controller method:
[HttpPost]
[HttpOptions]
public HttpResponseMessage MyAction(JsonData data)
{
var results = Request.CreateResponse();
try
{
data = new GenericContextDeserializer<JsonData>().DeserializeToType(HttpContext.Current);
// do stuff with data
results.StatusCode = HttpStatusCode.OK;
}
catch (Exception ex)
{
results.StatusCode = HttpStatusCode.InternalServerError;
}
return results;
}
If you want more detail, it's in the second half of a blog post I wrote.