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??
Related
I try to have more than one parameter in a POST from angular 9 to a .NET API controller
I get the error The JSON value could not be converted to Newtonsoft.Json.Linq.JToken
when sending my request, passing these arguments to my http post from angular 9
from:
return this.http.post<any>(environment.apiUrl + 'api/Partners/',partner : partner);
to
return this.http.post<any>(environment.apiUrl + 'api/Partners/',{partner : partner,manager : manager});
using the following code for the .NET controller
[HttpPost]
public async Task<ActionResult<int>> PostPartner([FromBody] JObject body)
{
Partner partner = body["partner"].ToObject<Partner>();
User manager = body["manager"].ToObject<User>();
...
JObject beeing from using Newtonsoft.Json.Linq
I know I can use System.text.json but I just don't find any example that fits my post function signature
any help appreciated
thanks
Instead of using Newtonsoft.Json.Linq.JObject, you should be able to use a model class which should contain both the Partner and the User properties like:
public class PostPartnerModel
{
public Partner Partner { get; set; }
public User Manager { get; set; }
}
and have your action like:
[HttpPost]
public async Task<ActionResult<int>> PostPartner([FromBody] PostPartnerModel model)
{
Partner partner = model.Partner;
User manager = model.Manager;
...
How would I create one controller with one API link in Web API 2 ASP.NET to respond on received data by an action that is in that data?
For example I receive this data:
{"t":"868efd5a8917350b63dfe1bd64","action":"getExternalServicePar","args":
{"id":"4247f835bb59b80"}}
and now I need to respond based on this "action" value. If there is some other action value like "incrementVallet" I need to respond with different data, and all that from one API link, etc.
The obvious question to ask is "Why would you want to do that?". Why not multiple methods or even multiple controllers? Having said that, you could do the following if you really want to:
public class ActionDetails
{
public string t { get; set; }
public string action { get; set; }
public ArgsContainer args { get; set; }
}
public ArgsContainer
{
public string id { get; set; }
}
Controller and method:
public class MyController : ApiController
{
// POST is not really the right choice for operations that only GET something
// but if you want to pass an object as parameter you really don't have much of a choice
[HttpPost]
public HttpResponseMessage DoSomeAction(ActionDetails details)
{
// prepare the result content
string jsonResult = "{}";
switch (details.action)
{
case "getExternalServicePar":
var action1Result = GetFromSomewhere(details.args.id); // do something
jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(action1Result);
break;
case "incrementVallet":
var action2Result = ...; // do something else
jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(action2Result);
break;
}
// put the serialized object into the response (and hope the client knows what to do with it)
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(jsonResult, Encoding.UTF8, "application/json");
return response;
}
}
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
When I have a return type of 'string' in my WebAPI controller, the SuccessStatusCode returns 'OK' in my MVC Controller, but when the return type is of a model named 'USER', I get this Internal Server Error. Here's my code:
WebAPI:
public class UserController : ApiController
{
OnlineCenterEntities db = new OnlineCenterEntities();
public USER GetUserInfo(string userName, string domain)
{
USER userInfo = (from u in db.USERs
where u.USER_NAME.ToUpper() == userName.ToUpper() && u.LDAP_NAME.ToUpper() == domain.ToUpper()
select u).FirstOrDefault();
return userInfo;
}
}
MVC Controller that calls the WebAPI:
public class HomeController : Controller
{
HttpClient client;
string url = "http://localhost:61566/api/user/";
public HomeController()
{
client = new HttpClient();
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<ActionResult> Index(string userName, string domain)
{
string GetUserInfoURL = String.Format("GetUserInfo?userName={0}&domain={1}", userName, domain);
HttpResponseMessage responseMessage = await client.GetAsync(url+GetUserInfoURL);
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
var userInfor = JsonConvert.DeserializeObject<USER>(responseData);
}
return View();
}
USER model:
public partial class USER
{
public int USER_ID { get; set; }
public string USER_NAME { get; set; }
public string FIRST_NAME { get; set; }
public string LAST_NAME { get; set; }
public string LDAP_NAME { get; set; }
public string EMAIL { get; set; }
}
In my WebAPI, if I change the return type from USER to string (and of course, change the return variable type to some string (userInfo.FIRST_NAME)), I get the SuccessStatusCode as 'OK', but as of this code, I get Internal Server Error with StatusCode: 500 (whatever that means). I have tried inserting breakpoint at every possible points, and I know that the api is returning the result fine. I simply don't understand why the following line
HttpResponseMessage responseMessage = await client.GetAsync(url+GetUserInfoURL);
gives InternalServerError error when I have the return type of USER, and return the whole USER model instead of just one string.
Please don't worry about the userName and domain parameters that I'm passing to the controllers, they are working fine!
Typically when this happens, it means it is failing to serialize the response. Once your controller returns a USER instance, somewhere WebAPI has to serialize that into the format requested by the client.
In this case the client requested "application/json". The default JsonMediaTypeFormatter uses JSON.Net to turn your C# object into json for the client. Apparently that serialization step is failing, but the response code doesn't tell you exactly why.
The easiest way to see exactly what is happening is to use a custom MessageHandler which forces the body to buffer earlier so you can see the actual exception. Take a look at this blog post for an example to force it to show you the real failure.
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) { }