I have no problems processing jQuery GET requests in a controller, however I cannot get any form data to POST. The client snippet
$.post(url,{name:"John"},function(result){
//process result
});
combined with a controller,
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Save(string name)
{
return Json("Success!");
}
will result in a NULL value for the name parameter when inspected inside the action method, whereas I expected name to be mapped to the method parameter. Also all other objects (Request.Form), etc. in this context seem to be NULL. I can do this with a $.get, but I think I am supposed to do any operations with side-effects with POSTs. I am using ASP.NET MVC 1.0, jQuery 1.2.6 and Internet Explorer 7.
Thanks!
Update: see my answer below and humble apologies
Sorry guys, I had a $.ajaxSetup entry in the page which overrided the default contentType to application/json.
When using the default contentType as follows:
$.ajax({ url,
type: "POST",
contentType: "application/x-www-form-urlencoded",
success: function(result) { alert(result); },
data: { name: "John" }
});
It works because processData is true by default which means the data entry with the JSON object will be parsed into a string (data: "name=John" also works).
Sorry for wasting your time :) and thanks to Mark for the suggestion on passing JSON objects, ill do that next cause it seems very cool.
I believe your code should work, is your URL correct and your routes setup correctly? In addition you could always fire up Fiddler to see exactly what your request to the server is and if you are passing the correct items.
Could it be that the Save(string name) method is expecting stringified JSON? Try this:
$.post(url,
"{'name':'John'}", function(result){
});
It isn't so simple as making a json object and throwing it at an action.
Start from here. People have written small scripts that get the JSON object dressed and ready for an action to read it in and map it to properties or arguments.
Related
I have a controller action method that works when it looks like this:
public ActionResult testMethod(int id)
{
//do something...
//return something...
return View();
}
But when I specify that it should be a "Post" method, I get a '404 not found error':
[HttpPost]
public ActionResult testMethod(int id)
{
//do something...
//return something...
return View();
}
I have other controller action methods in the same controller - both POST and GET, and they work fine. But this one doesn't? What's going on? (I'm sure I'm missing something obvious here...)
Update:
An ajax call requests the controller method:
var id = 1;
$.ajax({
url: '/indices/testMethod/',
data: id,
type: 'POST',
success: function (data) {
//Do something
}
});
I've also tried to test the method with Postman, making sure a POST request is sent.
Update 2:
I've tried changing the parameter to id, and tried to make sure all method and url locations are capitalised to match, but without any effect.
In Fiddler, I can see that actually a GET request is being made, even though I specify a POST request in the ajax call, so now I need to find out why the request ends up being sent as a GET instead of a POST.
I also tried including an attribute route description, like this
[HttpPost]
[Route("indices/TestMethod/{id:int}")]
public ActionResult TestMethod(int id)
And then tried the ajax call with a different url:
$.ajax({
url: '/indices/TestMethod/1',
data: id,
type: 'POST',
success: function (data) {
var tr = 123;
var yr = data;
//Do something
}
});
With attribute routing on, and the paramter value in the URL, I see in Fiddler that first a POST request happens, which gets a 301 status error, but then a GET request is also made, which gets the 404 error.
Update 3:
After more investigations I narrowed the problem definition down sufficiently that it made sense to open a new question, which can be found here:
ASP MVC jQuery $.ajax POST request does not call controller method, but works in "fresh" MVC project
The issue seems to be caused by Content Security Policy settings that were active for this project.
Try changing param1 to id and see if it works. This may sound stupid but actually I've experienced your problem before myself and that solved the problem.
The other issue I could think of is that in your app, testMethod's path is /Indices/TestMethod with uppercase characters. And when you request /indices/testMethod/ there might be some redirect happening which results in a GET request.
Try changing the url in your ajax call or try adding a [Route()] attribute to set the route name.
You might need to add the FromBody-attribute to the int param1-parameter as it is a simple type? See here for more info.
Otherwise a route in the format /indices/testMethod/{param1} is expected (i.e. param is required to be in the URL, even if it is a POST-request). This route might not be defined, i.e. in your global.asax.cs. You could try making a POST-request to /indices/testMethod/1 for example. Just to try if it really is a routing issue?
In case you do have issues with your routing, you can define a specific route for your method using Attribute Routing. At least for testing/development as this makes it easier to see/understand which route is actually defined for your method.
Some additional questions to narrow down, what it could actually be:
What format does you dataGoesHere-object have?
What do the POST-methods that work look like? What datatype is their parameter? Reference- or value-type?
What routes do you register (i.e. in the global.asax.cs)?
Update
I would try following:
Define controller method like this:
[HttpPost]
[Route("indices/TestMethod/")]
public ActionResult TestMethod([FromBody] int id)
Define action call like this:
$.ajax({
url: '/indices/TestMethod/',
data: id, // alternatively try: {id: id}
type: 'POST',
success: function (data) { }
});
Either try passing the id as a simple value or try passing it withn an object with an id-property (see comment above).
I have a web application that uses VB.NET MVC for the server side code. I set up the client side JavaScript to easily send and receive data to the server Controller functions. Basically what I did was create a JavaScript "request" object that uses Ajax to call a controller function and pass in parameters. I let MVC do all of the serialization for me. Then the controller function returns a JSON, usually with a block of HTML as a string. Since I am handling all of the ajax calls in one place, I can't figure out a good way to handle the responses. When the ajax response comes back, I have no way of knowing which request it came from. The website has a lot going on so the responses all need to be handled differently and all return different data.
Right now what I do is in the controller function I send back some key along with the block of HTML, then in the ajax complete function I check for all of these specific keys. Doing it this way makes the javascript code difficult to manage.
var postData = { id=0 };
$.ajax({
type: "POST",
url: "/Controller/Action/"
data: postData
}).done(function (data) {
if (data.Foo) {
Foo(data);
} else if(data.Bar) }
Bar(data);
}
});
I am having trouble researching this because I don't know which keywords to look up. I think I'm going to try and do something where I call the function names dynamically in the ajax done function, but I was wondering if there are any existing libraries or code examples that do larger scale ajax request functions like this.
Maybe the problem comes from the idea of "doing all the stuff in one place". I can imagine that it will be very difficult to maintain your code once you have 40 chained if...else if... in one method. Maybe splitting things up a bit wont hurt after all.
Anyway, one way of doing it the way you want it would be instead of passing a key, passing the name of the javascript function as a delegate. Then call window[data.funcName](data); in done().
Say your json is
{
foo: "bar",
funcName: "DoMyFoo"
}
This is how your call would look like :
var postData = { id=0 };
$.ajax({
type: "POST",
url: "/Controller/Action/"
data: postData
}).done(function (data) {
window[data.funcName](data);
});
function DoMyFoo(d){
//Do your specific stuff here
alert(d.foo);
}
See this question How to execute a JavaScript function when I have its name as a string for info and examples.
Edit: If your functions lies within an object instance instead of the global namespace, say obj, you can call it the same way with obj['myFunction'](args)
My code runs as,
$.ajax({
url: "api/WepAPI/",
dataType: 'json',
success: function (result) {
alert(result.length);
$.each(result, function (index, element) {
alert(element.StartDate);
});
},
});
while iterating it shows the first element's startdate correctly and for all other elements it returns the
undefined message in the alert.
My WEBAPI contoller code looks like,
public IEnumerable<Employees> GetAllEmployess()
{
EmpDataContainer context = new EmpDataContainer();
return context.Employees.AsEnumerable();
}
Help me in sorting out this error...
It appears your data might not be what you are expecting or maybe it is missing something or perhaps it is lower/different letter case.
In either case, without begin able to see the JSON for result; it is not possible to identify the possible cause for this issue.
Can you please add the JSON for a typical result object?
You can use console.log(result); to output the JSON.
After some debugging and browsing, I found that the problem was due to using the entity object itself which has navigation properties i.e., the object in turn has some child objects.
Then found a work around to solve the issue, created a view model and assigned the values needed to the view model.
make sure that the view model does'nt have child objects.
I have an ajax POST request that is supposed to be submitting data to an ASP.NET MVC action. This works fine 95% of the time but every so often, for whatever reason, my FormCollection is empty and the application errors out as a result.
I would have included the raw request values however I haven't been able to reproduce this myself.
My ajax call looks like this:
var data = {};
data.Property = 123; // etc
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: JSON.stringify(data),
success: function(viewModel) {
// do stuff
}
});
What would cause the FormCollection to intermittently be empty on the ajax POST?
I have suspected things like session timeouts and the like but I would expect that to error out before I get in to the action.
First of all you seem to be sending a JSON request (JSON.stringify(data)). This is not supported out of the box in ASP.NET MVC 2. It is in ASP.NET MVC 3 that a JsonValueProviderFactory was introduced. You may take a look at the following article which explains in more details JSON requests in ASP.NET MVC.
Also everytime you want to send a JSON request you should set the proper content type using the contentType parameter:
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
and last but not least I would recommend you to use view models instead of relying on some weakly typed structures such as FormCollection in your controller actions and having to write plumbing code.
UPDATE:
FormCollection is a key/value pair collection. So if you want to use it (despite my recommendation against it) you should not use a JSON request. You should use a normal key value request. So remove the JSON.stringify from your AJAX request and remove the contentType: 'application/json' parameter as well. There's really no point in using weakly typed key/value pair collection with JSON objects.
While there appears to be similar questions I do not believe I found one where somebody was passing the entire model from view to controller, the closest I found was passing a data value in the model to the controller... which is not what I want to do...
I want to pass the model object to the applicable controller action result as a parameter
and do what I want to do with the data in the model object from within the controller...
code abbreviated...
in the view i am using Url.Action(string, string, object) to pass the controller method name, and the route to it as the 2nd parameter, and the entire model object as the 3rd parameter...
my third parameter is the problem, the Url.Action(string, string) over load works fine with the same values, so I don't have any problem getting to the controller action result method, with the values I am using...
view code snippet...
$('#ControllerActionResult').click(function (e) {
window.location = '<%: Url.Action("ControllerActionResult", TheRoute, new { pModel = Model } ) %>';
});
controller code snippet...
public ActionResult ControllerActionResult(object pModel)
{
}
My error is "CS1502: The best overloaded method match for 'System.Web.Mvc.UrlHelper.Action(string, string, object)' has some invalid arguments" and the window location line is highlighted...
Am I missing something obvious?
I don't think you can do that. Url is trying to build a url, not call the action method directly. You can pass individual key value pairs via the anonymous object, which Url can then use to build a link. Model binding can take care of putting the key value pairs into the incoming model for you.
Also, is TheRoute a string as well?
If you need a Url you don't have many alternatives. Either pass all the values to rebuild the model, or just pass a key value to retreive the model from the database again (or maybe session / viewdata / tempdata, if you're using that).
There might be several issues in your code. But I will answer what you want to know, how to send data to controller from js. You have to first send "model" in json format, possibly with jquery.ajax. For example,
$.ajax({
url: '#Url.Action("ControllerActionResult")',
type: 'POST',
data: JSON.stringify(model),
dataType: 'json',
processData: false,
contentType: 'application/json; charset=utf-8',
success: OnSuccess
});
In controller, you have to have a defined class for the "model" and that should be the parameter of your controller.
[HttpPost]
public ActionResult ControllerActionResult(Model model) {
if (Request.IsAjaxRequest()) {
//to do
}
}
Otherwise, MVC cannot find a right controller to call.
try with following code it works for me
Javascript:
var location ='#url,action(string ,obj)'; window.location=location;
Controller:
public ActionResult index(string obj){return view();}
hope this works for you.