Getting Method Not Allowed when using AngularJS Delete - asp.net

I'll be glad to get your help. I'm using AngularJS version 1.6.5 and trying to use http delete method. On server side i'm using asp.net MVC5 Web API.
When i'm trying to delete a record i'm getting error 405 (Method Not Allowed).
This is my AngularJS code:
$scope.Delete = function (CustomerNumber) {
$http.defaults.headers["delete"] = {
'Content-Type': 'application/json,charset=utf-8'
};
$http({
method: "DELETE",
url: "/Api/Customer/" + CustomerNumber
}).then(function successCallback(response) {
$scope.Customers = response.data;
$scope.addCustomer.$setPristine();
$scope.addCustomer.$setUntouched();
$scope.Customer = {};
$scope.error = "";
}, function errorCallback(response) {
$scope.error = "Error on delete customer (" + response.status + ") - " + response.statusText;
});
};
and this is my asp.net code:
public List<Customer> Delete(string CustomerNumber)
{
DataLayer dal = new DataLayer();
CustomerViewModel cvm = new CustomerViewModel();
Customer cust = (from x in dal.Customers where x.CustomerNumber == CustomerNumber select x).ToList<Customer>()[1];
dal.Customers.Remove(cust);
dal.SaveChanges();
cvm.customers = dal.Customers.ToList<Customer>();
return cvm.customers;
}
I tried many ways and none of them worked. I would like to get your help.
Thank you.

Use JSON.stringify
$http({
method: "DELETE",
url: "/Api/Customer/" + JSON.stringify(CustomerNumber)
})

Related

Posting to Web API Controller from Razor Page Always Returns 400 Error

