I have the following chtml code to an action in a controller. The data is being sent by ajax to the action.
The chtml part:
<li>
<button id="abandon-popup" onclick="Transfer(#Model.Id)">
Transfer <i class="icon-arrow-right"></i>
</button>
</li>
The function Transfer:
function Transfer(modelId) {
//alert(modelId);
$.ajax({
type: "GET",
url: "/Internet/Transfer",
data: "id=" + modelId,
success: function (responsedata) {
alert("ok");
window.location.href = responsedata.newUrl;
},
error: function (data) {
console.log("KO");
}
})
}
The action in the controller:
public ActionResult Transfer(long id)
{
*some actions*
return Json(new { newUrl = PartialView("~/Views/Shared/Partials/Leads/_TransferPopup.cshtml", commonModel) });
}
However I am getting a 500 internal error on this:
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet
Any idea how to correct this?
Use this
return Json(new { newUrl = PartialView("~/Views/Shared/Partials/Leads/_TransferPopup.cshtml",
commonModel
)}, JsonRequestBehavior.AllowGet);
By default, the ASP.NET MVC framework does not allow you to respond to an HTTP GET request with a JSON payload. If you need to send JSON in response to a GET, you'll need to explicitly allow the behavior by using JsonRequestBehavior.AllowGet as the second parameter to the Json method. However, there is a chance a malicious user can gain access to the JSON payload through a process known as JSON Hijacking. You do not want to return sensitive information using JSON in a GET request.
Try this following:
return Json(new { newUrl = PartialView("~/Views/Shared/Partials/Leads/_TransferPopup.cshtml", commonModel) });
into
return Json(new { newUrl = PartialView("~/Views/Shared/Partials/Leads/_TransferPopup.cshtml", commonModel) }, JsonRequestBehavior.AllowGet);
Change GET method to POST method the following way:
Client side:
function Transfer(modelId) {
//alert(modelId);
$.ajax({
type: "POST",
url: "/Internet/Transfer",
data: {id: modelId},
success: function (responsedata) {
alert("ok");
window.location.href = responsedata.newUrl;
},
error: function (data) {
console.log("KO");
}
})
}
Controller side:
[HttpPost]
public ActionResult Transfer(long id)
{
*some actions*
return Json(new { newUrl = PartialView("~/Views/Shared/Partials/Leads/_TransferPopup.cshtml", commonModel) });
}
Related
I want to call a view with an ajax call on my current view. The following is my Ajax call that calls a function of my controller.
$.ajax({
type: 'POST',
url: '#Url.Action("EditCertificateObservation", "Frühwarnsystem")',
data: {
serverName: '#Model[0].ServerName',
name: event.data.name,
thumbprint: event.data.thumbprint,
expiringDateStr: event.data.expiringDate,
isChecked: document.getElementById(store + event.data.index).checked,
model: data,
},
});
This code is my controller function that returns a view to load.
[HttpPost]
public ActionResult EditCertificateObservation(string serverName, string name, string thumbprint, string expiringDateStr, bool isChecked, string model)
{
var newModel = JsonConvert.DeserializeObject<List<Store>>(model);
var cert = new Certificate(serverName, name, thumbprint, expiringDateStr);
var server = new Server(serverName);
server.FetchIdByServerName();
if (isChecked)
{
cert.AddToObservation(server.Id);
}
else
{
cert.DeleteFromObservation();
}
return View("Index");
}
To know for you: I call the ajax call with a checkbox on my view, which is dynamically generated. If I debug the controller function get called and runs but the browser doesn't load the view I return.
If you need more information, just ask here.
Thank you for your help
If you want to open a view with after Ajax request than you just have to wait for the response of your controller then you can use success, but you can also use failure or error depend on your need, so your Ajax will be like this:
$.ajax({
type: 'POST',
url: '#Url.Action("EditCertificateObservation", "Frühwarnsystem")',
data: {
serverName: '#Model[0].ServerName',
name: event.data.name,
thumbprint: event.data.thumbprint,
expiringDateStr: event.data.expiringDate,
isChecked: document.getElementById(store + event.data.index).checked,
model: data,
},
success: function (response) {
alert(response.message);
window.location.href = "/Frühwarnsystem/Index";
// or with some parameter
window.location.href ="/Frühwarnsystem/Index?id=" + response.counter;
// or if you prefer with helper ...
window.location.href = '#Url.Action("Frühwarnsystem","Index")';
},
failure: function (response) { alert("failure"); },
error: function (response) { alert("error"); }
});
And to be a little more useful, your controller can send a Json response with some parameter for example, as follow:
[HttpPost]
public JsonResult EditCertificateObservation(string serverName, string name, string thumbprint, string expiringDateStr, bool isChecked, string model)
{
var newModel = JsonConvert.DeserializeObject<List<Store>>(model);
var cert = new Certificate(serverName, name, thumbprint, expiringDateStr);
var server = new Server(serverName);
server.FetchIdByServerName();
if (isChecked)
{
cert.AddToObservation(server.Id);
}
else
{
cert.DeleteFromObservation();
}
// Do some condition here to send an answer ...
string message = "";
int counter = 0;
var response = new { counter, message };
return Json(response);
}
You are calling an ajax POST HTTP request. It means you can download the result of the call and assign it into a javascript variable. This result will not be displayed in the browser as a page. Take a look at examples of $.post here.
I have the following ajax call in my view:
var obj = { maintId: id };
$.ajax({
url: '#Url.Action("EditLog" ,"Maintenance")',
type: "GET",
dataType: "json",
data: obj,
async: false,
success: function (data) {
alert(data.Reason);
},
error: function (xhr, status, error) {
alert(xhr.responseText);
alert(status);
alert(error);
}
});
It hits the Action (EditLog) just fine but not able to return the values for SystemID and Reason to the ajax call success data area.
Note that I will be putting values from the DB but for testing, I put hard coded values for SystemID and Reason. When I run the code it goes to the error: function section and I get a parsererror. I am wondering if I am doing anything wrong.
[HttpGet]
public ActionResult EditLog(int maintId)
{
return Json(new { SystemID = 1233, Reason = "ReagDegree change" });
}
You need to use the JsonRequestBehavior.AllowGet as well:
return Json(new { SystemID = 1233, Reason = "ReagDegree change" }, JsonRequestBehavior.AllowGet);
The JsonRequestBehavior Enum:
Specifies whether HTTP GET requests from the client are allowed.
Which by default is set to Deny get.
https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.jsonrequestbehavior?view=aspnet-mvc-5.2
after a compiling a form needed for register on the website( Registration.cshtml ), the form data are sent in a sqlite db ( successfully). Returning from that, i want to be sent to a Main.cshtml webpage. The problem is that the Action controller that is suposed to render the Main.cshtml view, isn't doing it.
I've tryed changing the Redirect/RedirectToAction and View methods many times, but it was a failure.
return View("Main");
return RedirectToAction("Main");
return JavaScript("window.location = window.location.origin + /Pages/Main");
PagesController.cs
[HttpPost]
public ActionResult Register {
if (insert data in db == true) {
return RedirectToAction("Main");
}
return View();
}
public ActionResult Main(){
return View();
}
Main.cshtml
#{
Layout = "~/Views/Layouts/LoggedMasterPage.cshtml";
ViewBag.Title = "Benvenuto in ETL365";
}
#section Head{
<link rel="stylesheet" href="~/Content/Main.css" />
<script type="text/javascript" src="~/Scripts/Main.js"></script>
}
Part of my Register.js
$("#register").dxButton({
text: "Registrati",
type: "normal",
hint: "Clicca per registrarti",
onClick: function () {
if($('#password').
dxValidator('instance').validate().isValid &&
$('#email').dxValidator('instance').validate().isValid) {
let email = $("#email").dxTextBox('instance').option('value');
let pass = $("#password").dxTextBox('instance').option('value');
$.ajax({
url: window.location.origin + '/Pages/Register',
type: "POST",
data: '{"email":"' + email + '","password":"' + pass + '"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
});
}
}
});
I've already used breakpoints on Main.cshtml, and it actually gets in there after the
return View();
done by the action Main().
What i expect is to be redirected to the mylocalhost:xxxx/Pages/Main
What i get is absolute nothing, I'm always in mylocalHost:xxxx/Pages/Register
You need to redirect to your main page after a successfull ajax call.
$.ajax({
...
success:
{
location.href = 'mylocalhost:xxxx/Pages/Main'
}
...
You cannot use RedirectToAction for AJAX call response because AJAX requests are intended to update the view without reloading whole page. You need to pass the URL as JSON response like this:
[HttpPost]
public ActionResult Register(string email, string password)
{
if (condition) // put your condition here
{
return Json(new {
status = "Success",
url = Url.Action("Main", "Pages")
});
}
// since this controller receives AJAX request, the partial view should be used instead
return PartialView("_Register");
}
Then in AJAX success condition you can check response status and redirect to target URL:
$.ajax({
url: '#Url.Action("Register", "Pages")',
type: "POST",
data: { email: email, password: pass },
success: function (result) {
if (typeof result.status !== undefined && result.status == "Success") {
location.href = result.url; // redirect to main page
}
else {
$('#register').html(result); // refresh partial view
}
}
});
Related issue:
return url.action as json object mvc
In a Post method within a Controller derived from ApiController what should I return to indicate success to jQuery ?
I've tried HttpResponseMessage but jQuery sees this as an error (even though the argument the jQuery error handler clearly has a 200 status).
The jQuery looks like this :
processParticipantEvent: function(parID, evtType, evtNotes, successFunction, errorFunction){
debugger;
var requestURL = '/api/participantevent';
var json = {"parId" : parID, "evtType": evtType, "evtNotes": evtNotes};
var jsonArray=JSON.stringify(json);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: requestURL,
data: jsonArray ,
dataType: "json",
success: function (data) { successFunction(data); },
error: function (data) { errorFunction(data); }
});
},
I've read this : Ajax request returns 200 OK, but an error event is fired instead of success which seems like it's touching on the same issue but I suspect it's out of data as it won't work for me ?
Just to be clear all I want to do is to return a plain old 2xx with no data.
As per the documentation:
"json": Evaluates the response as JSON and returns a JavaScript
object. Cross-domain "json" requests are converted to "jsonp" unless
the request includes jsonp: false in its request options. The JSON
data is parsed in a strict manner; any malformed JSON is rejected and
a parse error is thrown. As of jQuery 1.9, an empty response is also
rejected; the server should return a response of null or {} instead.
So if you want to use jQuery ajax you have to return a valid json string, just use the following in your API controller:
return Ok(new {});
Note this is a jQuery ajax "feature", using Angular for example to do an ajax post I can use return Ok(); inside my controller and everything works as expected.
As mentioned by #Beyers the return with OK() just works.
I've created the same structure here and worked.
My Controller has this:
[Route("api/participantevent")]
public IHttpActionResult Test()
{
return Ok("");
}
And at client I've changed your function just to simplify:
processParticipantEvent= function(){
debugger;
var requestURL = '/api/participantevent';
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: requestURL,
data: [{'test': '1'}] ,
dataType: "json",
success: function (data) { alert('success'); },
error: function (data) { alert('error'); }
});
}
Your error is with the requestURL. Its value is absolute and http://api/participantevent does not exist. Try using a relative value.
var requestURL = './api/participantevent';
It seems that if you get an OK response, It is probably not a valid JSON.
I would recommend to you to check the HTTP response in the browser and try to run the JSON.parse function with the responseText and see whether it fails.
I usually declare a class like below:
public class AjaxResult
{
private bool success = true;
private List<string> messages;
public bool Success { get { return success; } set { success = value; } }
public List<string> Messages { get { return messages; } }
public AjaxResult()
{
messages = new List<string>();
}
}
In the controller, the action(to which the ajax request is made) should have JsonResult as return type.
[HttpPost]
public JsonResult Action(string id)
{
AjaxResult result = new AjaxResult();
//Set the properties of result here...
result.Success = true;
result.messages.Add("Success");
return Json(result);
}
3.And your ajax call will look like this:
$.ajax({
type: "POST",
dataType: 'json',
url: /ControllerName/Action,
data: { id: "Test"},
success: function (data) { alert('success'); },
error: function (data) { alert('error'); }
});
My code makes an ajax call:
$.ajax({
url: "/Controller/EmailUserKeys",
dataType: 'json',
success: function () {
alert('success');
},
error: function () {
alert('error');
}
});
It calls an action in my controller which returns some JSON:
public JsonResult EmailUserKeys(string UserId)
{
...
return Json(new { success = true });
}
My problem is that the ajax error function is called and not the ajax success function.
Why?
PS. If my action returns "return null;", the ajax success function is called.
You must allow GET which is disabled by default when returning JSON results:
public JsonResult EmailUserKeys(string UserId)
{
...
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
or use a POST request:
$.ajax({
url: "/Controller/EmailUserKeys",
type: "POST",
dataType: 'json',
data: { userId: 'some user id' },
success: function () {
alert('success');
},
error: function () {
alert('error');
}
});
Also never hardcode the url to your controller action as you did. Always use url helpers when dealing with urls in an ASP.NET MVC application:
url: "#Url.Action("EmailUserKeys", "Controller")",
And here's a piece of advice: use a javascript debugging tool such as FireBug if you are doing any web development. Among with other useful things it allows you to inspect AJAX requests. If you had used it you would have seen the response sent from the server which would have looked like this:
This request has been blocked because sensitive information could be
disclosed to third party web sites when this is used in a GET request.
To allow GET requests, set JsonRequestBehavior to AllowGet.
And you wouldn't need to come to StackOverflow and ask this question as you would have already known the answer.
You should edit your code to this:
public JsonResult EmailUserKeys(string UserId)
{
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
See the official documentation for more info:
http://msdn.microsoft.com/en-us/library/system.web.mvc.jsonrequestbehavior.aspx
The reason for disabling this by default is because of JSON hijacking. More information about this can be found here:
http://haacked.com/archive/2009/06/25/json-hijacking.aspx
Hope this helps you out!