How to post array of values to webapi? - c#

I am a newbie to C# am trying to post an array of values to a webapi POST method. Not sure how to go about this. This is what I have so far:
In the controller class:
namespace SATLyncWebService.Controllers
{
[RoutePrefix("lync")]
public class LyncController : ApiController
{
// POST: lync/search/
[HttpPost]
[Route("search")]
public void Post([FromBody]string value)
{
log.Info(value.ToString());
}
}
I get a NullReferenceException on the value field when I send a POST message as follows:
POST http://localhost:55129/lync/search
Application/json
["user1",
"user2 "
]
Thoughts?

I think that's because your signature is taking a single string as opposed to an IEnumerable (or any other sort of collection - List, []...) therefore webapi can't deserialize into that type

Related

Postman form-data works (WebAPI can parse 1) but raw data does not (WebAPI receives 0, instead of initial 1) in .NET 6.0 WebAPI controller GET request

I am using Postman to test my .NET 6.0 WebAPI.
When I try to process a form-data request, the WebAPI gets the original value of "parameter"
When I try to process a raw data request, the WebAPI gets the default value of "parameter"
This is the code of my .NET 6.0 controller:
[Route("[controller]")]
public class SiteInfoController : Controller
{
[HttpGet]
[AllowAnonymous]
[Route("Test")]
public IActionResult Test(int parameter)
{
return Ok($"response: {parameter}");
}
}
I added in Headers
Content-Type application/json
Accept application/json
but it didn't help me
Please help me to find the reason why form-data works (WebAPI can parse 1) but raw data does not (WebAPI receives 0, instead of initial 1) in .NET 6.0 WebAPI controller GET request.
You are trying to read an object from the body of a request. You must define said object and tell the framework where to read it from. And HttpGet can't have a body. You must use HttpPost or any other verb that can handle it:
[Route("[controller]")]
public class SiteInfoController : Controller
{
private sealed class MyParameter
{
public int Parameter { get; set; }
}
[HttpPost]
[AllowAnonymous]
[Route("Test")]
public IActionResult Test([FromBody] MyParameter parameter)
{
return Ok($"response: {parameter.Parameter}");
}
}
Make sure you change your PostMan script to use Post and not Get.

Is there a way to skip the url query parameter urlDecoding in ASP.NET Core for a specific controller/action method?

I have the following controller method:
public class MyApiController : Controller
{
[HttpGet("api/custom")]
public async Task<IActionResult> Custom(string data)
{
}
}
If I hit this action method with the following query param localhost:5000/api/custom?data=Y%3D%3DX then I get the value Y==X for my data parameter in the Custom method.
Is it possible to disable this decoding for this method only, so I can get the original unescaped value?
For ASP.Net Core if you need to encode the characters from a query parameter, you could use Uri.EscapeDataString(String) in this way:
string dataEncoded = Uri.EscapeDataString(data);
In your HttpGet request it would become:
public class MyApiController : Controller
{
[HttpGet("api/custom")]
public async Task<IActionResult> Custom(string data)
{
string dataEncoded = Uri.EscapeDataString(data);
}
}
You will still get the decoded string in the data parameter. To my knowledge, there isn't a way to completly disable URL Decoding on a specific controller.

Can't bind json in POST request body to class argument in .net-core

I'm trying to make a post request from my Angular frontend to the .net Core 3.1 backend, but in the controller method the argument object only gets by default 0 and null values;
let response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(obj)
});
[ApiController]
[Route("[controller]")]
[ApiExplorerSettings(IgnoreApi = true)]
public class RequestController : ControllerBase
{
[HttpPost]
public async Task<IAResponseViewModel> PostAnswer([FromBody] IAResponseViewModel something)
{
var temp = something.ToString();
if (!ModelState.IsValid)
{
Console.WriteLine();
}
return something;
}
}
public class IAResponseViewModel
{
public string AdministrationId { get; }
public int RoundUsesItemId { get; }
public int ResponseOptionId { get; }
}
The JSON object I see being submitted
{AdministrationId: "12345678-00e8-4edb-898b-03ee7ff517bf", RoundUsesItemId: 527, ResponseOptionId: 41}
When inspecting the controller method the 3 values of the IAResponseViewModel are null or 0
When I change the argument to object I get something with a value of
ValueKind = Object : "{"AdministrationId":"12345678-00e8-4edb-898b-03ee7ff517bf","RoundUsesItemId":523,"ResponseOptionId":35}"
I've tried with and without the [FromBody] attribute, changing the casing of the properties of the controller method's argument and the frontend argument, copy pasting the viewmodel attributes on to the submitted object keys, wrapping the posted object in a 'something' object. the ModelState.IsValid attribute shows as true.
I've red other answers such as Asp.net core MVC post parameter always null &
https://github.com/dotnet/aspnetcore/issues/2202 and others but couldn't find an answer that helped.
Why isn't the model binding working and how do I populate the viewmodel class I'm using with the json data?
From a comment on my original question:
Could it be because the properties in IAResponseViewModel are 'get only'?
Indeed this was the problem. Giving the properties (default) set methods fixed the problem.

