Q: HttpDelete for MVC controller using KnockoutJS - javascript

[HttpDelete]
public ActionResult DeleteCustomer(int id)
{
var cus = customerContext.Customers.Find();
customerContext.Customers.Remove(cus);
customerContext.SaveChanges();
return null;
}
Above is my controller code for delete click event. Below is my js file. Call ajax to do delete action. But when I click delete button, it always pop-up a "Not Found" dialog. I have no idea what happened in the front end or back end. So sad. Need help, please. Thank you.
self.deleteCustomer = function () {
$.ajax({
type: "DELETE",
url: "../Customer/DeleteCustomer/",
data: { id: self.cusId() },
success: function (result) {
alert("Deleted!");
GetCustomers();
$('#AddCustomer').modal('hide');
},
error: function (error) {
alert(error.statusText);
}
});
}

For what you have posted it seems like you are using a path instead of a "url" in the url property. Try to use url: "/Customer/DeleteCustomer", instead of url: "../Customer/DeleteCustomer/",. If it still doesn´t work open chrome development tools and sniff the network to see where (url) it is sending the request.
To check if your roting is correct (in backend), you can install Postman (chrome plugin) and send a DELETE request and verify if the controller receives the request.
Regards.

Related

Opening new page passing parameters without showing them on the URL

I'm making a MVC C# Web App, and I began wondering whether you could open other pages that need parameters to function, without actually sending them through the URL, which is unsafe, and can lead to some user messing up another registry of the database.
My issue is though, I've never done such a thing, and I cannot find any example of code that does such a thing. The project is run with C# and JS, and the main things I've tried include:
-Doing so with Ajax:
First of all I have a button that calls for a function:
Link Text|
function openHorario(id, id_schedule, id_tool) {
alert(oid, id_schedule, id_tool);
$.ajax({
type: 'POST',
url: '/Schedules/actionEditStuff',
data: {
id: id,
id_schedule: id_schedule,
id_tool: id_tool
},
async: 'false',
success: function (data) {
//???
}
});
}
I know there's a way to go to a new page with the success Ajax return, but... That also requires for you to send the parameters through URL.
Obviously, that didn't work, because what the action does in the controller is to return a view, not a page. So... I realized that my idea was not very smart, and moved onto somewhere else: Link, but those always end up having to send the parameters visibly through URL.
Is there any way at all to do this in a proper, clean manner?
Thank you!
#Layan - just to illustrate my comment above, - you could implement something along these lines:
your client side invokes via ajax
...
var data = {
id: id,
id_schedule: id_schedule,
id_tool: id_tool
};
$.ajax({
url: '/Schedules/actionEditStuff',
type: "POST",
data: data,
contentType: 'application/json; charset=utf-8',
success: function (view) {
//load returned data into div? or popup?
}
, error: function (xhr, status, error) {
...
}
});
...
and your controller action
public ActionResult actionEditStuff(....parameters...)
{
...
...do your magic ...
return PartialView("~/Views/_PartialViewThatShowsSomething.cshtml", ...pass model...);
}

JavaScript URL issue with Permalinks enabled

I am using the following JavaScript function to fetch the data using ajax call
function findName() {
var name = "Jhon";
$.ajax({
method: "POST",
url: "oc-content/themes/bender/ajax-test.php",
data: { name : name },
success: function (data) {
alert(data);
},
})
}
It calls the following php file and works fine.
http://127.0.0.1/osclass/oc-content/themes/bender/ajax-test.php
But when I enable SEO friendly Permalinks in my CMS current page URL is appended in start of link and I get the following error in Chrome Console.
GET http://127.0.0.1/osclass/fashion-beauty/oc-content/themes/bender/ajax-test.php?name=Jhon 404 (Not Found)
Anybody tell me how to solve this issue?
The url you've provided in the ajax call is document relative. When you changed the server's url generation scheme, you also caused the url pointed at by the ajax call to change.
Adjust the ajax url, changing:
url: "oc-content/themes/bender/ajax-test.php",
To:
url: "/osclass/oc-content/themes/bender/ajax-test.php",
Why don't you make the URL server-relative? Something like this:
function findName() {
var name = "Jhon";
$.ajax({
method: "POST",
url: "/osclass/oc-content/themes/bender/ajax-test.php",
data: { name : name },
success: function (data) {
alert(data);
},
})
}
As you have not posted the php code. I would mention that any url directly navigated through addressbar of browser causes in the GET request and i can see you have a POST request in the ajax, so, it can't work.
Workaround would be to use $_REQUEST super globals at php end. $_REQUEST would work for $_GET/$_POST requests.

Call webservice at page load in AngularJS Framework scope

