org.json.JSONException: No value for name - json

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.

Related

Increasing maxjsonlength on MVC post from Javascript

I have a controller action Export which accepts a List of models like below. This is sending back and manipulated dataset back from the view where the user could interact with it. So we have been able to send the data down with much more information.
[HttpPost]
public JsonResult Export(List<MappingExportModel> sources){}
This works fine in all cases but there is one where we have a bigger than normal dataset. This is causing an issue with the export. So far I have tried just passing the values as an object or string but I am unable to convert them into any usable instance after the data is into the controller.
Is it possible to preemptively increase this maxjsonlength value somewhere. The value from the web.config is being ignored from what I have come across so far.
The error I receive is
"Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property"
I need to be able to accept this directly from the ajax request into the controller action. Spinning up a version of JsonResult and then setting the max value will not work because the error is thrown the the data is trying to be deserialized into the object var presented above. We get the value in the original GET request and do set the value before the view is loaded. Now we are taking the data from this view and sending it back plus all the manipulations the users have created.
User posts data to server, the controller action is hit with the data. The error is encountered and spit back out to the browser which handles the error.
You can use custom json length. add the following file in your project and edit your global.asax.cs
Global.asax
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
///// **********
JsonValueProviderFactory jsonValueProviderFactory = null;
foreach (var factory in ValueProviderFactories.Factories)
{
if (factory is JsonValueProviderFactory)
{
jsonValueProviderFactory = factory as JsonValueProviderFactory;
}
}
//remove the default JsonVAlueProviderFactory
if (jsonValueProviderFactory != null) ValueProviderFactories.Factories.Remove(jsonValueProviderFactory);
//add the custom one
ValueProviderFactories.Factories.Add(new CustomJsonValueProviderFactory());
/////*************
}
}
///******** for json length
public sealed class CustomJsonValueProviderFactory : ValueProviderFactory
{
private static void AddToBackingStore(Dictionary<string, object> backingStore, string prefix, object value)
{
IDictionary<string, object> d = value as IDictionary<string, object>;
if (d != null)
{
foreach (KeyValuePair<string, object> entry in d)
{
AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);
}
return;
}
IList l = value as IList;
if (l != null)
{
for (int i = 0; i < l.Count; i++)
{
AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);
}
return;
}
// primitive
backingStore[prefix] = value;
}
private static object GetDeserializedObject(ControllerContext controllerContext)
{
if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
// not JSON request
return null;
}
StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
string bodyText = reader.ReadToEnd();
if (String.IsNullOrEmpty(bodyText))
{
// no JSON data
return null;
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = int.MaxValue; //increase MaxJsonLength. This could be read in from the web.config if you prefer
object jsonData = serializer.DeserializeObject(bodyText);
return jsonData;
}
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
object jsonData = GetDeserializedObject(controllerContext);
if (jsonData == null)
{
return null;
}
Dictionary<string, object> backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
AddToBackingStore(backingStore, String.Empty, jsonData);
return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
}
private static string MakeArrayKey(string prefix, int index)
{
return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
}
private static string MakePropertyKey(string prefix, string propertyName)
{
return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName;
}
}
JsonValueProviderFactory.cs
public sealed class JsonValueProviderFactory : ValueProviderFactory
{
private static void AddToBackingStore(Dictionary<string, object> backingStore, string prefix, object value)
{
IDictionary<string, object> d = value as IDictionary<string, object>;
if (d != null)
{
foreach (KeyValuePair<string, object> entry in d)
{
AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);
}
return;
}
IList l = value as IList;
if (l != null)
{
for (int i = 0; i < l.Count; i++)
{
AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);
}
return;
}
// primitive
backingStore[prefix] = value;
}
private static object GetDeserializedObject(ControllerContext controllerContext)
{
if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
// not JSON request
return null;
}
StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
string bodyText = reader.ReadToEnd();
if (String.IsNullOrEmpty(bodyText))
{
// no JSON data
return null;
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = int.MaxValue; //increase MaxJsonLength. This could be read in from the web.config if you prefer
object jsonData = serializer.DeserializeObject(bodyText);
return jsonData;
}
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
object jsonData = GetDeserializedObject(controllerContext);
if (jsonData == null)
{
return null;
}
Dictionary<string, object> backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
AddToBackingStore(backingStore, String.Empty, jsonData);
return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
}
private static string MakeArrayKey(string prefix, int index)
{
return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
}
private static string MakePropertyKey(string prefix, string propertyName)
{
return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName;
}
}
by this you can pass lengthy json through ajax to controller and if you want to retrieve a lengthy string back to ajax result from controller then add below code in your controller also
//add this for getting large json string
protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
{
return new JsonResult()
{
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior,
MaxJsonLength = Int32.MaxValue
};
}

send custom error status code with JArray

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;
}

