Posting data to asp.net Web API - c#

I'm trying to figure out the new ASP.NET Web API.
So far I've been able to create this method signature and connect to it just fine and get a valid response...
[HttpPost]
public HttpResponseMessage CreateAccount()
I am able to send a request to this method with fiddler and have verified that it is receiving the request.
However, when I try to pass data is when I am running into a problem.
The first thing I tried was...
[HttpPost]
public HttpResponseMessage CreateAccount([FromBody]string email, [FromBody]string password)
And I type
email:xyz,password:abc
into the body of the request in fiddler. When I do this I get a 500 error stating
'Can't bind multiple parameters ('email' and 'password') to the request's content.'
I have also tried this as a method signature...
[HttpPost]
public HttpResponseMessage CreateAccount([FromBody]UserAccountRequestData data)
with the UserAccountRequestData being a simple POCO
public class UserAccountRequestData
{
public string Email { get; set; }
public string Password { get; set; }
}
And I put
{Email:xyz,Password:abc}
or
data:{Email:xyz,Password:abc}
into the body of the request. In both cases trying to populate the POCO I am able to reach the method while debugging, but the data object is always null.
I need to understand how to create API methods that accept both strongly typed POCOs and others that accept multiple primitive types like strings and ints.
Thanks

You need to set the Content-Type header to application/json and then provide valid JSON.
{"Email":"xyz","Password":"abc"}

Related

C# .Net API Post Call Using HttpResponseMessage Post([FromBody] is always null

I'm new to writing .net APIs and I'm working in Visual Studio 2017. I've been working on this for a couple of days and I'm completely stumped. I'm trying to create a simple web API that a Post call sends a cXML string passed into it via the Post Body. I then take the incoming cXML string and simply save it to a text file on a network drive. That is all I need to do, I don't need to de-serialize the xml, read any of the fields or extract any data out of the XML, I just need to grab the entire input xml string and save it to a text file. The problem I'm having is no matter what I've tried the incoming body always seems to be null. My code is simple:
[HttpPost]
[Route("api/Pass_XML_to_File")]
public HttpResponseMessage Post([FromBody] dynamic IncomingXML)
{
//do work here: take Incoming xml string and save it to a file which should be simple...
}
Unfortunately my IncomingXML variable is always null, so I have no data to save into a text file. I've been testing this from Postman and no matter what I've tried the variable is always null.
I've tried many other ways such as
Post([FromBody] XmlDocument IncomingXML)
Post([FromBody] string IncomingXML), etc.
I've tried changing in Content-Type header in Postman from application/xml, text/xml, text and a few others without any success. The funny thing is if I pass a JSON string in the body (changing the Content-Type to text/JSON) the data comes in perfectly without issue. Just when I pass xml the incoming body is always null.
Does anyone know how I can get the body xml to come in as a string so I can simply save it to a text file for later processing on a separate system? Thank you all in advance for your assistance.
Can you post the form you sent on the client side?
[HttpPost]
[Route("api/Pass_XML_to_File")]
public HttpResponseMessage Post([FromBody] dynamic IncomingXML)
{
// data is coming in correctly.
return null;
}
Postman Client Send :
{
"IncomingXML":"<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don'tforgetmethisweekend!</body></note>"
}
data comes to variable successfully.
if you want to accept a xml format request, you should do the below steps:
Startup.ConfigureServices edit:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddXmlSerializerFormatters();
}
Apply the Consumes attribute to controller classes or action methods that should expect XML in the request body.
[HttpPost]
[Route("api/Pass_XML_to_File")]
[Consumes("application/xml")]
public HttpResponseMessage Post([FromBody] dynamic IncomingXML)
{
// data is coming in correctly.
return null;
}
Note: Install the Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet package.

Is there a way in Postman to store multiple values for one key?

I am working on side-project using ASP.Net Core web api. I am currently using Postman so I can interact with custom middleware. As you can see in the picture I have a User id and would like the request header to have more than one value for the user id key. Everytime I debug the api, the request header only counts one value instead of two values. I have looked at the Postman help page but it doesn't really cover any material regarding my issue. So to condense my question, is there a way in Postman that a key (For my scenario, User Id) can hold more than one value.
Your question doesn't really make sense. Postman will send the data you put, to the server. The data you put is "1,2". At the server end, if you pull the userId value and split it on the comma, you have your two values, no?
I find it incredibly unlikely that when you pull userId at the server, the value of the header is "1" and the other id has disappeared. If the web did that loads of headers (such as your gzip, deflate, br there) would get lost and stuff wouldn't work properly
In java with spring boot framework i have idea about it we have to send List userIds from request controller method this method you have to take as post method and send that data into body part with
#PostMapping("/listUsers")
public String getList(#RequestBody List<Integer> userIds) {
// call service method
return "page";
}
Json Request from postman
{
1,2,3,4,5............
}
In dot net core
[Produces("application/json")]
[Route("api/accounts")]
public class AccountsController : Controller
{
[HttpGet]
[Route("servicesbycategoryids")]
public IActionResult ServicesByCategoryIds([FromQuery] int[] ids)
{
return Ok();
}
}