I have a webservice which returns Jsonobject and I call it in JS using Ajax like here :
$scope.init = function () {
$.ajax({
type: 'GET',
timeout: 1000000000,
url: serverName.replace('services', 'servicesV2') + '/getTreasuryResults',
data: { data: 'None' }, // the data in form-encoded format, ie as it would appear on a querystring
dataType: "text", // the data type we want back, so text. The data will come wrapped in xml
success: function (data) {
var dataAngularTreasury = JSON.parse(data);
alert(dataAngularTreasury);
//FillDefaultTreasuryValues(data.split(";"));
CallTreasuryDetailValuesWS(934);
},
error: function (data) {
alert(errServiceCall); // show the string that was returned, this will be the data inside the xml wrapper
$('#loading').hide();
}
});
};
If I call that init() function in ng-click like
<button id="btnGetDefaultValues" type="button" class="button" ng-click="init()">Fill</button>
It runs with no problem.
but if I call this webservice in page load like
angular.module('termDeposite', []).controller('userCtrl', function ($scope) {
$scope.treasuryValues = [];
angular.element(document).ready(function () {
$.ajax({
type: 'GET',
timeout: 1000000000,
url: serverName.replace('services', 'servicesV2') + '/getTreasuryResults',
data: { data: 'None' }, // the data in form-encoded format, ie as it would appear on a querystring
dataType: "text", // the data type we want back, so text. The data will come wrapped in xml
success: function (data) {
var dataAngularTreasury = JSON.parse(data);
alert(dataAngularTreasury);
//FillDefaultTreasuryValues(data.split(";"));
CallTreasuryDetailValuesWS(934);
},
error: function (data) {
alert(errServiceCall); // show the string that was returned, this will be the data inside the xml wrapper
$('#loading').hide();
}
});
});
});
or
if I call this webservice in ng-init trigger like
<body id="body" ng-app="termDeposite" ng-controller="userCtrl" ng-init="init()" >
webservice goes to error step and throws that error :
"\n\n\nError 404--Not
Found\n\n\n\n\n\nError 404--Not
Found\n\n\nFrom RFC
2068 Hypertext Transfer Protocol --
HTTP/1.1:\n10.4.5 404 Not Found\nThe server has not found anything matching the
Request-URI. No indication is given of whether the condition is
temporary or permanent.If the server does not wish to make this
information available to the client, the status code 403 (Forbidden)
can be used instead. The 410 (Gone) status code SHOULD be used if the
server knows, through some internally configurable mechanism, that an
old resource is permanently unavailable and has no forwarding
address.\n\n\n\n\n\n"
Finally, I can call a webservice with using ng-click but I can't call same webservice using ng-init or pageload. So how can I call a webservice using ajax in page init or page load in angular framework scope ?
Assuming you have serverName as a global and it is readable then the ng-init version or creating a custom directive and sticking the code in the link function should work.
Check the URL that is actually being called in the network tab in the Chrome dev tools (built into chrome) - cmd+alt+j on mac f12 on PC.

Firefox pop up "This web page is being redirected to a new location" on every requestPromise ajax call- is there any way to avoid?