webapi2 Binding not working

I'm new to webapi 2 and trying to get my api to bind to this call below.
Can anyone see what I'm doing wrong?
Call:
https://blabla.azurewebsites.net/myjohndeere/authenticated/e33dd8f74c97474d86c75b00dd28ddf8?oauth_token=1539dccf-d935-4d9e-83be-e00f76cabbb9&oauth_verifier=B22dWL
[RoutePrefix("myjohndeere")]
public class ApiMyJohnDeereController : ApplicationController
{
[HttpGet, Route("authenticated/{callbackId}")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(ApiResponseModel))]
[SwaggerResponse(HttpStatusCode.InternalServerError, "An unknown error occurred")]
[SwaggerResponse(HttpStatusCode.BadRequest, "Missing FieldMappings")]
public IHttpActionResult Authenticated(string callbackId,[FromUri]string oauth_token, [FromUri]string oauth_verifier)
{
...
}
First of, you missed the 'api' in the route.
Try it like this
https://blabla.azurewebsites.net/api/myjohndeere/authenticated/e33dd8f74c97474d86c75b00dd28ddf8?oauth_token=1539dccf-d935-4d9e-83be-e00f76cabbb9&oauth_verifier=B22dWL
Then, remove the FromUri attribute from your controller method. The attribute is not needed when just reading querystring of value types.
Try it like this
public IHttpActionResult Authenticated(string callbackId, string oauth_token, string oauth_verifier)
The issue was the Azure API gateway was still set to use PUT rather than GET.

ASP.NET WebApi not receiving post data

I need to receive some string and binary data using WebApi. I have created a controller this way:
[HttpPost]
public void Post(byte[] buffer)
{
// Some code goes here
}
Here's the routtings:
routes.MapHttpRoute(
name: "CuscarD95B",
routeTemplate: "D95B/{controller}",
defaults: new { buffer = RouteParameter.Optional },
constraints: new { controller = #"Cuscar" }
Now when I try to post some data, buffer is always byte[0] (zero length array). No data is being passed to the controller.
Any help would be appreciated.
Thanks.
If you are ever struggling with deserializing a body, try and do it manually to see if you are actually sending it correctly.
[HttpPost]
public void Post()
{
string body = Request.Content.ReadAsStringAsync().Result;
}
We passed Json object by HttpPost method, and parse it in dynamic object. it works fine. this is sample code:
ajaxPost:
...
Content-Type: application/json,
data: {"name": "Jack", "age": "12"}
...
Web API:
[HttpPost]
public string DoJson2(dynamic data)
{
string name = data.name;
int age = data.age;
return name;
}
If there is complext object type, you need to parse the dynamic type by using:
JsonConvert.DeserializeObject< YourObjectType >(data.ToString());
A complex data content sample is here, it includes array and dictionary object:
{"AppName":"SamplePrice","AppInstanceID":"100","ProcessGUID":"072af8c3-482a-4b1cā€Œā€‹-890b-685ce2fcc75d","UserID":"20","UserName":"Jack","NextActivityPerformers":{"39ā€Œā€‹c71004-d822-4c15-9ff2-94ca1068d745":[{"UserID":10,"UserName":"Smith"}]}}
I was able to post a byte[] in my request body, and the value was successfully model bound. Was the content-type set? Note that simple string is considered to be valid JSON here, and so it should work if your request's content-type is set to application/json...
Having said that, you can simply have your POST method that expects a string from the body instead of a byte[] and set the content-type to be application/json:
[HttpPost]
public void Post([FromBody]string buffer)
{
// Some code goes here
}
I am not sure how to send byte[] to webApi, but what you can do is to pass the binary data as Base64 string to your controller and then convert the base64 string to the byte[].
I found the solution here.
Looks like we need to create custom MediaTypeFormatter to achieve primitive type deserialization.
Did you try to use the HttpPostedFileBase without [FromBody] ?
public void Post(HttpPostedFileBase buffer)
I had a similar situation where I was using a string array and it would always come through null or I would get an exception about an improperly formatted request. I added the annotation [FromUri] in my method parameters then it worked. To give a little more context, my controller method looked like this before:
public async Task<IHttpActionResult> MyControllerName(List<string> id)
After:
public async Task<IHttpActionResult> MyControllerName([FromUri] List<string> id)

Categories

Resources