Asp.net MVC Ajax call not calling controller method - c#

I am making an ASP.net MVC application And I would like it so when a user clicks on a link it performs an ajax call sending data to the controller and then returning other data back to the view.
This is the method I would like to call in my controller:
public JsonResult GetImage(string url)
{
Image image = Image.FromFile(url, true);
byte[] byteImage = converter.ImageToBytes(image);
return Json(new { byteImage }, JsonRequestBehavior.AllowGet);
}
And here is the controllers location:
08983ClassLibrary\EpostASP\Controllers\CustomerController.cs
This is my Ajax Call:
$.ajax({
url: "~/Controllers/CustomerController/GetImage/",
type: 'POST',
contentType: 'application/json',
data: "url="+url,
success: function (image) {
document.getElementById("image").src = "data:image/png;base64," + image;
showImage();
}
});
When i place my breakpoints in the code I can see it hitting the ajax call then stepping over it never reaches the controller and doesnt give any errors.
Any ideas?

The main issue is here -
url: "~/Controllers/CustomerController/GetImage/",
You see, ~ is a server side literal, in other words, when you use this in a ASP.net server side path, it is replaced by the current server application folder location. This was the traditional ASP.Net way. This line has 2 errors -
This url will never work. Because its inside a string in JS and thus ASP.net does not know that it has to replace it with server path. Now comes the second error, even if ASP.net could detect and convert it, it will still not work. Because of the point I described at 2 -
Since you are using ASP.net MVC, it's not a good practice. The more conventional MVC way is to create routes and use those routes. Because in ASP.net you have the option to link to a page (.aspx, .ascx) directly. But MVC controller actions cannot be linked like that. So you have to create routes in your route config (check Global.asax) and then use that route as the url in here. BY default MVC apps will support the following format -
<host>/{controller}/action
example -
'localhost/Home/Index`
Notice that I didn't write HomeController, because by default controllers are supposed to ignore the trailing string Controller.
I hope this helped and just incase you are looking for a solution for your current situation try this (I haven't tested but it should be like this) -
$.ajax({
url: "Customer/GetImage",
type: 'POST',
contentType: 'application/json',
data: "url="+url,
success: function (image) {
document.getElementById("image").src = "data:image/png;base64," + image;
showImage();
}
});
but to be on the safe side, make sure you use -
[HttpPost]
public JsonResult GetImage(string url)
{
}
UPDATE:
the maproute (as requested in comment ) will work with any of these routes. But can also work with different routes config. Route config is very very flexible, it is just a matter to setup the routes the way it works for you. -
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"...", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.MapRoute(
"...", // Route name
"{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.MapRoute(
"...", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Customer", action = "GetImage", id = "" } // Parameter defaults
);
routes.MapRoute(
"...", // Route name
"Customer/GetImage/{id}", // URL with parameters
new { controller = "Customer", action = "GetImage", id = "" } // Parameter defaults
);
..... //all of these mentioned route will land on the same url
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}

