0
votes

I am just adding data from blazor to api. I check the data is bound and not empty but when It arrives the controller it always null. this is just easy api request.

I am just adding data from blazor to api. I check the data is bound and not empty but when It arrives the controller it always null. this is just easy api request.

[HttpPost]
    public async Task<ActionResult> AddRole(string roleName)
    {
        if (roleName != null)
        {
            await _roleManager.CreateAsync(new IdentityRole(roleName.Trim()));
        }
        return Ok();
    }

Blazor code

 @page "/role"
@inject HttpClient client
@inject IJSRuntime js

<h3>Roles</h3>
<small>Add as many role as you wish.</small>
    <div class="form-group">
        <input @bind:event="oninput" @bind="roleName" />
        <a>@roleName</a>

    </div>
    <button type="submit" @onclick="AddNewRole" class="btn btn-success">
        Submit
    </button>

<br>

@if (roles == null)
{
    <text>Loading...</text>
}
else if (roles.Length == 0)
{
    <text>No Records Found.</text>
}
else
{
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Id</th>
                <th>Role Name</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (RoleDto role in roles)
            {
                <tr>
                    <td>@role.Id</td>
                    <td>@role.Name</td>
                    <td>
                        <button class="btn btn-danger" @onclick="@(() => ManagePermission(role.Id))">Manage Role</button>
                        <a class="btn btn-success" href="role/edit/@role.Id">Edit</a>
                        <button class="btn btn-danger" @onclick="@(() => Delete(role.Id))">Delete</button>
                    </td>
                </tr>
            }

        </tbody>
    </table>
}
@code {
    RoleDto[] roles { get; set; }
    string roleName { get; set; }
    protected override async Task OnInitializedAsync()
    {
        roles = await client.GetFromJsonAsync<RoleDto[]>("api/roles");
    }

    async Task AddNewRole()
    {
        await client.PostAsJsonAsync("api/roles", roleName);
        await OnInitializedAsync();
    }

}
2

2 Answers

1
votes

You need to tell the framework where the parameter string role is coming from in your endpoint.

Try this instead:

public async Task<ActionResult> AddRole([FromBody] string roleName) { ... }

It would be more formal to have an actual model being passed instead of a string. So you should look in to something like this:

public sealed class SubmitRoleNameModel
{
    public string RoleName { get; set; }
}

Then your endpoint would look like this:

public async Task<ActionResult> AddRole([FromBody] SubmitRoleNameModel roleName) { ... }

and you'd call it as so:

await client.PostAsJsonAsync("api/roles", new SubmitRoleNameModel { RoleName = roleName });
0
votes

Couple of things I personally would do that may help/solve your problem:

  1. Encapsulate the data you are posting in and object.

    • This is an overall good practice, allows you to pass multiple values, and allows for validation
  2. Decorate your method parameter with [FromBody].

    • This instructs the framework where the data is located
  3. Make certain the controller is decorated with [ApiController] attribute

    • This implements things like binding and routing by default

Example method

[HttpPost]
public async Task<IActionResult> AddRole([FromBody] RoleRequest request)
{
    ///code for creating a role
}

Example request object

public class RoleRequest
{
      public string Name { get; set; }
}

Microsoft Documentation that further explains controller implementation:

https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-5.0