I have a web app with a lot of AJAXing going on. In my original tests this was working fine, but in my testing today, Firefox (on both Mac & IE, on multiple computers), is giving a pop-up message "This web page is being redirected to a new location" for every single PUT & DELETE ajax call, which makes the page a totally unworkable mess. Interestingly, the pop-up does not occur on the GET calls.
The PUT & DELETE are both using an Angular Promise structure, while the GET uses a standard $.http call.
Here's the code of my GET, which does not trigger the pop-up:
$http({
method: 'GET',
url: $scope.faveURL
}).success(function (data, status, headers, config) {
if (data === "false") {
$scope.faveempty = true;
$scope.faveloading = false;
} else {
$scope.favourites = data;
$scope.faveloading = false;
}
});
And here's the code of my PUT & DELETE, which both do trigger the pop-up:
if (food.favourite === true) {
requestPromise = $http.put($scope.URL).then(function () {
$scope.favourites.push(food);
$scope.faveempty = false;
food.loading = "none";
change = $scope.favouriteChange(food);
});
} else if (food.favourite === false) {
requestPromise = $http({
method: 'DELETE',
url: $scope.URL
}).then(function () {
$scope.favourites.splice($scope.favourites.indexOf(food), 1);
if ($scope.favourites.length < 1) {
$scope.faveempty = true;
}
food.loading = "none";
change = $scope.favouriteChange(food);
});
}
Has anyone else experienced this problem while using requestPromise for Ajax calls? Have you found any work-arounds?
UPDATE:
Checking the Network traffic, this is only occurring on AJAX calls which respond with a redirect. This is fine, no pop-up:
[15:09:58.742] GET http://redacted/api/ext/group/35/ [HTTP/1.1 200 OK 381ms]
This causes a pop-up:
[15:03:25.036] PUT http://redacted/api/ext/favorite/713 [HTTP/1.0 301 TYPO3 RealURL redirect 126ms]
So it's a problem with the way the Typo3 services are responding to the PUT & DELETE methods, and Firefox just so happens to have dialog warning for this.
This may not directly help your case, but I was experiencing the same issue and it was due to me having the wrong request type. I am sure it may help others.
Bear in mind I am using jQuery.
Original code:
$.ajax({
url: link,
type: 'json',
success: function(html) {
return _this.ajaxLoadIn(html);
},
error: function(e) {
return alert('Sorry, something went wrong, please try again');
}
});
Resolved code:
$.ajax({
url: link,
dataType: 'json',
type: 'get',
success: function(html) {
return _this.ajaxLoadIn(html);
},
error: function(e) {
return alert('Sorry, something went wrong, please try again');
}
});
As you can see I was setting the wrong "type" parameter. It should have been GET or POST. Hopes this may shed some light.
It is likely your backend doesn't accept URLs without trailing slashes (in case you are using them) and when it meets such a request it tries to redirect you to the right URL (with a trailing slash). This attempt to redirect you to the right URL results in the popup. So make sure you are using URLs with trailing slashes.
Regarding AngularJS RESTful infrustructure, $resource by default removes trailing slashes, but you can turn them on (starting from AngularJS 1.3.0). See more details in the documentation

Accessing MVC Action from another application via javascript

I have an MVC 3 web app that has an Action which I need to access from a webform app via javascript.
My action returns a Json result, which I have checked works just fine. However, when accessing it with javascript from another application, I can see it reaching my action, doing all the work, returning my data, but the jquery function then gives me an error 200 and no data.
Example:
My MVC Action:
public ActionResult GetData(int categoryId)
{
var listofSeries = new List<string>
{
"foo1",
"foo2",
"foo3"
};
return Json(listofSeries, JsonRequestBehavior.AllowGet);
}
This returns me: ["foo1","foo2","foo3"]
Normally, my javascript function is used to query a database and get data back for a Highcharts chart but I have the same issue with this kind of example.
<script type="text/javascript">
$(document).ready(function () {
var foo = getData(9);
});
function getData(categoryId) {
var results;
$.ajax({
type: 'POST',
url: 'http://localhost:xxxx/Home/GetData',
//contentType: "application/json; charset=utf-8;",
async: false,
data: { "categoryId": categoryId },
dataType: "json",
success: function (data) {
console.log("results: " + data);
results = data;
}
});
return results;
}
</script>
With this I get:
http://localhost:63418/Home/GetData?categoryId=9 200 OK
results: null
If I add the contentType, I can't even see the function running in the firebug console, all I see is results: null. When I remove it I do but I get the error above.
I've been told it might not be doable because of "Cross-site scripting". And to instead have my javascript function call a webservice (or handler but I haven't quite figured out how to make one of those yet) that will then call my action, return my data to the service who then returns the data to the javascript.
But now I'm getting a 415 Unsupported Media Type error message when trying to connect to my webservice.
My IWebService.cs:
[ServiceContract]
public interface IWebService
{
[OperationContract]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "POST")]
void GetData(int mileId);
}
My WebService.svc:
public void GetData(int categoryId)
{
string url = "http://localhost:63418/Home/GetWoWData?categoryId=" + categoryId;
WebRequest wr = WebRequest.Create(url);
WebResponse response = wr.GetResponse();
}
I'm not returning anything yet, it won't even go in this function. Giving me the 415 error message.
If I change the contentType to "text/xml" I get an error 400.
I would really like to have this work without using the webservice, and figure why I get an error 200 OK when I can see the action running, but if that's not possible, any idea why the webservice isn't working?
Thanks.
string url = "http://localhost:63418/Home/GetWoWData?categoryId=" + categoryId;
WebRequest wr = WebRequest.Create(url);
wr.Credentials = CredentialCache.DefaultNetworkCredentials; // uses current windows user
var response = (HttpWebResponse)wr.GetResponse();
I only just remembered I had this post and found the solution a while ago. It was solved by adding the credentials (in my case the current windows user) and getting the response as an HttpWebResponse.
200 makes me think everything is working ok, but IE is using a cached result, i've run into this problem before with IE. try adding:
$.ajaxSetup({
// Disable caching of AJAX responses */
cache: false
});
this will make it append a random parameter, and will stop IE from being stupid.

Categories

Resources