I can write a JQuery AJAX call to a webapi2 (asp.net) controller with only 1 parameter just fine (one json object), but when attempting to send 2 parameters (a string and an integer) to a call with all else remaining the same, I get
No HTTP resource was found that matches the request URI
error in the browser console. I believe I've tried every combination I can think of to get 2 parameters to pass, but always end up with the same error message! I'm not sure of the correct format for the data: in javascript - I thought I made a JSON object, but did not. I've quoted, unquoted, and tried every combination I can think of, but no joy. Does ASP.Net WebAPI2 not accept more than 1 parameter? (I'm converting ASMX from an old site to api controllers and am stuck on 1 particular one that takes 2 parameters - works fine for ASMX, but webapi doesn't seem to recognize the signature).
web method in C# (i've tried the post, put and delete verbs - no joy)
[Route("api/DeleteUserSearch")]
[HttpPost]
[Authorize(Roles = "admin,paid,vendor,visitor")]
public async Task<IHttpActionResult> DeleteUserSearch(string userid, int usersearchidx)
{
int retval = 0;
if (IsValidUserId(userid))
{
retval = (await userSearch_Data.DeleteSavedSearchAsync(userid, usersearchidx)).xToInt();
}
return Ok(retval);
}
The AJAX call: (one version that worked with ASMX)
function deleteUserSearch(uid, sid) {
$.ajax({
url: '../../api/DeleteUserSearch',
dataType: 'json',
method: 'post',
data: { userid: uid , usersearchidx : sid },
success: function (data) {
//refresh searches dropdown
ShowSuccessMsg('Your search has been deleted.');
$('#SSPopup').modal('hide');
RetrieveSearchesDD(uid, "#ddlSavedSearches", false, "")
},
error: function (err) {
console.log('Error (deleteUserSearch): ' JSON.stringify(err, null, 2));
}
});
};
This works for all other calls with 1 parameter (any object), but does not for more than one. What am I doing wrong here?
Full Error in the Console: (it's obviously a signature problem - the URI is correct).
Error (deleteUserSearch): {
"readyState": 4,
"responseText": "{\"Message\":\"No HTTP resource was found that matches the request URI 'https://localhost:44371/api/DeleteUserSearch'.\",\"MessageDetail\":\"No action was found on the controller 'SavedSearches' that matches the request.\"}",
"responseJSON": {
"Message": "No HTTP resource was found that matches the request URI 'https://localhost:44371/api/DeleteUserSearch'.",
"MessageDetail": "No action was found on the controller 'SavedSearches' that matches the request."
},
"status": 404,
"statusText": "error"
}
CodePudding user response:
When you are passing data as an object like { userid: uid , usersearchidx : sid }
you need some changes in your Controller
and Action
public class Parameter
{
public int UserId { get; set; }
public int UserSearchIdX { get; set; }
}
public async Task<IHttpActionResult> DeleteUserSearch([FromForm] Parameter param)
{
// Your code
}
CodePudding user response:
OK. Got it figured out. WebApi can only handle one parameter, but it can be anything (an object). Because this is DotNetFW 4.72 , the [Form] decorator won't work (DotNetCore only), so I figured I'd just create a JSON object in Javascript and match it with an object in C#.
(I have a class/model called UserSearch with the properties UserId and UserSearch_Idx)
So the working version code is as follows:
[Route("api/DeleteUserSearch")]
[HttpDelete]
[Authorize(Roles = "admin,paid,vendor,visitor")]
public async Task<IHttpActionResult> DeleteUserSearch(UserSearch p)
{
int retval = 0;
if (IsValidUserId(p.UserId))
{
retval = (await userSearch_Data.DeleteSavedSearchAsync(p.UserId, p.UserSearch_Idx)).xToInt();
}
return Ok(retval);
}
On the client side, it's straightforward: Just create a JSON object and assign it's properties. Code on that end looks like so:
function deleteUserSearch(uid, sid) {
var uSearch = {};
uSearch.UserId = uid;
uSearch.UserSearch_Idx = sid;
$.ajax({
url: '../../api/DeleteUserSearch',
dataType: 'json',
method: 'delete',
data: uSearch,
success: function (data) {
//refresh searches dropdown
ShowSuccessMsg('Your search has been deleted.');
$('#SSPopup').modal('hide');
RetrieveSearchesDD(uid, "#ddlSavedSearches", false, "")
},
error: function (err) {
console.log('Error (deleteUserSearch): ' JSON.stringify(err, null, 2));
}
});
};
Thank you Saeid for the tip (Core has a built in object representing the form data - which is nice)!