Error in constructed URL for getJSON method - c#

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

Related

Web API DELETE - The parameters dictionary contains a null entry for parameter 'id'

I'm trying to use ASP.NET Web API DELETE to remove a record from a database.
Here is the jQuery AJAX call:
var row = $(dom).closest("tr");
var text = row.find(".tId").text();
var tId = +(text);
//HTTP DELETE method
$.ajax({
url: 'api/transaction/delete',
type: 'DELETE',
data: {
'id': tId
},
success: function (result) {
//Success logic
//Refresh table?
console.log("Successfully deleted transaction " + tId);
},
error: function () {
console.log("Error deleting transaction");
}
});
Here is the controller code:
[HttpDelete]
[Route("api/transaction/delete/{id}")]
public HttpResponseMessage Delete(int id)
{
if (DataLayer.DataLayer.DeleteTransaction(id))
{
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
return null;
}
}
And the Http routing from Global.asax.cs
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Looking at the request in Fiddler, the error returned says The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' in 'SemanticUI_Playground.Controllers.TransactionController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
What's odd though is that - also in Fiddler - I can see the the request has id=1045.
I've obviously not done something correct; my guess is with the routing. If I change the AJAX request URL to api/transaction rather than api/transaction/delete I get a different error (to the effect of DELETE is not supported or similar).
Removing the id parameter altogether means that the breakpoint in TransactionController is met, but obviously useless!
I understand this is a bit ham-fisted (this project is just a personal one to teach myself about web development), please accept my apologies for my obvious lack of understanding!
The benefit of adding in the different type of requests is that you don't need to have multiple URLs to perform actions; you call them via the request type (DELETE, GET, POST etc). What I would do in the example you gave is remove the additional routing you've declared with [Route("api/transaction/delete/{id}")] and call it using:
$.ajax({
url: '/api/transaction/' + tId,
type: 'DELETE',
success: function (result) {
//Success logic
//Refresh table?
console.log("Successfully deleted transaction " + tId);
},
error: function () {
console.log("Error deleting transaction");
}
});
Or similarly keep the code route and send the request to '/api/transaction/delete/' + tId.
I've found that you will also need to register the attribute routing with RouteTable.Routes.MapHttpAttributeRoutes in your Global.asax.cs before your MapHttpRoute call. Check this out for a bit of guidance on that (ordering of the registration code is important!)

Get third parameter in asp.net MVC

I have a asp.net MVC website, and I have this url:
Home/Index/
There is one action that I want to do, and currently I'm doing it using query string, like this:
Home/Index/?action=1
I'll then get it in my code using Request.QueryString["action"].
But this does not look as good as it should, I'd like to have something like this:
Home/Index/Action
So the query string would be a third parameter. How can I use it like this and check if the third parameter exists, and it's name?
My routes are configured like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Do I need to change anything on the routes or I can just enter the way I want, and if so, how do I retrieve this value?
Edit :
Alright. What I wanted to do was to have a different result in the view depending on this parameter.
What I did now was create two ActionResults that use the same View sending different values to the ViewData.
In MVC there is the concept of Model Binding, where the names of the parameters are used and then filled with values from the Form, without you having to do it.
If you write your Action method like this:
public ActionResult Index(int action)
{ ... }
then it will already work for /Home/Index?action=1.
If you want to be able to call it like /Home/Index/1 then the easiest way is to simply write the Action method like this:
public ActionResult Index(int id)
{ ... }
This works because the MapRoute definition basically says 'if there is something after the {action} part (which in this case is "Index", by the way), then give it the parameter name {id} and bind it to the {id} parameter of my Action method".
Update:
The problem with using a parameter called action in both calling scenarios is that {action} is a special keyword in MVC.
To use MySpecialParam for both calling scenarios, you could just add this Route:
routes.MapRoute(
name: "Default_MySpecialParam",
url: "{controller}/{action}/{MySpecialParam}",
defaults: new { controller = "Home", action = "Index", MySpecialParam = UrlParameter.Optional }
);
However if MySpecialParam were to become action, then there is a name resolution conflict that MVC probably won't know how to handle, or it may even throw an error.
The action is supposed to be right after the controller, usually. I think in your case it might be better to add a new controller, which has the action you want.
I gave up mapping routes as this is cumbersome. You need to add a new route for every number of parameters, like follows:
routes.MapRoute(
"ThreeIds", // Route name
"{controller}/{action}/{firstId}/{secondId}/{thirdId}" // URL with parameters
);
routes.MapRoute(
"Dates", // Route name
"{controller}/{action}/{startDate}/{endDate}" // URL with parameters
);
Try doing ajax calls using something like jQuery instead. No nead to add a route for every possibility.
$.ajax({
url: '../' + controller + '/' + method,
data: jsonObjectString,
contentType: 'application/json',
dataType: 'json',
success: function (data) {
//do something
},
error: function (err) {
//do something
}
});
You can use my library at https://github.com/Biot-Savart/MVC-DataCall.js to make life a bit easier.

Receive parameters in action controller JSON

In ASP.NET MVC 5 with Entity Framework 6, I'm using a typical MVC Controller template with EF and I'm adding a custom action there.
My idea is to call this action from an AJAX call, to dynamically populate a select2 dropdown.
...
public JsonResult getWarrehouses(string name)
{
var warrehouses = from c in db.warrehouses
where c.nom_wrh.Contains(name)
orderby c.nom_wrh
select new { c.cod_wrh, c.nom_wrh} ;
return Json(warrehouses.ToList(), JsonRequestBehavior.AllowGet);
}
...
However, I don't know how to pass parameters to this, the parameter provided is always null. If I type: http://localhost:[port]/warrehouses/getWarrehouses/somestring the parameter is not received.
How I suppose to declare that action in order to receive GET parameters?
Feel free to provide an alternate solution if my approach is wrong.
The problem may be in the calling. For example:
the "name" is the name of your parameter on your Action;
$.ajax({
type: "POST",
url: #Url.Action("getWarrehouses"),
data: {
name: VALUE_TO_PASS
},
success: function (data) {
// Manipulate (data)
}
you need to use browser extensions like postman https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en
they help you to make a get/post requests to getWarrehouses . with your parameters

Asp.net MVC Ajax call not calling controller method

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 !!

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