Webapi custom JsonMediaTypeFormatter

I am trying to create a custom JSONMediaTypeFormatter in which posts some json parameters to a webapi call. I need to encrypt the returned data from the webapi, hence writing a custom mediatypeformatter.
In my webapiconfig I clear all formatters and only add the custom formatter.
config.Formatters.Clear();
config.Formatters.Add(new CipherMediaFormatter());
In my custom media type formatter I add in the relevant headers and types but i still cant call my web api. It gives me an error
No MediaTypeFormatter is available to read an object of type 'Param' from content with media type 'application/json
The code for the mediatypeformatter
public class CipherMediaFormatter : JsonMediaTypeFormatter
{
private static Type _supportedType = typeof(object);
public CipherMediaFormatter()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var taskSource = new TaskCompletionSource<object>();
try
{
var ms = new MemoryStream();
readStream.CopyTo(ms);
taskSource.SetResult(ms.ToArray());
}
catch (Exception e)
{
taskSource.SetException(e);
}
return taskSource.Task;
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var taskSource = new TaskCompletionSource<object>();
try
{
if (value != null)
{
var jsonData = JsonConvert.SerializeObject(value);
ICryptographicService cgService = new CryptographicService();
string apiKey = string.Empty;
string pattern = #"api\/(.*)?\/(\d+)?";
var match = Regex.Match(HttpContext.Current.Request.RawUrl, pattern);
....
}
}
catch (Exception e)
{
taskSource.SetException(e);
}
return taskSource.Task;
}
}
The problem was ReadFromStreamAsync causing the mediatypeformatter to error.

Unable to populate data in option field of jtable

