Creating post web api 2 actions - asp.net-web-api2

I am currently attempting to do something that should be fairly straight forward, but to be honest is pretty far from it at the moment and its driving me a bit mad.
I've been consuming Get actions in my WebApi, however I'm trying to create Post actions in order to keep my mvc controllers clean however I can't for the life of me figure out why my get actions work as expected but my post action results in a 404
using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Mvc;
using TamWeb.Models.api;
namespace TamWeb.Controllers.api
{
[Authorize]
[Route("api/[controller]")]
public class AdminController : Controller
{
[HttpPost]
public bool UpdateDetails([FromBody]DetailsViewModel model)
{
return false;
}
}
}
using System;
namespace TamWeb.Models.api
{
public class DetailsViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
The api controller is as simple as it gets and as per several other api questions instead of using string parameters I've created a model object and to follow other answers and what little out of date documentation I can find I consume the api as follows:
$(function() {
var firstname = $('#firstName').val();
var lastname = $('#lastName').val();
$.ajax({
url: "api/admin/UpdateDetails",
type: "POST",
data: JSON.stringify([firstname, lastname]),
success: function(data) {
console.log(data);
},
error: function() { console.log("error") }
});
});
As far as I can tell everything "should" work, however fiddler keeps telling me the url doesn't exist so now I'm at a loss as to whats wrong.

hopefully my answer can help you to deal with your question.
1.first issue you have to use "ApiController" instead "Controller"
2. [Authorize] <-- you have to get token key and then using it to get data from webapi
as following code, I will share you me simple code without Authorize,I wish it can solve your problems
client code
$("#read1").click(function () {
$.support.cors = true;
$.ajax({
crossDomain: true,
url: 'http://localhost:43520/api/Banners/',
datatype: "json",
contenttype: "application/json; charset=utf-8",
data: { id: 123 },
type: 'post',
error: function (xhr, status, errorThrow) {
alert(xhr.status);
},
success: function (data) {
alert(JSON.stringify(data));
}
});
});
server code
// GET: api/Banners/5
[ResponseType(typeof(Banners))]
public IHttpActionResult GetBanners(int id)
{
Banners banners = db.Banners.Find(id);
if (banners == null)
{
return NotFound();
}
return Ok(banners);
}

Related

ASP.NET Core AJAX POST not returning error, however, not saving data

I am using a button OnClick event to try and save a record to a database using AJAX in ASP.NET Core. The function is not returning an error, however, the data is not being saved. I am just trying to test with hard coded data first. A record with AdapollingProjectProcessStatusId = 1 exists in the database.
function SendHtmlEditorValueToController(data) {
$.ajax({
type: 'POST',
url: '#Url.Action("AJAXPost", "LiveAdapollingProjectProcessStatus")',
contentType: "application/json",
data: JSON.stringify({ "id": 1, "status": 'test'}),
dataType: 'json',
success: () => {
console.log("value is sent");
},
error: (error) => {
console.log(JSON.stringify(error));
}
});
}
LiveAdapollingProjectProcessStatusController:
[HttpPost]
public JsonResult AJAXPost(int id, string status)
{
LiveAdapollingProjectProcessStatus processstatus = new LiveAdapollingProjectProcessStatus
{
AdapollingProjectProcessStatusId = id,
AdapollingProjectProcessStatus = status
};
//save it in database
return Json(processstatus);
}
LiveAdapollingProjectProcessStatus.cs:
namespace CPSPMO.Models.PMO
{
public partial class LiveAdapollingProjectProcessStatus
{
public int AdapollingProjectProcessStatusId { get; set; }
public string AdapollingProjectProcessStatus { get; set; }
}
}
Please let me know if you are able to help me with this AJAX Post.
Thanks
Not sure how do you store it to the database, but the way you pass parameter to backend by ajax should be like below:
function SendHtmlEditorValueToController(data) {
$.ajax({
type: 'POST',
url: '#Url.Action("AJAXPost", "LiveAdapollingProjectProcessStatus")',
//contentType: "application/json", //remove this...
data:{ "id": 1, "status": 'test'}, //modify here...
dataType: 'json',
success: () => {
console.log("value is sent");
},
error: (error) => {
console.log(JSON.stringify(error));
}
});
}
After reviewing the comments regarding missing code for saving the data in the database, I modified the controller:
[HttpPost]
public JsonResult AJAXPost(int id, string status)
{
LiveAdapollingProjectProcessStatus processstatus = new LiveAdapollingProjectProcessStatus
{
AdapollingProjectProcessStatusId = id,
AdapollingProjectProcessStatus = status
};
//save it in database
var result = _context.LiveAdapollingProjectProcessStatuses.Update(processstatus);
_context.SaveChanges();
return Json(processstatus);
}
It is saving the data to the database now. Thanks for the help

Why is the model binding not working? ASP.NET Core 5.0 RazorPages

ASP.NET Core 5.0 Razor Pages.
When posting the array, the model is not binding - value is showing empty array.
This is a JSON array posted using Ajax -
[
{ "Order":1, "FileName":"bbed5ecf-4133-4681-b0f3-c11366ad3186.jpg" },
{ "Order":2, "FileName":"737e60dc-0631-493d-947d-2f5948d7818c.jpg" },
{ "Order":3, "FileName":"6c76f9d1-44bd-4b80-926e-2ce4307eb30b.jpg"}
]
function UpdateImageOrder() {
$.ajax({
type: "POST",
url: "/property/imagesorter",
dataType: "json",
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
data: JSON.stringify(newOrderDictionary),
success: function (response) {
}
});
}
RazorPage action Method
public async Task OnPostAsync(ImageOrder[] data)
{
}
public class ImageOrder
{
public int Order { get; set; }
public string FileName { get; set; }
}
The data parameter of the POST should be the object value, not a stringified version of it. Try changing to:
...
data: newOrderDictionary,
...
Assuming newOrderDictionary is an array.
Considering using post to pass data, you need to add contentType:"application/json" in ajax.
$.ajax({
type: "POST",
url: "/?handler",
dataType: "json",
contentType:"application/json",
//...
});
In addition, add [FromBody] in the bakend.
public async Task OnPostAsync([FromBody]ImageOrder[] data)
{
}
Then, it can get the data.
Turns out that this works :
public async Task OnPostAsync(ImageOrder[] order)
{
}
function UpdateImageOrder() {
$.ajax({
type: "POST",
url: "/property/imagesorter",
dataType: "json",
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
data: {
order: newOrderDictionary
},
success: function (response) {
}
});
}

JSON not mapped to Class

I have a asp.net core 3.0 application with WebPages and I try to send a JSON via ajax to my handler. But the parameter is always null or just filled with the default values. I tried to if the JSON string from the post is parseable and it works when I parse manually.
This is my controller:
public void OnPost([FromBody]FilterModel filter)
{
Console.Write(filter);
}
This is the model class:
public class FilterModel
{
public DateTime TimeRangeFrom { get; set; }
public DateTime TimeRangeTo { get; set; }
public int CustomerId { get; set; }
}
The ajax request:
$.ajax({
url: "/CustomerOverview/Test",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({
CustomerId: customerId,
TimeRangeFrom: picker.startDate,
TimeRangeTo: picker.endDate
}),
beforeSend: function(xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function(response) {
button.hide();
},
failure: function(response) {
alert(response);
}
});
And the JSON as logged in Chrome Dev Tools:
{CustomerId: "1", TimeRangeFrom: "2019-08-26T22:00:00.000Z", TimeRangeTo: "2019-09-25T21:59:59.999Z"}
Do I have to setup a mapping or something?
FromBody attribute will parse the model the default way which in most cases are sent by the content type application/json from the request body.So if you fill a form and pass the form data to the controller action,you need to convert the JavaScript object into a string with JSON.stringify().
FromForm attribute is for incoming data from a submitted form sent by the content type application/x-www-url-formencoded.
Reference:https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.0#sources
Turns out that it can't convert an "1" to an int. I had to convert the value for customerId to a int first so that I have this JSON:
{
"CustomerId": 1,
"TimeRangeFrom": "2019-08-26T22:00:00.000Z",
"TimeRangeTo": "2019-09-25T21:59:59.999Z"
}

Calling POST as URL ASP.NET web api

I want to know how to test POST by typing in the url.
Here's my route Config
config.Routes.MapHttpRoute(
name: "myWebApi",
routeTemplate: "api/mywebapi/{action}/{ID}/{DeptID}",
defaults: new { Controller = "mywebapi", ID = #"\d+", DeptID = #"\d+" }
);
programmatically this is how I call POST
I have 3 text boxes and a button. When user clicks on the button the below program gets called
function parseform(button) {
var id = $("#ID").val();
var deptid = $("#DeptID").val();
var name = $("#Name").val();
var inputdata = {
id: id,
deptid: deptid,
name: name
}
if (button.attr('value') === "POST") {
postdata(inputdata);
} else {
console.log("ERROR");
}
}
function postdata(inputdata) {
$("#response").text("Posted");
$.ajax({
type: "POST",
dataType: "json",
url: "api/mywebapi/Post/",
contentType: "application/json",
data: JSON.stringify(inputdata),
xhrFields: {
withCredentials: true
},
success: function (data, status, xhr) {
$("#response").text(status+" - "+data)
},
error: function (xhr, status, error) {
var json = jQuery.parseJSON(xhr.responseText);
$("#response").text(status)
}
});
}
In the controller
[System.Web.Http.AcceptVerbs("POST")]
public void Post([FromBody]mywebapi value)
{
saves to database
}
Here's what I tested
http://localhost:222/api/mywebapi/Post/new newwebapi ({"id":"1","deptid":"2","name":"testing"})
I get error. How to test this?
thanks
R
Since it's a POST request, you can't test it in your browser by typing in an address (those are GET requests, which contain no body).
To test these types of things you can use something like Postman
or Rest Console (if you're using chrome), there's tons of these types of things in whatever your browsers extension store is called.
Some tools you can use are something like Fiddler
this will let you see what the requests and responses look like, and you can change/modify them as well, though it's probably a bit harder to use than something like PostMan or Rest Console (also more powerful)

asp.net webapi validation

I have an API Controller and call action from JS:
$('#create-se').on('click', function () {
var data = {};
$.ajax({
url: 'api/registration',
type: 'POST',
data: data,
dataType: 'json',
contentType: 'application/json',
success: function () {
}
});
});
public bool Post(UserRegistrationViewModel model)
{
if (!ModelState.IsValid) { return false; }
return true;
}
Model has few required properties and few StringLength. When I send data from js to controller ModelState.IsValid always returns true. I can't figure out how to solve it. Even if posted model is null, Model.IsValid is true anyway
http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/
This website has a better way of doing validation and using headers to send the token across and if it invalid it will return validation failed.