I'm having an issue with JSON and JSP. My Java code creates a JSON from a map, like this:
#RequestMapping(value = "/internationalWAExpose", method = RequestMethod.GET)
#ResponseBody
public String exposeWAData(final HttpServletRequest request) {
Map<String, WebAnalyticsDataValue> ajaxDataMap = new HashMap<>();
WAGlobalDataHandler globalHandler = WebAnalyticsFactory.getHandler(WAGlobalDataHandler.class);
globalHandler.setGlobalData(request, "Home", "Content");
ajaxDataMap.putAll(globalHandler.getDataMap());
JSONObject json = new JSONObject();
ajaxDataMap.forEach((k, v) -> {
try {
json.put(k, v);
} catch (JSONException e) {
e.printStackTrace();
}
});
return json.toString();
}
And I need to get the JSON on a JSP to be exposed in the elements section.
So far, I managed to set it in a JS with an Ajax call, but it shows on the console, rather than in the elements section.
AAUI.ajaxRequest({
url: '/home/ajax/internationalWAExpose',
type: 'GET',
dataType: 'json',
timeout: 50000,
onSuccess: function onSuccess(jsonResponse, textStatus) {
var webAnalyticsData = [];
for (var x in jsonResponse) {
webAnalyticsData.push(new KeyValueObject(x, jsonResponse[x]));
}
waTealiumUtils.reportEvent(webAnalyticsData, "view");
},
onError: function onError() {
},
onComplete: function onComplete() {
}
})
Any ideas? Be advised, I'm quite a newbie to JS and JSP.
Related
I have a simple function that searches for item I want in my database and retrieves it in my controller.
[HttpPost]
public ActionResult Index(string searchString)
{
var user = from m in db.Users select m;
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.UserName.Contains(searchString));
}
return View(user);
}
And then in my Javascript I send a value to search:
$('#test').click(function(e) {
e.preventDefault();
var user = "John";
$.ajax({
url: "#Url.Action("Index", "Users")",
data { "searchString": user },
type: "post",
success: function (saveResult) {
console.log(saveResult);
},
error: function(xhr, ajaxOptions, thrownError) {
console.log(xhr, ajaxOptions, thrownError);
}
})
})
However of course all this does it return my view inside the console window which is something like:
But I would like to return a json object I can use.
just use the Json Action method.
return Json(user);
Edit:
As a side note, I would also set my return Type to be JsonResult for clarity
You just return as JsonResult such as below:
public ActionResult SomeActionMethod() {
return Json(new {foo="bar", baz="Blech"});
}
I have a problem with JSON and JQUERY. In my web application I submit some data (through an $.ajax call) to a servlet and want to receive back some informations from this servlet once it has done.
I'm using JSONObject in this way:
function check(){
$.ajax({
url: "/check",
type: "POST",
dataType: "json",
success: on_check_ok,
error: function(){
alert("something wrong happened");
},
data: {
players_code: $("#players_code").val(),
},
});
return false;
}
function on_check_ok(data) {
var json = data;
$("#display").text(json.check); //"display" is a <div> into index.html
};
and this is doPost() method in my servlet code:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
String code_array = request.getParameter("players_code");
System.out.println("Player's code is: " + code_array);
int arr = Integer.parseInt(code_array);
LinkedList<Integer> stack = new LinkedList<Integer>();
while(arr > 0){
stack.push(arr%10);
arr = arr/10;
}
int index = 0;
while(!stack.isEmpty()){
array[index] = (int)stack.pop();
index++;
}
mm.checkGuess(array);
response.getWriter().write(mm.ris + " ");
tries++;
System.out.println("TRIES: " + tries);
JSONObject obj = new JSONObject();
obj.put("check", tries);
String json = obj.toString();
out.write(json);
System.out.println("JSON " + json);
}
}
but cannot get displayed any information. Seems that JSONObject has been created correctly, since I can display it on console. I'm having hard times on getting this data back to javascripts.
That's my code, what I'm doing wrong? Or, is there an alternative way to get the same result? thanks for the help!
I'm working on Asp.net MVC project as a single page application for error handling. I want to return json data from Application_Error method in global.asax to UI and show it by jQuery or call a controller and return partialView.
I don't want to refresh the page or redirect it to Error page.
here is the way to go
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
// if the error is NOT http error, then stop handling it.
if (!(exception is HttpException httpException))
return;
if (new HttpRequestWrapper(Request).IsAjaxRequest())
{
Response.Clear();
Response.TrySkipIisCustomErrors = true;
Server.ClearError();
Response.ContentType = "application/json";
Response.StatusCode = 400;
JsonResult json = new JsonResult
{
Data = exception.Message
};
json.ExecuteResult(new ControllerContext(Request.RequestContext, new BaseController()));
}
}
//Write This code into your global.asax file
protected void Application_Error(Object sender, EventArgs e)
{
var ex = Server.GetLastError();
//We check if we have an AJAX request and return JSON in this case
if (IsAjaxRequest())
{
Response.Write(JsonConvert.SerializeObject(new
{
error = true,
message = "Exception: " + ex.Message
})
);
}
}
private bool IsAjaxRequest()
{
//The easy way
bool isAjaxRequest = (Request["X-Requested-With"] == "XMLHttpRequest")
|| ((Request.Headers != null)
&& (Request.Headers["X-Requested-With"] == "XMLHttpRequest"));
//If we are not sure that we have an AJAX request or that we have to return JSON
//we fall back to Reflection
if (!isAjaxRequest)
{
try
{
//The controller and action
string controllerName = Request.RequestContext.
RouteData.Values["controller"].ToString();
string actionName = Request.RequestContext.
RouteData.Values["action"].ToString();
//We create a controller instance
DefaultControllerFactory controllerFactory = new DefaultControllerFactory();
Controller controller = controllerFactory.CreateController(
Request.RequestContext, controllerName) as Controller;
//We get the controller actions
ReflectedControllerDescriptor controllerDescriptor =
new ReflectedControllerDescriptor(controller.GetType());
ActionDescriptor[] controllerActions =
controllerDescriptor.GetCanonicalActions();
//We search for our action
foreach (ReflectedActionDescriptor actionDescriptor in controllerActions)
{
if (actionDescriptor.ActionName.ToUpper().Equals(actionName.ToUpper()))
{
//If the action returns JsonResult then we have an AJAX request
if (actionDescriptor.MethodInfo.ReturnType
.Equals(typeof(JsonResult)))
return true;
}
}
}
catch
{
}
}
return isAjaxRequest;
}
//Write this code in your ajax function in html file
<script type="text/javascript">
$.ajax({
url: Url
type: 'POST',
data: JSON.stringify(json_data),
dataType: 'json',
cache: false,
contentType: 'application/json',
success: function (data) { Successfunction(data); },
error: function (xhr, ajaxOptions, thrownError) {
var obj = JSON.parse(xhr.responseText);
if (obj.error) {
show_errorMsg(obj.message);
}
}
});
</script>
How do I handle exceptions thrown in a controller when jquery ajax calls an action?
For example, I would like a global javascript code that gets executed on any kind of server exception during an ajax call which displays the exception message if in debug mode or just a normal error message.
On the client side, I will call a function on the ajax error.
On the server side, Do I need to write a custom actionfilter?
If the server sends some status code different than 200, the error callback is executed:
$.ajax({
url: '/foo',
success: function(result) {
alert('yeap');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
and to register a global error handler you could use the $.ajaxSetup() method:
$.ajaxSetup({
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
Another way is to use JSON. So you could write a custom action filter on the server which catches exception and transforms them into JSON response:
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
and then decorate your controller action with this attribute:
[MyErrorHandler]
public ActionResult Foo(string id)
{
if (string.IsNullOrEmpty(id))
{
throw new Exception("oh no");
}
return Json(new { success = true });
}
and finally invoke it:
$.getJSON('/home/foo', { id: null }, function (result) {
if (!result.success) {
alert(result.error);
} else {
// handle the success
}
});
After googling I write a simple Exception handing based on MVC Action Filter:
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
filterContext.Exception.StackTrace
}
};
filterContext.ExceptionHandled = true;
}
else
{
base.OnException(filterContext);
}
}
}
and write in global.ascx:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleExceptionAttribute());
}
and then write this script on the layout or Master page:
<script type="text/javascript">
$(document).ajaxError(function (e, jqxhr, settings, exception) {
e.stopPropagation();
if (jqxhr != null)
alert(jqxhr.responseText);
});
</script>
Finally you should turn on custom error.
and then enjoy it :)
Unfortunately, neither of answers are good for me. Surprisingly the solution is much simpler. Return from controller:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
And handle it as standard HTTP error on client as you like.
I did a quick solution because I was short of time and it worked ok. Although I think the better option is use an Exception Filter, maybe my solution can help in the case that a simple solution is needed.
I did the following. In the controller method I returned a JsonResult with a property "Success" inside the Data:
[HttpPut]
public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave)
{
if (!ModelState.IsValid)
{
return new JsonResult
{
Data = new { ErrorMessage = "Model is not valid", Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
try
{
MyDbContext db = new MyDbContext();
db.Entry(employeToSave).State = EntityState.Modified;
db.SaveChanges();
DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];
if (employeToSave.Id == user.Id)
{
user.Company = employeToSave.Company;
user.Language = employeToSave.Language;
user.Money = employeToSave.Money;
user.CostCenter = employeToSave.CostCenter;
Session["EmployeLoggin"] = user;
}
}
catch (Exception ex)
{
return new JsonResult
{
Data = new { ErrorMessage = ex.Message, Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
return new JsonResult() { Data = new { Success = true }, };
}
Later in the ajax call I just asked for this property to know if I had an exception:
$.ajax({
url: 'UpdateEmployeeConfig',
type: 'PUT',
data: JSON.stringify(EmployeConfig),
contentType: "application/json;charset=utf-8",
success: function (data) {
if (data.Success) {
//This is for the example. Please do something prettier for the user, :)
alert('All was really ok');
}
else {
alert('Oups.. we had errors: ' + data.ErrorMessage);
}
},
error: function (request, status, error) {
alert('oh, errors here. The call to the server is not working.')
}
});
Hope this helps. Happy code! :P
In agreement with aleho's response here's a complete example. It works like a charm and is super simple.
Controller code
[HttpGet]
public async Task<ActionResult> ChildItems()
{
var client = TranslationDataHttpClient.GetClient();
HttpResponseMessage response = await client.GetAsync("childItems);
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content);
return Json(content, JsonRequestBehavior.AllowGet);
}
else
{
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
}
}
Javascript code in the view
var url = '#Html.Raw(#Url.Action("ChildItems", "WorkflowItemModal")';
$.ajax({
type: "GET",
dataType: "json",
url: url,
contentType: "application/json; charset=utf-8",
success: function (data) {
// Do something with the returned data
},
error: function (xhr, status, error) {
// Handle the error.
}
});
Hope this helps someone else!
For handling errors from ajax calls on the client side, you assign a function to the error option of the ajax call.
To set a default globally, you can use the function described here:
http://api.jquery.com/jQuery.ajaxSetup.
I have the following jQuery code in a View in MVC3. I want to load a partial view (named OffshoreECore) in a div (#Form) depending on the JSON object passed in the success function. Here's the code:
var inputParamtrs = { 'HeadId': $('#ExpenseId').val(), MProjid': $('#MProjid').val() };
$.ajax({
type: "POST",
url: "/Expenses/Edit",
data: inputParamtrs,
success: function (json) {
('#Form').load('#Url.Action("OffShoreECore", *What comes here ?!?*)');
}
Thanks.
The second parameter of load() is the data which should be sent to the specified URL along with the request. To send your JSON string, try this:
success: function (json) {
$('#Form').load('#Url.Action("OffShoreECore")', json);
}
You example code is also missing a ' delimiter from the second key in inputParamtrs and the $ from the selector in success, but I guess they're just typos.
$.getJSON("/Expenses/Edit",
{
HeadId: $('#ExpenseId').val(),
MProjid: $('#MProjid').val()
},
function (data) {
elementForResult.innerHTML = data;
});
In Controller:
public JsonResult Edit(int HeadId, int MProjid)
{
...
var result = SerializeControl("~/Views/Expenses/Edit.cshtml", null);
return Json(result, JsonRequestBehavior.AllowGet);
}
private string SerializeControl(string controlPath, object model)
{
var control = new RazorView(ControllerContext, controlPath, null, false, null);
ViewData.Model = model;
var writer = new HtmlTextWriter(new StringWriter());
control.Render(new ViewContext(ControllerContext, control, ViewData, TempData, writer), writer);
string value = writer.InnerWriter.ToString();
return value;
}