Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call Api controller action from server side blazor Net Core 5.0?

I created a standard Blazor Server app. Then I added an API Controller with read/write actions.

Now I want to call an action from the index page, but it doesn't work. The app runs without error, but doesn't return the expected (status = "Waiting for activation", Method = "null" and result = "Not yet computed"). I put a breakpoint in the controller action, but the program never hits it.

Controller:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET: api/<ValuesController>
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET: api/<ValuesController>/5
    [HttpGet("{id}")]
    public string Get(int id)
    {
        return "value";
    }
}

Index page:

<button class="btn btn-primary" @onclick="RetrieveGet">
    GET
</button>

void RetrieveGet()
{
    HttpClient Http = new HttpClient();
    string baseUrl = "https://localhost:44382/";
    var temp2 = Task.Run(async () => { await Http.GetStringAsync($"{baseUrl}api/values/5"); });
}

Startup.cs (other items removed for brevity):

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
}
like image 610
Ben Junior Avatar asked Jan 27 '21 23:01

Ben Junior


1 Answers

Here is how you can do it.

1) Create a new Blazor Server app.

2) Add some extra configuration to the app's service collection.

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
            
    services.AddControllersWithViews();
    services.AddHttpClient("LocalApi", client => client.BaseAddress = new Uri("https://localhost:44333/"));
}

The only difference in the above code is:

services.AddControllersWithViews();

// You should change the URI based on your project's needs.
// It's best to get the URI from appsettings.json.
services.AddHttpClient("LocalApi", client => client.BaseAddress = new Uri("https://localhost:44333/"));

3) Configure the app's endpoints as follows:

app.UseEndpoints(endpoints =>
{
    // This is the line you need to add
    endpoints.MapControllers();

    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});

4) In your Blazor page you can use either of the following options to reach the API:

  • Use HttpFactory.
  • Create your own HTTP client.

Option 1: If you decide to use HttpFactory you should add the following code at the top of your page: @inject IHttpClientFactory ClientFactory

And inside your function use it as follows:

var clientlocal = ClientFactory.CreateClient("LocalApi");
var res = await clientlocal.GetStringAsync("api/values/5");

Of course you also need to change your function signature: async Task RetrieveGet()

Option 2: If instead you choose to create your own HTTP client, you will need to call your API as follows:

HttpClient Http = new HttpClient();
string baseUrl = "https://localhost:44333/";
var temp2 = await Http.GetStringAsync($"{baseUrl}api/values/5");

Of course you need to change your function signature: async Task RetrieveGet()

Here are screenshots for either approach. Note the same URL: Same URL

The app now hits your breakpoint, as expected: Calling the controller

And here is the return result: Return result

There you have it. Let me know if you have any questions.

like image 116
khaled Dehia Avatar answered Oct 19 '22 20:10

khaled Dehia