3

I have done some searching and nothing seems to help.

My angular looks like this with username being a string.

getUser(username = null) {

if (username == null) {
  username = this.cookie.getCookieValue("username");
}
console.log(JSON.stringify({ username: username }));
console.log("passing in "+ username);

return this.http.post<User>(this.userBackendUrl + "/user", username, httpOptions).pipe(map(user => {
  console.log("Successfully got the user!");
  console.log(user);
  return user;
}));}

Backend method looks like

public ActionResult GetUser(string username)
    {

I can hit my method but my username string in the backend is always null.

Adrian
  • 807
  • 2
  • 12
  • 25
Lionel
  • 31
  • 1
  • 8

3 Answers3

1

Depending how the string is sent with the request you have to do the following:

Sent as a plain string

If your username or string is sent as plain string in the request like the following:

"testuser"

Then you can add the [FromBody] attribute to a string parameter in the controller, like the following:

public ActionResult GetUser([FromBody] string username)
{
   //...
}

If your username or string is not sent as "testuser" pass the variable or string to the JSON.stringify method like this:

return this.http.post<User>(this.userBackendUrl + "/user", JSON.stringify(username), httpOptions) //...

Sent as a JSON object

If your username or string is sent as a JSON object in the request like the following:

{
   username: "testuser"
}

Then you need to create a seperate class (a DTO for example, GetUserRequest) tp bind to, which should look like this:

public class GetUserRequest
{
   public string Username { get; set; }
}

Later you can bind the model (your sent JSON object) to this class, again with providing the [FromBody] attribute and a parameter with the created class as the data type, like the following:

public ActionResult GetUser([FromBody] GetUserRequest user)
{
   //...
}

Multiple parameters without creating an extra class/DTO

As Lionel asked here are two ways I know how you can bind to multiple parameters without creating an extra class or a DTO.

Unfortunately, you can not bind the [FromBody] to multiple parameters to my knowledge.

But there are the following two ways:

Send data as form url encoded

If you send the data form url encoded you can bind the data/parameters with the [FromForm] attribute like the following:

Send the data as form url encoded:

username=test&email=test%40gmail.com&created=2018-08-07T15%3A02%3A00.736Z

Bind data with [FromForm] attribute:

public ActionResult GetUser([FromForm] string username, [FromForm] string email, [FromForm] DateTime created)
{
   //...
}

Send data as JSON object and bind with Newtonsoft

Another way would be using the JObject of Newtonsoft. This way is a little less intuitive to my opinion.

You would send the data as a normal JSON object like the following:

{   
   "username": "test",  
   "email": "test@gmail.com",   
   "created": "2018-08-07T14:53:54.639Z"
}

And then you would bind the data to a single JObject with a [FromBody] attribute and then bind the data to seperate variables like the following:

public void GetUser([FromBody] JObject requestBody)
{
   string username = requestBody["username"].ToString();
   string email = requestBody["email"].ToString();
   DateTime created = requestBody["created"].ToObject<DateTime>();
}
Adrian
  • 807
  • 2
  • 12
  • 25
  • That didn't work do I need to add something to my route? Because my route attribute looks like this [Route("user")] and attribute looks like this [HtttpPost] – Lionel Aug 07 '18 at 11:56
  • No that should be correct as you said that you can hit the method. What type is the username variable in the angular code (the one you send on the post request)? Is it a plain string or a JSON object? – Adrian Aug 07 '18 at 11:58
  • It's a plain string, here I will update my code on here – Lionel Aug 07 '18 at 12:02
  • Are you using ASP .NET or ASP .NET Core? – Adrian Aug 07 '18 at 12:05
  • I am using .netcore – Lionel Aug 07 '18 at 12:33
  • I think you get null because your string is maybe sent differently as you think in the request. Review my updated answer and also try to check how the string is sent using the developer tools maybe – Adrian Aug 07 '18 at 13:04
  • @Lionel check [this](https://stackoverflow.com/questions/41559050/string-value-is-empty-when-using-frombody-in-asp-net-web-api/41559569#41559569). Try sending a hardcoded value with double quotes to see if it solves your problem – Tim Martens Aug 07 '18 at 13:15
  • Thanks @adiii4 , just curious how would I be able to pass in more data in the future? like void getInfo(string name, string email) without having to create an object – Lionel Aug 07 '18 at 14:03
  • @Lionel I updated my answer with two ways I know how you could do it. – Adrian Aug 07 '18 at 15:14
0

modify your c# method like below

    [Route("GetUser/{username}")]
    [HttpPost]
    public ActionResult GetUser(string username)
    {
       //code
    }
Midhun P
  • 126
  • 1
  • 11
0

Send as form data in Angular:

const formData = new FormData();
formData.append("userName", userName);
return this.http.post<any>(url, formData);

And add FromForm in ASP.NET, with the same parameter name(userName):

public IActionResult GetUserName([FromForm] string userName) {
Jose
  • 1,857
  • 1
  • 16
  • 34