send custom error status code with JArray - json

I have webapi, that return JArray.
There is any way to send response with some status code that I pick (like 422, 4XX )?
//GET api/UserControl/GetUserName
public JArray GetUserName()
{
JArray json = new JArray();
try
{
string UserID= getUserID();
if (!string.IsNullOrEmpty(UserID) || UserID== "None Was found")
{
var result = JsonConvert.SerializeObject(donorRep.GetUserFullName(UserID), Formatting.None,
new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
try
{
json = JArray.Parse(result);
}
catch
{
json.Add(result.ToString());
}
}
else
{
json.Add("There was an issue while retrieving your UserID.");
}
}
catch (JsonSerializationException ex)
{
json.Add("There was an issue while retrieving your IDSID. Please contact support");
}
return json;
}
for example if there is an error here than in the UI :
json.Add("There was an issue while retrieving your UserID");

Wrap your array inside a JSON object, then add additional properties for the status code and any other "meta" information you might need. For example, you might try to make the JSON response look something like this:
{
"statusCode" : 422
"errorMessage" : "Error message, if any, goes here."
"results" : [
"item 1",
"item 2",
"etc.",
"you can also use objects here instead of strings if your data is more complex"
]
}
Then make your code something like this:
// GET api/UserControl/GetUserName
public JObject GetUserName()
{
JArray resultArray = new JArray();
int statusCode = 200; // success
string errorMessage = null;
try
{
string UserID= getUserID();
if (!string.IsNullOrEmpty(UserID))
{
var fullName = donorRep.GetUserFullName(UserID);
resultArray.Add(fullName);
}
else
{
statusCode = 421; // error
errorMessage = "There was an issue while retrieving your UserID.";
}
}
catch (Exception ex)
{
statusCode = 422; // error
errorMessage = "There was an issue while retrieving your IDSID. Please contact support.";
}
JObject response = new JObject();
response.Add("statusCode", statusCode);
response.Add("errorMessage", errorMessage);
response.Add("results", resultArray);
return response;
}
You'll have to adjust your client side code to be able to extract the parts of the response. If you're using jQuery, for example, you could get the data something like this:
$.get("/api/UserControl/GetUserName")
.done(function(data) {
var statusCode = data.statusCode;
if (statusCode == 200) {
var userName = data.results[0];
alert("Success! User name is " + userName);
}
else {
alert("Failed with code " + statusCode + ". message: " + data.errorMessage);
}
});
For sake of completeness I should also mention that in Web API you don't have to manually build the JSON using JObjects, JArrays, etc. As an alternative, you can use strongly-typed classes and return those from your methods directly, and Web API will serialize them to JSON for you. Of course the structure of the classes has to match the JSON you want to return. For example if you wanted to do that approach, you would define a class like this:
class ResponseData
{
public int statusCode { get; set; }
public string errorCode { get; set; }
public List<string> results { get; set; }
public ResponseData()
{
results = new List<string>();
}
}
Then you can do:
public ResponseData GetUserName()
{
ResponseData response = new ResponseData { statusCode = 200 };
try
{
string userID = getUserID();
if (!string.IsNullOrEmpty(UserID))
{
var fullName = donorRep.GetUserFullName(UserID);
response.results.Add(fullName);
}
else
{
response.statusCode = 421; // error
response.errorMessage = "There was an issue while retrieving your UserID.";
}
}
catch (Exception ex)
{
response.statusCode = 422; // error
response.errorMessage = "There was an issue while retrieving your IDSID. Please contact support.";
}
return response;
}

Related

NewtonSoft.Json Treating Blank Value as Null but not throwing error

Environment
.net 7
Using Both System.Text.Json
Also NewtonSoft.Json ( 13.0.2)
Example code
string str = #"{
""DateTimeNull"":""""
}";
try
{
var t = System.Text.Json.JsonSerializer.Deserialize<Test>(str);
}
catch (JsonException ex)
{
Console.WriteLine(new { Field = ex.Path , Message = ex.Message });
}
try
{
var t = Newtonsoft.Json.JsonConvert.DeserializeObject<Test>(str);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
public class Test
{
public DateTime? DateTimeNull { get; set; }
}
In above System.Text.Json Deserlizer throw exception but newtonsoft.json line is not throwing any exception. It is converting empty value to null but I want it should thow error and due to limitation I can not move to System.Text.Json as of now.
Payload ( This is i already set in str)
Sample one
#"{
""DateTimeNull"":""""
}";
Expected result: Throw error and should not convert to null.
Sample two.
#"{
""DateTimeNull"": null
}";
Expected result: Should not throw error and it is null value and destination type is null.
I usually recommend to use a JsonConstructor:
var json = #"{
""DateTimeNull"":""""
}";
Test test = JsonConvert.DeserializeObject<Test>(json);
public class Test
{
public DateTime? DateTimeNull { get; set; }
[Newtonsoft.Json.JsonConstructor]
public Test(JToken DateTimeNull)
{
if (DateTimeNull.Type == JTokenType.Null) this.DateTimeNull = null;
else if ((string)DateTimeNull == string.Empty)
throw new JsonException("DateTimeNull property should not be an empty string");
else this.DateTimeNull = DateTimeNull.ToObject<DateTime>();
}
}

Severity Code Description Project File Line Supcannot convert from 'System.Web.Mvc.JsonRequestBehavior' to 'Newtonsoft.Json.JsonSerializerSettings'

cannot convert from 'System.Web.Mvc.JsonRequestBehavior' to 'Newtonsoft.Json.JsonSerializerSettings'
code
public JsonResult Get()
{
try
{
using (smartpondEntities DB = new smartpondEntities())
{
var pond = DB.Temperatures.OrderByDescending(x => x.WaterTemperature).FirstOrDefault();
return Json(new { success = true, sensorsdata = new { id = pond.WaterTemperature, CurrentTime = pond.CreatedDate } }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception Ex)
{
}
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
The second parameter for Json method in Web API controller is incorrectly assigned, since ApiController Json method requires JsonSerializerSettings as second argument:
protected internal JsonResult<T> Json<T>(T content, JsonSerializerSettings serializerSettings)
{
......
}
The MVC controller counterpart for Json method is shown below:
protected internal JsonResult Json(object data, JsonRequestBehavior behavior)
{
......
}
In this case, if the controller class containing Get method above extends ApiController, you need to change 2 return Json statements to return new JsonResult as given below:
public class ControllerName : ApiController
{
public JsonResult Get()
{
try
{
using (smartpondEntities DB = new smartpondEntities())
{
var pond = DB.Temperatures.OrderByDescending(x => x.WaterTemperature).FirstOrDefault();
// return JsonResult here
return new JsonResult()
{
Data = new { success = true, sensorsdata = new { id = pond.WaterTemperature, CurrentTime = pond.CreatedDate }},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
catch (Exception Ex)
{
}
// return JsonResult here
return new JsonResult()
{
Data = new { success = false },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
If you want to use MVC controller when returning JSON instead, change ApiController to Controller class from System.Web.Mvc namespace and keep return Json(...) there.
Similar issue:
JSON return error with ASP

deserialize httpclient's content result yields intermittend null values

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?

org.json.JSONException: No value for name

What could be the reason of this error in the code below?
loginButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
final String e_mail = e_mailEditText.getText().toString();
final String password = passwordEditText.getText().toString();
// Response received from the server
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
boolean success = jsonResponse.getBoolean("success");
if (success) {
String name = jsonResponse.getString("name");
// int age = jsonResponse.getInt("age");
Intent intent = new Intent(login.this, Welcome.class);
intent.putExtra("name", name);
// intent.putExtra("age", age);
intent.putExtra("e_mail", e_mail);
login.this.startActivity(intent);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
builder.setMessage("Login Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
LoginRequest loginRequest = new LoginRequest(e_mail, password, responseListener);
RequestQueue queue = Volley.newRequestQueue(login.this);
queue.add(loginRequest);
}
});
Check if you have the key first:
if (jsonObject.has("name")) {
String name = jsonObject.getString("name");
}
For others users which have the org.json.JSONException: No value for //your parameter.
In this case you should check if the name is empty.
For example using method jsonResponse.optString("name").
Live example:
if (success) {
String name = jsonResponse.optString("name"); //will get name value or return empty String
if (!name.equals("")) {
//Your code if name is exist
Intent intent = new Intent(login.this, Welcome.class);
intent.putExtra("name", name);
intent.putExtra("e_mail", e_mail);
login.this.startActivity(intent);
} else {
//Your code if the name is empty
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
builder.setMessage("Login Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
Can't say for sure without knowing the context (or the line number of the exception), but my money would be on the call:
jsonResponse.getString("name")
Most likely, the JSON received from the server doesn't contain any name/value pairs with name name.

Json Parsing, need to get key name from response not key value

Json Response :
response :{"status":false,"Message":"Some DataBase Error"}
Requirement :
i want key name i.e. Message not value of Message
Code :
private final String KEY_MSG = "Message";
private final String KEY_MSG1 = "message";
try {
AppLog.Log("TAG123", response);
JSONObject jsonObject = new JSONObject(response);
String message1="Message";
if (message1.equals(jsonObject.getString(KEY_MSG)))
{
AppLog.Log("fgesarfefe", "dsfdsfdsfds");
return jsonObject.getString(KEY_MSG);
}
else
{
AppLog.Log("00000000", "111111");
return jsonObject.getString(KEY_MSG1);
}
/* if (jsonObject.getString(KEY_MSG).equals("message"))
{
return jsonObject.getString(KEY_MSG1);
}
else
{*/
// return jsonObject.getString(KEY_MSG);
// }
} catch (JSONException e) {
e.printStackTrace();
}
return "No data";
You can use JSONObject.keySet() method to get the set of keys on that object. In your case, it should return "status" and "Message".
In case you want to get individual key, you can iterate using :
for (String jsonKey : jsonObject.keySet()) {
// Check each key here, jsonKey value will be "status" and "Message"
}
Hope this helps, good luck