How can we support ajax post?
This the server code:
[RoutePrefix("api/Dashboard")]
public class PatientDashboardController : ApiController
{
[Route("UpdatePatientById")]
[HttpPost]
public IHttpActionResult UpdatePatientById(int? pk, string name, object value )
{
return Ok(name);
}
}
This is what I post to the server
Request URL:http://localhost/mydomain/api/Dashboard/UpdatePatientById
Request Method:POST
name:sex
value:1
pk:1093
I'm using x-editable plugin on the front end, it does the ajax post automatically. I don't think there is anything wrong with the post url.
This the error it gives me:
"No HTTP resource was found that matches the request URI 'http://example.com/mydomain/api/Dashboard/UpdatePatientById'."
MessageDetail: "No action was found on the controller 'Dashboard' that matches the request."
Web API can only receive one parameter from the body so you'll have to specify it as a type that aggregates those fields.
class PatientParameters
{
public int? Pk { get; set; }
public string Name { get; set; }
public object Value { get; set; }
}
and pass that:
public IHttpActionResult UpdatePatientById([FromBody] PatientParameters parameters) { }
Related
I'm working on a simple notes api, I'm trying to create a Put method to update a note in my notes list, but when I try to update any note through the SwaggerUI I get a the 404 status code. I think that I'm missing something in the structure.
This is my [HttpPut] request:
[HttpPut("{id}")]
public IActionResult Put([FromBody] Note requestParam)
{
if (!ModelState.IsValid)
{
return BadRequest("Not a valid model");
}
using (_datacontext)
{
var ExistingNote = _datacontext.Note.Where(n => n.Id == requestParam.Id)
.FirstOrDefault<Note>();
if (ExistingNote != null)
{
ExistingNote.Title = requestParam.Title;
ExistingNote.Description = requestParam.Description;
ExistingNote.Completed = requestParam.Completed;
_datacontext.SaveChanges();
} else
{
return NotFound();
}
}
return Ok();
}
My DataContext:
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> option) : base(option)
{
}
public DbSet<Note> Note { get; set; }
}
And lastly my Note Model:
public class Note
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool Completed { get; set; }
}
After looking for different examples I haven't found a standard approach so I'm not sure what to do about it
I've researched about Http bodies since it seemed like it needed to be part of the request but still get the error code. What could be wrong with it? (Both post and get methods work!).
Also, the error code:
When using the [HttpPut("{id}")] attribute on your controller, you need to add a parameter to the controller method's signature:
IActionResult Put([FromRoute] int Id, [FromBody] Note requestParam)
You can then call the API like this when Id=123
PUT http://{base-url}/123
Then you need to query the data context using the id from the route (which means you can remove it from the body)
On the other hand, if you don't want the Id as part of the request URL and keep it in the body, you need to remove the Id from the route template:
[HttpPut] without {id}.
Needless to say, make sure the Id actually exists in the data context. Otherwise your code will return, yes, a 404.
I have an ASP.Net Core application which needs passing of a model from one action to another.
These are models :
public class ClassA
{
public string Id{get;set;}
public string Name {get;set;}
public StudentMarks Marks {get;set;}
}
public class StudentMarks
{
public int Marks {get;set;}
public string Grade {get;set;}
}
And the post Controller:
[HttpPost]
public ActionResult TestAction1(ClassA model)
{
return RedirectToAction("TestAction2", model);
}
public ActionResult TestAction2(ClassA model)
{
}
In TestAction 1 while debugging, i see that Id, Name and marks have value.
I am getting the value for Id in TestAction2 same as that in TestAction1. However the value of complex object Marks is not obtained in the TestAction2 action method.
What are my other options?
You cannot redirect with a model. A redirect is simply an empty response with a 301, 302, or 307 status code, and a Location response header. That Location header contains the the URL you'd like to redirect the client to.
The client then must make a new request to that URL in the header, if it so chooses. Browsers will do this automatically, but not all HTTP clients will. Importantly, this new request is made via a GET, and GET requests do not have bodies. (Technically, the HTTP spec allows for it, but no browser or HTTP client out there actually supports that.)
It's unclear what your ultimate goal is here, but if you need to persist data temporarily between requests (such as a redirect), then you should serialize that data into a TempData key.
You can use TempData to pass model data to a redirect request in Asp.Net Core In Asp.Net core, you cannot pass complex types in TempData. You can pass simple types like string, int, Guid etc. If you want to pass a complex type object via TempData, you have can serialize your object to a string and pass that. I have made a simple test application that will suffice to your needs:
Controller:
public ActionResult TestAction1(ClassA model)
{
model.Id = "1";
model.Name = "test";
model.Marks.Grade = "A";
model.Marks.Marks = 100;
var complexObj = JsonConvert.SerializeObject(model);
TempData["newuser"] = complexObj;
return RedirectToAction("TestAction2");
}
public ActionResult TestAction2()
{
if (TempData["newuser"] is string complexObj )
{
var getModel= JsonConvert.DeserializeObject<ClassA>(complexObj);
}
return View();
}
Model:
public class ClassA
{
public ClassA()
{
Marks = new StudentMarks();
}
public string Id { get; set; }
public string Name { get; set; }
public StudentMarks Marks { get; set; }
}
public class StudentMarks
{
public int Marks { get; set; }
public string Grade { get; set; }
}
If you want to persist your TempData values for more requests you can use Peek and Keep functions. This answer can give more insight on these functions.
I think you're getting model and routeValues mixed up. The overload of RedirectToAction that you're calling (takes a string and an object) expects a routeValues argument, not a model argument. https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.redirecttoaction?view=aspnetcore-2.2
TestAction1 is called via Post, but TestAction2 is called via Get. You need to work out a URL that will let you call TestAction2 the way you want (independently of the RedirectToAction in TestAction1). I'm guessing this will involve setting up a custom route. Once you have a URL that will let you call TestAction2 the way you want, you can specify the route values to form that URL in the RedirectToAction in TestAction1.
I think the problem is that you shuold use:
return RedirectToAction("TestAction2", model);
(you did this without return)
Following is my get method in ASP.NET Web API.
[HttpGet]
public IHttpActionResult GetDetails([FromBody] RetrieveDetails eDetails)
{}
following is the class
public class RetrieveDetails
{
public string name{ get; set; }
public string Type { get; set; }
}
When I try to call GetDetails from Fiddler eDetails is always null.
http://localhost:101222/api/emailservice/GetDetails?name=testname&Type=testtype
I tried different methods but the value is always null.
If I change [HttpGet] to [HttpPost] and add the request body its working fine. But I need get method.
Do you need [FromBody] there if you are passing values in URL for GET. You should be using [FromUri] if you are passing values in querystring.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
This question already has answers here:
Angular2 HTTP Post ASP.NET MVC Web API
(7 answers)
Closed 6 years ago.
I have a WebAPI controller
public class MyController : ApiController
{
[HttpPost]
public SomeResult MyAction(string name, string message)
{
return SomeResult.???;
}
}
I have an angular controller calling this method
$http
.post("/api/My/MyAction", { name: "bob", message: "hello" })
.then(function(xhr) { ... }, function(xhr) { ... });
I get this result
Server Error in '/' Application.
The resource cannot be found.
What did I do wrong?
P.S. It's not the URL...It works when I use HttpGet and append the parameters to the query string.
For more than one attribute for post requests, you can use [FromBody] in your controller and make a ViewModel class. Example:
[HttpPost]
public HttpResponseMessage UpdateNumber([FromBody]UpdateNumberViewModel model)
{
//To do business
return Request.CreateResponse(HttpStatusCode.OK);
}
UpdateViewModel:
public class UpdateViewModel
{
public int Id{ get; set; }
public string Title{ get; set; }
}
Angular:
var model = {
Id: 1,
Title: 'Vai filhão'
}
$http.post('/api/controller/updateNumber/',model).then(function () { alert("OK"); }, function () {alert("something wrong"); });
You can see more details about how web api it works here: https://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
I've faced that problem, if you google there are different ways to solve it. One of the easiest requires to use only one input object in you WebApi controller, so in you case just crate a class
public class InputData {
public string name { get; set; }
public string message { get; set; }
}
Then change your input to the new create object with [FromBody] prefix (maybe not mandatory, see #ADyson comment)
public SomeResult MyAction([FromBody]InputData inputData)
My issue is to get my ASP.NET web API to deserialize the JSON data I provide in the request body, when calling the following controller on my API:
[HttpPost]
public IEnumerable<Notification> SearchNotifications(IEnumerable<SearchQuery> searchCriteria, int lastRow)
{
INotificationService notificationService = new NotificationService();
return notificationService.GetNotificationsFiltered(searchCriteria, User.UserData, lastRow);
}
The SearhQuery class looks like this:
public class SearchQuery
{
public string Filter { get; set; }
public string Value { get; set; }
}
The JSON data I provide in the request body (in Fiddler) looks like this:
{"searchCriteria":[{"filter":"category","value":"all_unread"}], "lastrow":60}
I get a 404: No HTTP resource was found that matches the request URI
Any ideas how to troubleshoot this further??