I am new to .Net Core and MVC. I've got several Razor Pages that allow users to post stuff like comments and ratings for individual posts, but I want to try something new for liking a post so that it can be done using javascript without refreshing the page. To do this I am trying to pass data from the page to a service class via an API controller using jQuery ajax. Unfortunately every time I try to pass a simple value to the controller I get a an error 400 saying that the value cannot be converted to System.WhateverObjectTypeITry. For instance if I try to pass it as an integer I get "The JSON value could not be converted to System.Int32" and if I try to pass it as a string I get "The JSON value could not be converted to System.String"
My API controller looks like this:
[HttpPost]
[Route("AddPostLike")]
public async Task<string> AddPostLike([FromBody] int postid)
{
if(_signInManager.IsSignedIn(User))
{
ApplicationUser user = await _userManager.GetUserAsync(User);
Likes newLike = new Likes();
newLike.Post = Convert.ToInt32(postid);
newLike.Commentid = null;
newLike.Userid = user.Id;
await _likeService.LikeAsync(newLike);
return $"liked";
}
else
{
return $"User Must Be Logged in to Like";
}
}
My jQuery in the Razor Page looks like this:
<script>
$(document).ready(function () {
$('#like-post').on('click', function () {
var postid = parseInt($('#idlabel').text());
$.ajax({
url: '/api/Likes/AddPostLike/',
type: 'POST',
dataType: 'text',
data: '{"postid":"' + postid + '"}',
contentType: 'application/json',
success: function () {
var likecount = parseInt($('#like-post-count').text());
likecount + 1;
$('#like-post-count').text(likecount);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("responseText=" + XMLHttpRequest.responseText + "\n textStatus=" + textStatus + "\n errorThrown=" + errorThrown);
}
});
});
});
</script>
I am using .Net Core 5.0 and am trying to use the Contoso Crafts demo as a guide, but the people at Microsoft that built Contoso Crafts decided to use a Blazor component instead of a razor page which somehow communicates with controllers despite not requiring the developer to write any javascript (see https://github.com/dotnet-presentations/ContosoCrafts/blob/master/src/Components/ProductList.razor) and they don't use a database to store data (they use a static JSON file), so I've had to go out and find a solution that might actually work in the real world.
Your [FromBody] attribute is saying that the body should be parseable as an integer, but the body is actually something like {"postid":"13"}.
The body is an object with a property named postId. So try defining that as your DTO:
public sealed class AddPostLikePostDto
{
public int PostId { get; set; }
}
...
public async Task<string> AddPostLike([FromBody] AddPostLikePostDto dto)
If you just want to post an Integer data, just change like below:
data: JSON.stringify(postid)
but the success function did not work.
That is because the counter does not increase, you can use likecount++ or likecount = likecount + 1 to make it work.
Another problem seems to be with the response from the controller which never tells people they must be logged in if the user is not signed in like it should.
That is because the else clause in your backend is a correct response for the ajax, you can simply throw an exception like:throw new Exception("User Must Be Logged in to Like");
Another way, you can change your code like below:
[HttpPost]
[Route("AddPostLike")]
public async Task<IActionResult> AddPostLike([FromBody] int postid)
{
if (xxx)
{
return Ok("liked");
}
else
{
//return $"User Must Be Logged in to Like";
return BadRequest("User Must Be Logged in to Like");
}
}
A whole working demo:
<label id="idlabel">1</label>
<label id="like-post-count" >4</label>
<input id="like-post" type="button" value="Post"/>
#section Scripts
{
<script>
$(document).ready(function () {
$('#like-post').on('click', function () {
var postid = parseInt($('#idlabel').text());
$.ajax({
url: '/api/Likes/AddPostLike/',
type: 'POST',
dataType: 'text',
data: JSON.stringify(postid), //change here....
contentType: 'application/json',
success: function () {
var likecount = parseInt($('#like-post-count').text());
likecount++;
$('#like-post-count').text(likecount);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("responseText=" + XMLHttpRequest.responseText + "\n textStatus=" + textStatus + "\n errorThrown=" + errorThrown);
}
});
});
});
</script>
}
Controller:
[HttpPost]
[Route("AddPostLike")]
public async Task<string> AddPostLike([FromBody] int postid)
{
if (xxxx)
{
return $"liked";
}
else
{
//return $"User Must Be Logged in to Like";
throw new Exception("User Must Be Logged in to Like");
}
}
In addition to fixing the way data can be sending to controller ( #StephenCleary already offered one of the possible ways), you have to fix a success function too by adding a result parameter
success: function (result) {
var likecount = parseInt(result).text());
likecount + 1;
$('#like-post-count').text(likecount);
},

JsonConvert.SerializeObject in Asp.Net MVC

Im retrieving data in database using ajax but when I'm calling the method in controller I getting an error in JsonConvert.SerializeObject(model, Formatting.Indented, new JsonSerializerSettings and I don't know why. Here's my code:
Views
function EditRecord(Id) {
var url = "/Admin/GetCategoryGroupById?Id=" + Id;
$("#ModalTitle").html("Update Category Group");
$("#MyModal").modal();
$.ajax({
type: "GET",
url: url,
success: function (data) {
var obj = JSON.parse(data);
$("#Id").val(obj.Id);
$("#Name").val(obj.Name);
//$("#Status option:selected").text(obj.tblDepartment.DepartmentName);
$("#cbStatus").val(obj.Status);
}, error: function (xhr, status, error) {
alert(error);
}
})
}
Controllers
public JsonResult GetCategoryGroupById(int Id)
{
CategoryGroup model = db.CategoryGroups.Where(x => x.Id == Id).SingleOrDefault();
string value = string.Empty;
value = JsonConvert.SerializeObject(model, Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return Json(value, JsonRequestBehavior.AllowGet);
}
The error:
Please help me. Thank you.
i think that your db doesn't have any CategoryGroups with the specified id. this is why the singleOrDefault returns null. so you need to add an if statement to check weather model is null

How do I pass along json patch data with rest client in asp.net?

We use a rest api to get customer information. A lot of the GET request were already written by others. I was able to follow their code to create other GET request, but one of the API methods for updating a customer requires using json patch. Below I have pasted in sample code of a current GET method, a Patch method (that I don't know how to implement) and a sample function written in javascript on how to use the json-patch that came from the api creators demo documentation:
public GetCustomerResponse GetCustomerInfo(CustomerRequest request)
{
//All of this works fine the base url and token info is handled elsewhere
var restRequest = CreateRestRequest($"customer/account?id={request.id}", RestSharp.Method.GET);
var response = CreateRestClient().Execute<GetCustomerResponse>(restRequest);
if (response.StatusCode == HttpStatusCode.OK)
{
return response.Data;
}
else
{
return new GetCustomerResponse(response.Content);
}
}
public EditCustomerResponse EditCustomer(EditCustomerRequest request)
{
var restRequest = CreateRestRequest($"customer/account?id={request.id}", RestSharp.Method.PATCH);
var response = CreateRestClient().Execute<EditCustomerResponse>(restRequest);
//how do I pass along json patch data in here???
//sample json might be like:
//[{'op':'replace','path':'/FirstName','value':'John'},{'op':'replace','path':'/LastName','value':'Doe'}]
if (response.StatusCode == HttpStatusCode.OK)
{
return response.Data;
}
else
{
return new EditCustomerResponse(response.Content);
}
}
//javascript demo version that is working
function patchCustomer(acctId, patch, callback) {
var token = GetToken();
$.ajax({
method: 'PATCH',
url: BaseURI + 'customer/account?id=' + acctId,
data: JSON.stringify(patch),
timeout: 50000,
contentType: 'application/json; charset=UTF-8',
beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', 'Bearer ' + token.access_token) },
}).done(function (data) {
if (typeof callback === 'function')
callback.call(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("Request failed: " + textStatus);
console.error(errorThrown);
failureDisplay(jqXHR);
});
}
This was pretty simple. After viewing similar questions on stackoverflow, I initially was trying something like this:
var body = new
{
op = "replace",
path = "/FirstName",
value = "John"
};
restRequest.AddParameter("application/json-patch+json", body, ParameterType.RequestBody);
It would not work. To get it to work, I added a patchparameters class with op, path and value properties, and then added a list property of type patchparameters to my EditCustomerRequest class and used it like this:
restRequest.AddJsonBody(request.patchParams);

Can't send data with $http.post in Ionic Framework

I'm trying make an application with Ionic framework which can take and send data to MS SQL server. For this I am using web api. I have no problem with taking data but something wrong with send new datas. Here is my ionic code :
angular.module('starter.controllers',[])
.controller('CheckListCtrl', function($scope, ChecklistService, $ionicPopup) {
function addCheck(){
ChecklistService.addCheck()
}
.factory('ChecklistService', ['$http', function ($scope, $http) {
var urlBase = 'http://localhost:56401/api';
var CityService = {};
CityService.addCheck = function(){
var url = urlBase + "/TBLCHECKLISTs"
var checkdata = {
AKTIF : true,
SIL : false,
KAYITTARIHI : Date.now(),
KULLANICIID : 3,
BASLIK : "Onur",
TAMAMLANDI : false,
TAMAMLANMATARIHI : null,
GUN : 1
}
var request = $http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: checkdata
});
return request;
}
return CityService;
}]);
And here is my web api:
[HttpPost]
[ResponseType(typeof(TBLCHECKLIST))]
public IHttpActionResult PostTBLCHECKLIST(TBLCHECKLIST tBLCHECKLIST)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
tBLCHECKLIST.KAYITTARIHI = DateTime.Now;
db.TBLCHECKLISTs.Add(tBLCHECKLIST);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = tBLCHECKLIST.TABLEID }, tBLCHECKLIST);
}
When i try to send i get this exception:
After, I realize that I take that exception because my checkdata is never come to web api. I don't know why.
These are not the datas I send:
I have tried different versions of post request but nothing. When I try to send data with PostMan, it works and I can insert data to my database. But why I can't do it with my application? Can anybody help me?
I think this should be the problem:
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
Try this:
return $http.post(url, checkdata);
And in your API:
[HttpPost]
[ResponseType(typeof(TBLCHECKLIST))]
public IHttpActionResult PostTBLCHECKLIST([FromBody]TBLCHECKLIST tBLCHECKLIST)
{
//code here
}
Also, make sure your checkdata properties match the ones in your TBLCHECKLIST c# type.

Using DOJO with RESTful web services

I have built a RESTful web service using ASP.NET HttpHandler, when running the web service project im redirected to the default page from which I can choose to download the DOJO code for my Client app.
here is a code snippet from the downloaded file:
function PickrWebService(){ self = this; }
PickrWebService.prototype = {
self: null,
urlString: "http://AYMAN/Handler.ashx",
CreateUser:function(Email,Username,Password,FirstName,Surname,Birth,Gender,Mobile,Picture,Address,successFunction,failFunction,token) {
var data = { 'interface': 'PickrWebService', 'method': 'CreateUser', 'parameters': {'Email':Email,'Username':Username,'Password':Password,'FirstName':FirstName,'Surname':Surname,'Birth':Birth,'Gender':Gender,'Mobile':Mobile,'Picture':Picture,'Address':Address}, 'token': token };
var jsonData = dojo.toJson(data);
var xhrArgs = {
url: self.urlString,
handleAs: 'json',
postData: jsonData,
load: successFunction,
error: failFunction };
var deferred = dojo.xhrPost(xhrArgs);
},
CheckUserExistence:function(Email,successFunction,failFunction,token) {
var data = { 'interface': 'PickrWebService', 'method': 'CheckUserExistence', 'parameters': {'Email':Email}, 'token': token };
var jsonData = dojo.toJson(data);
var xhrArgs = {
url: self.urlString,
handleAs: 'json',
postData: jsonData,
load: successFunction,
error: failFunction };
var deferred = dojo.xhrPost(xhrArgs);
}
}
I need help on how to use this code in my client app, and what does the parameter 'token' refer to?
The code is a javascript object for you service which you can call the webservice, by invoking the methods. token is not the part of dojo.xhrPost, it might be from the ASP.Net for passing authentication token. If you have not setup the security on the service, you could ignore it.
var successFunction = function(args){
//Handle the success response.
}
var failFunction= function(err){
//Handle the failure response.
}
var service = new PickrWebService();
service.createUser(Email,Username,Password,
FirstName,Surname,Birth,Gender,Mobile,Picture,Address,successFunction,failFunction);
Apart from the above code, you need to add the dojo api in you client.

Resources