Your ajax script says it is looking for a POST action method.
$.ajax({type: 'POST',
Have you decorated the action method with POST?
[HttpPost]
public JsonResult GetImage(string url)
{
}
Also, adjust your ajax data parameter
$.ajax({
data: {
"url": url
},

If you are using chrome you can go the developer tools -> network tab and see all the server requests being made. Hit your button and you will see it pop up and show you the response codes, headers etc. In your case it will be red and will tell you what went wrong

If you are using web api... Your method is starting with "Get" GetImages so you need to decorate the method with [HttpPost]

I have found that using fiddler is the best way to see what is going on in MVC.
Start up fiddler, run the code again and see what actually came back. Most likely (as mentioned by Yorro) is that you got a 404 error and as you have no error handling in your json call, you wont ever see the error.

$.ajax({
url: '#Url.Action("GetImage", "Customer")',
type: 'POST',
contentType: "application/json; charset=utf-8",
data: "url="+url,
success: function (image) {
document.getElementById("image").src = "data:image/png;base64," + image;
showImage();
}
});

If using IE, and your controller is hitting the first time only add ...
$.ajax({
cache:false,
...

Some time it will work or some time not work so don't mention URL such as static "~/Controllers/CustomerController/GetImage/" please follow the dynamic way
So you will change the code snippet such as below
$.ajax({
url: "#Url.Action("GetImage", "CustomerController")",
type: 'POST',
contentType: 'application/json',
data: "url="+url,
success: function (image) {
document.getElementById("image").src = "data:image/png;base64," + image;
showImage();
}
});
hopefully this code will be resolved your problem !!

Related

ASP.NET MVC - JQuery call from url without action not working

I have a http://localhost:54393/CreateTest/4fwp36 which working fine but when I call http://localhost:54393/CreateTest/RemoveControlsNew from jQuery ajax then it is not working giving an error also not calling into a controller if any one can help me out as I am stuck here more then 1 day
I have tried this but it's not working:
MVC JQuery call from url without action
This is my route config:
routes.MapRoute(
name: "CreateTest",
url: "CreateTest/{id}",
defaults: new { controller = "CreateTest", action = "Index", id = UrlParameter.Optional }
);
Above code works perfectly when I call from another controller calling it like this:
return Redirect("/CreateTest/"+ strTestID);
When I try to call on same controller with ajax post method
RemoveControls: function (rid) {
var MyAppUrlSettings = {
MyUsefulUrl: "/CreateTest/RemoveControlsNew"
}
$.ajax({
type: 'POST',
dataType: "JSON",
async: false,
//url: '#Url.Action("RemoveControlsNew",Request.Url.Scheme)',
url: MyAppUrlSettings.MyUsefulUrl,
contentType: 'application/json; charset=utf-8',
data: {
rid: rid,
bgcolor: CREATETEST.globalbgcolor,
fontcolor: CREATETEST.globalfontcolor,
fontsize: CREATETEST.globalfontsize
},
success:
function (response) {
var data = response;
if (data == 'Error') {
CREATETEST.showerror('Some thing went wrong you cannot remove a question at the moment for selected option');
}
else {
$("#AddControlNew").load(location.href + " #AddControlNew");
}
},
error:
function (response) {
console.log(response);
CREATETEST.showerror("Error: " + response);
}
});
},
Then these is not working and my method is not called.
I am getting this error:
Error on page
Controller code for Ajax call
Regular Controller code
Your "Error on Page" image doesn't show anything useful, are you getting a 404, 202, 405 Header Status Code
Please post code, not images.
Apply the [FromBody] attribute to a parameter to populate its properties from the body of an HTTP request. The ASP.NET Core runtime delegates the responsibility of reading the body to an input formatter.
public JsonResult RemoveControlsNew([FromBody] int rid, string bgcolor, string fontcolor, string fontsize)

MVC C# AJAX Post routing issue

I am from ASP Classic background and new to MVC object-oriented programming especially their re-routing config. I do understand the Model View Controller concept.
I am having the following issue:
When my view is at Password.chtml and heading to detail PasswordDet.chtml either from
button [New] will be http://localhost:50218/Password/PasswordDet OR
button [Edit] will be http://localhost:50218/Password/PasswordDet/123
The URL syntax on AJAX postback to trigger back PasswordController/PasswordDet is different depends on whether you come from [New] or [Edit] in order for the postback to work.
My understanding is that now I am at PasswordDet.chtml. Triggering PasswordController/PasswordDet/ shouldn't it be var url = 'PasswordDet/' + $("#btnSubmit").val()? Or please share what is the correct way. Please help thank you.
The following is an illustration of my problem.
From Password.chtml to PasswordDet.chtml I have:
New
window.location.href = '#Url.Action("PasswordDet", "Password")';
Edit
"render": function (data, type, full, meta) {
return '<img src="../../Content/myPics/edit-2-24.png" >';
}
But in order for it to work. At PasswordDet.html AJAX Postback
From New I need to put PasswordDet/ infront :
var url = 'PasswordDet/' + $("#btnSubmit").val()
And From Edit I don't need to:
var url = $("#btnSubmit").val()
Shouldn't both of them the same
AjaxCode at PasswordDet.chtml
var url = 'PasswordDet/' + $("#btnSubmit").val()
var formData = $('#formPassDet').serialize();
$.ajax({
url: url,
type: "POST",
data: formData,
dataType: "json",
success: function (response) {
if (response.status == "saved") {
*****Here i don't need to put '.../" ******************
window.location.href = 'Password';
} else if (response.status == "updated") {
*****Here i have to put************************
window.location.href = '../Password/';
});
Password Controller
[HttpPost]
public ActionResult PasswordDet(string id, ForgotPasswordModel viewModel)
{
some code
}
RouteConfig Not sure how to use this
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Login", id = UrlParameter.Optional }
);
Actually not clear what u need.If you are a beginner in MVC
pls go through the link https://www.youtube.com/watch?v=bCNyL4LfWSw

Two post methods in one WebApi controller, results in application not working

I have the following Web Api Controller
public class ImageUploadController : ApiController
{
[HttpGet]
public string UploadImage(int id)
{
return "Value = " + id;
}
[HttpPost]
public void UploadImage([FromBody] Customer customer)
{
string name = customer.company_name;
string dooda = string.Empty;
}
[HttpPost]
public bool DeleteImage(int id)
{
try
{
string dooda = string.Empty;
return true;
}
catch (Exception ex)
{
return false;
}
}
}
The get and post method for UploadImage work but as soon as I add another post i.e DeleteImage neither of the posts work.
I get a 404 Bad Request for both methods.
In my view I have two buttons, one that calls the upload image and the other that calls delete image as shown here
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="jquery-1.11.2.js"></script>
<title></title>
</head>
<body>
<button id="btnPushMe">Push Me</button><br />
<button id="btnDeleteMe">Delete Me</button>
</body>
</html>
<script type="text/javascript">
$('#btnPushMe').click(function () {
var apiurl = "http://localhost:50793/api/ImageUpload/UploadImage"
var customer = { customer_name: "Scott", company_name: "HP" };
$.ajax({
type: "POST",
data: JSON.stringify(customer),
url: apiurl,
contentType: "application/json"
});
});
$('#btnDeleteMe').click(function () {
var apiurl = "http://localhost:50793/api/ImageUpload/DeleteImage"
$.ajax({
type: "POST",
data: { id: "2" },
url: apiurl,
contentType: "application/json"
});
});
</script>
This is my config
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Again I'm just playing around with Web Api and trying to learn it as I go so if someone can enlighten me in to why/what I'm doing wrong I'd much appreciate it.
Thanks
The route template you are using is a "restful" one that will map to controller actions purely by the HTTP verb. i.e. There is no {action} in the template.
When you add the second post method WebAPI cannot disambiguate the calls.(For example http://localhost:50793/api/ImageUpload/UploadImage and http://localhost:50793/api/ImageUpload/DeleteImage both match api/{controller}/{id} which also matches both action methods. The action isn't specified in your template url.
Using a template like api/{controller}/{action}/{id} would map the urls you are calling with. Note this is then stepping away from a restful approach; which isn't necessarily wrong.
You might also consider adding specific templates - e.g. api/ImageUpload/UploadImage and explicitly set the action in the defaults.
Or you could use attribute based routing which would let you add an attribute directly to the action method with the desired url. This is often better for non-restful style controllers.
You should use JSON.stringify(data), as you are setting the content type as application/json.
You could have passed the value as part of the uri like delete/12 or delete?ID=12.
IMHO, Also, you can use HttpDelete for delete verbs instead of put or post, unless delete is not accepted.
HTH
In your Code please just remove the contentType: "application/json" on ajax method. Then it will automatically lead u to the controller page.
Please get look on the below code
$('#btnDeleteMe').click(function () {
var apiurl = "http://localhost:50793/api/ImageUpload/DeleteImage"
$.ajax({
type: "POST",
data: { id: "2" },
url: apiurl,
});

Error in constructed URL for getJSON method

I have the following jQuery call in the razor view.
$.getJSON('/Controller/ActionName/'+ #ViewContext.RouteData.Values["Name"] + '?Date=' + ('#StartDate').val(), function (data) {
alert(data);
});
The error in chrome browser console is that the below URL has returned no page found.
http://localhost:{portNumber}/Controller/ActionName/John?Date=9/21/2014&_=1413867422739
it is true because of the added extra token to the end of the url.
Can any one please let me know the reasons for the extra token?
I have an appropriate method in the controller and not able to figure out a solution.
The routeConfig.cs file is not changed and it has the default values to it.
Please let me know in comments if you need further information. I am not able to understand which information to furnish.
Route information:
{
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", name = UrlParameter.Optional }
);
}
Action Signature in the controller
public JsonResult ActionName(string**?** name, DateTime startDate)
{
var model = new ViewModel();
model.loadItems(name**.value**, startDate);
return Json(model.Data, **JsonRequestBehavior.AllowGet**);
}
Answer:
Made the above changes in surrounded by ** and the code worked.
Thank you for the comments and answers.
Update:
I have mentioned the default values in order to hide the unrequired information.
localhost is correct and other pages are working fine just a small part of ui which is related to this ajax call is not working.
No controller is name something else.
Can you please provide a solution for sending date values in URLS?
Change you call to (assuming your controller is really named ControllerController
$.getJSON('/Controller/ActionName/', { name: #ViewContext.RouteData.Values["Name"], startDate: $('#StartDate').val(), function (data) {..
You have a few problems here. Your default route accepts a parameter named ID but your method only has parameters name and startDate. You are not passing any parameters with those names (you are passing one for date but that does not match the method signature parameter)
Note you should not hard code the controller and action names this way. The recommend ways is
var url = '#Url.Action("ActionName", "Controller")';
var StartDate= ('#StartDate').val();
var url="/Controller/ActionName/'+ #ViewContext.RouteData.Values["Name"] + '/";
$.ajax({
url: url,
data: { Date: StartDate},
cache: false,
type: "POST",
success: function (data){
},
error: function (data){
}
});

ajax jquery .net results in "The resource cannot be found."

I'm trying to do a simple ajax call in .net
Any advice?
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
I call the webmethod in my browser like this:
http://localhost.com/Ajax/WebService1.asmx/HelloWorld
Which results in
"The resource cannot be found."
Probably because of the url syntax.
My routes are setup like:
routes.IgnoreRoute("Ajax/");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
If I delete the MapRoute, the webcall works, but the rest of my website fails.
Any advice?
Update:
I changed to use a controller. When I call it with a url in my browser I hit my breakpoint in the controller. But not when I run this code:
<div id="Result">
Kig her!
</div>
#section javascript {
$(function () {
$("#FirstReminder").datepicker();
$("#EndDate").datepicker();
});
$(document).ready(function() {
// Add the page method call as an onclick handler for the div.
$("#Result").click(function() {
alert('kkk');
$.ajax({
type: "POST",
url: "AjaxWorkflow/GetSteps",
data: {workflowId: "1", workflowStep: "test"},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Replace the div's content with the page method's return.
$("#Result").text(msg.d);
}
});
});
});
Update 2:
I solved it by changing the line to
data: "{workflowId: '1', workflowStep: 'test'}",
Because you are using routing, I assume this is an MVC website? If so you should use an ActionResult in your controller instead of a WebMethod. Try this:
public string HelloWorld()
{
return Content("Hello World");
}
You would then call this using jQuery on the following URL: http://localhost.com/[Controller]/HelloWorld
Note, in the example here I am returning a string - as per your original example. It is also possible to return an object via JSON, using return Json(obj);
WebMethods belong to ASP.NET WebForms while the routing belongs to ASP.NET MVC. You'd better not mix the two technologies.
In this case most of the application seems to be ASP.NET MVC if after removing the routing everything stops working. That means that you want to replace the WebMethod with a Controller Action.

Categories