How to verify Slack Events API Request Url in ASP.Net Core Mvc application?

I'm working on Slack integration in an ASP.Net Core MVC 2 application.
I have done it for Searching and Posting messages to Slack channels. Now I'm stuck at integrating Events API in this application. Basically, at the moment I'm not able to verify my Request Url as mentioned here Events API Subscription
Following is my action method that we have give to Slack where they will send the verification json object which will be mapped to request parameter of my action and is as follows:
{
"token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
"type": "url_verification"
}
[HttpPost]
public IActionResult Event(EventsRequest request)
{
if (request != null)
{
if (request.type.Equals("url_verification"))
return Content(request.challenge);
else
ViewBag.Challenge = request.challenge;
}
return View();
}
Here is my EventsRequest class:
public class EventsRequest
{
public string token { get; set; }
public string challenge { get; set; }
public string type { get; set; }
}
I have deployed this application locally on IIS and have applied InBound rules to make it accessible publicly and it is accessible. But issues arise when I give the following URL to Slack for verification:
http://IP_Address/Slack/Event
Following is the screenshot of the response that Slack gives
Can someone tell what's wrong here? I tried to hit this URL with Postman and I was able to get the desired results.
You can try these:
As suggested in https://api.slack.com/events-api#subscriptions
Your Event Request URL must be confirmed before saving this form. If
your server takes some time to "wake up" and your initial attempt at
URL verification fails due to a timeout, use the retry button to
attempt verification again.
If it fails at first attempt make sure server is up & running and try next time.
After you've completed typing your URL, we'll dispatch a HTTP POST to
your request URL. We'll verify your SSL certificate and we'll send a
application/json POST body containing three fields:
{
"token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
"type": "url_verification"
}
You need to replace example json with the real values generated for you url configuration and verification.
Make sure url for verification is set correctly before generating challenge and is not changed afterwards.
Make sure no mismatch in url scheme like http in one place and https at other.
Try adding from body in post request:
[HttpPost]
public IActionResult Event([FromBody]EventsRequest request)

How to handle PostJsonAsync() call

Currently I have 3rd party WebApi which has the following external call using Flurl builder.
await _client.Url.ToString().PostJsonAsync(data);
And I'm trying to handle the response with such endpoint:
[HttpPost]
public void HandleResponse(HttpResponseMessage response)
{
}
The response message is with status OK but has Content and Headers = null
How can I handle this properly?
This API endpoint doesn't make any sense to me:
[HttpPost]
public void HandleResponse(HttpResponseMessage response)
{
//...
}
The endpoint would be handling a request and returning a response, not the other way around. Something more like this:
[HttpPost]
public HttpResponseMessage HandleResponse(HttpRequestMessage request)
{
//...
}
When something contacts an API (or server of any kind, really), it's sending a request to that API. That API receives the request and returns a response. The semantics of these two words pretty much describe the process, it's very important to keep them straight.
Consider it like this... If someone asks you a question, what you receive is a question. Not an answer. What you send back to that person is the answer.

In MVC, how do I pass in form data as query strings?

I want to make it so that when people search for something, what they searched gets added to the url of the next page. So they can favorite the page, and then access the page again without filling in the form again. All the posts I can fine assume I want to pass in hard coded query string parameters.
When you send an HTTP POST request, the data that the client send to the server are stored in the request's body.
While, when you send an HTTP GET request, you can send data to the client that are in the query string (after the question mark, ?, in form of key/value pairs, ?name=test&age=21) of your url.
That being said, you have to add a filter to your ActionResult method in your controller that allows only HTTP GET request to reach it. For instance, you need something like this:
public class HomeController : Controller
{
[HttpGet]
public ActionResult ActionName(string name, int age)
{
}
}
Then the client can make a GET request using the following url:
www.domain/Home/ActionName?name=test&age=21

Categories