I have a jsp page in which i have implemented J-Table. I have a field in jtable called ClassID which i want to make as dropdown. So how am i trying to do it as :
$('#UserTableContainer').jtable({
title : 'Table of Users',
actions : {
listAction : 'CRUDController?action=list',
fields : {
ClassID : {
title : 'ClassID',
list : true,
width : '50%',
edit : true,
option:'CRUDController?action=getClassID'
},
My Model i.e. the BEAN Class is :
private int id;
private String name;
private String classID;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassID() {
return classID;
}
public void setClassID(String classID) {
this.classID = classID;
}
When listAction : 'CRUDController?action=list' is called i get the populated data in jtable from servlet to the jsp
But when control comes to this line : option:'CRUDController?action=getClassID' , It goes to the dopost method of servlet class, searches the action=getClassID and then creates the jsonArray. But when the control comes back to the jsp page, it is unable to populate the dropdown in the JTable
My servlet code is :
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getParameter("action") != null) {
List<UserModel> lstUser = new ArrayList<UserModel>();
String action = (String) request.getParameter("action");
Gson gson = new Gson();
response.setContentType("application/json");
if (action.equals("list")) {
try {
// Fetch Data from User Table
lstUser = daoForMat.getAllUserList();
// Convert Java Object to Json
JsonElement element = gson.toJsonTree(lstUser, new TypeToken<List<UserModel>>() {
}.getType());
JsonArray jsonArray = element.getAsJsonArray();
String listData = jsonArray.toString();
// Return Json in the format required by jTable plugin
listData = "{\"Result\":\"OK\",\"Records\":" + listData + "}";
response.getWriter().print(listData);
} catch (Exception ex) {
String error = "{\"Result\":\"ERROR\",\"Message\":" + ex.getMessage() + "}";
response.getWriter().print(error);
ex.printStackTrace();
}
else if(action.equals("getClassID") ){
System.out.println("I came to action getClassID");
List<String> lstClassID = new ArrayList<String>();
//Here i am able to get the List containing classID
lstClassID = GetClassList();
JsonElement element = gson.toJsonTree(lstClassID , new TypeToken<List<String>>() {
}.getType());
JsonArray jsonArray = element.getAsJsonArray();
String listData = jsonArray.toString();
// Return Json in the format required by jTable plugin
listData = "{\"Result\":\"OK\",\"Records\":" + listData + "}";
response.getWriter().print(listData );
//return jsonArray;
}
}
}
What am i doing wrong? I have written the same code for action.equals("getClassID") as that for if (action.equals("list")). **For the later condition i am able to populate the Jtable but for this condition - action.equals("getClassID") i am not able to populate the dropdown in JTable.
The only difference is when action=list i am writing a list of BEAN Class to the response. ie.List<UserModel> lstUser = new ArrayList<UserModel>(); as you can see in the servlet code
and when action=getClassID i am writing a list of String to the response i.e.List<String> lstClassID = new ArrayList<String>();
What should i write in option field of JTABLE in the jsp page so that i can populate the dropdown?** Looking forward to your solutions. Thanks in advance
Hey you can try this.
declare a field whch u gonna use as dropdown like this
Location:
{
title: 'Location',
width: '12%',
list: true,
options: '/JTablePractice.aspx/GetContinentalOptions',
},
and write this in your front end
public static object GetContinentalOptions()
{
using (var db = new ASPPracticesEntities1())
try
{
var numbers = db.Members.Select(c => new { DisplayText = c.Location, Value = c.Location }).ToList();
return new { Result = "OK", Options = numbers };
}
catch (Exception ex)
{
return new { Result = "ERROR", Message = ex.Message };
}
}
Donno how to write it in java but hopw it help u

Http Post with Blackberry 6.0 issue

I am trying to post some data to our webservice(written in c#) and get the response. The response is in JSON format.
I am using the Blackberry Code Sample which is BlockingSenderDestination Sample. When I request a page it returns with no problem. But when I send my data to our webservice it does not return anything.
The code part that I added is :
ByteMessage myMsg = bsd.createByteMessage();
//myMsg.setStringPayload("I love my BlackBerry device!");
myMsg.setMessageProperty("querytpe","myspecialkey");//here is my post data
myMsg.setMessageProperty("uname","myusername");
myMsg.setMessageProperty("pass","password");
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
// Send message and wait for response myMsg
response = bsd.sendReceive(myMsg);
What am i doing wrong? And what is the alternatives or more efficients way to do Post with Blackberry.
Regards.
Here is my whole code:
class BlockingSenderSample extends MainScreen implements FieldChangeListener {
ButtonField _btnBlock = new ButtonField(Field.FIELD_HCENTER);
private static UiApplication _app = UiApplication.getUiApplication();
private String _result;
public BlockingSenderSample()
{
_btnBlock.setChangeListener(this);
_btnBlock.setLabel("Fetch page");
add(_btnBlock);
}
public void fieldChanged(Field button, int unused)
{
if(button == _btnBlock)
{
Thread t = new Thread(new Runnable()
{
public void run()
{
Message response = null;
String uriStr = "http://192.168.1.250/mobileServiceOrjinal.aspx"; //our webservice address
//String uriStr = "http://www.blackberry.com";
BlockingSenderDestination bsd = null;
try
{
bsd = (BlockingSenderDestination)
DestinationFactory.getSenderDestination
("name", URI.create(uriStr));//name for context is name. is it true?
if(bsd == null)
{
bsd =
DestinationFactory.createBlockingSenderDestination
(new Context("ender"),
URI.create(uriStr)
);
}
//Dialog.inform( "1" );
ByteMessage myMsg = bsd.createByteMessage();
//myMsg.setStringPayload("I love my BlackBerry device!");
myMsg.setMessageProperty("querytpe","myspecialkey");//here is my post data
myMsg.setMessageProperty("uname","myusername");
myMsg.setMessageProperty("pass","password");
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
// Send message and wait for response myMsg
response = bsd.sendReceive(myMsg);
if(response != null)
{
BSDResponse(response);
}
}
catch(Exception e)
{
//Dialog.inform( "ex" );
// process the error
}
finally
{
if(bsd != null)
{
bsd.release();
}
}
}
});
t.start();
}
}
private void BSDResponse(Message msg)
{
if (msg instanceof ByteMessage)
{
ByteMessage reply = (ByteMessage) msg;
_result = (String) reply.getStringPayload();
} else if(msg instanceof StreamMessage)
{
StreamMessage reply = (StreamMessage) msg;
InputStream is = reply.getStreamPayload();
byte[] data = null;
try {
data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
} catch (IOException e) {
// process the error
}
if(data != null)
{
_result = new String(data);
}
}
_app.invokeLater(new Runnable() {
public void run() {
_app.pushScreen(new HTTPOutputScreen(_result));
}
});
}
}
..
class HTTPOutputScreen extends MainScreen
{
RichTextField _rtfOutput = new RichTextField();
public HTTPOutputScreen(String message)
{
_rtfOutput.setText("Retrieving data. Please wait...");
add(_rtfOutput);
showContents(message);
}
// After the data has been retrieved, display it
public void showContents(final String result)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
_rtfOutput.setText(result);
}
});
}
}
HttpMessage does not extend ByteMessage so when you do:
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
it throws a ClassCastException. Here's a rough outline of what I would do instead. Note that this is just example code, I'm ignoring exceptions and such.
//Note: the URL will need to be appended with appropriate connection settings
HttpConnection httpConn = (HttpConnection) Connector.open(url);
httpConn.setRequestMethod(HttpConnection.POST);
OutputStream out = httpConn.openOutputStream();
out.write(<YOUR DATA HERE>);
out.flush();
out.close();
InputStream in = httpConn.openInputStream();
//Read in the input stream if you want to get the response from the server
if(httpConn.getResponseCode() != HttpConnection.OK)
{
//Do error handling here.
}