Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add controller (not view) support to a server-side Blazor project

While my server-side Blazor app is running, I want some Javascript code in _Host.cshtml to be able to post data to a controller action. Of course, this happens completely outside of the scope of, and is unrelated to, the Blazor app itself.

I thought this would be a matter of adding calls to services.AddControllers() and endpoints.MapControllers() at the appropriate places in Startup.cs. However, after doing this, and implementing the controller action, I made the following observations:

  • Requests to the action are not routed and treated as "not found"
  • In Razor, @Url.Action on the controller action returns a blank string

How can I add controller (not view) support to my server-side Blazor project in a way that overcomes the above two issues?

like image 766
Pancake Avatar asked Feb 02 '20 01:02

Pancake


People also ask

Do you use controllers with Blazor?

If all you are ever doing is rendering pages server-side and interacting with them, then you can do this entirely through Blazor, with no need for controllers.

Can I use MVC in Blazor?

Blazor applications are component-based. Blazor components can be used in existing ASP.NET MVC applications.


1 Answers

Use: endpoints.MapControllers()

You can have this in your startup.cs:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });

This controller:

[Route("api/[controller]")]
[ApiController]
public class DownloadController : Controller
{
    private readonly IWebHostEnvironment environment;
    public DownloadController(IWebHostEnvironment environment)
    {
        this.environment = environment;
    }

    [HttpGet("[action]")]
    public IActionResult DownloadFile(string FileName)
    {
        string path = Path.Combine(
                            environment.WebRootPath,
                            "files",
                            FileName);

        var stream = new FileStream(path, FileMode.Open);

        var result = new FileStreamResult(stream, "text/plain");
        result.FileDownloadName = FileName;
        return result;
    }
}

And this in your .razor page:

@inject NavigationManager NavigationManager

<button @onclick="DownloadFile">Download</button>

@code {
     public void DownloadFile()
    {
        NavigationManager.NavigateTo($"/api/Download/DownloadFile?FileName=BlazorHelpWebsite.zip", true);
    }
}

See: https://github.com/ADefWebserver/Blazor-Blogs/tree/master/BlazorBlogs

like image 77
Michael Washington Avatar answered Sep 20 '22 23:09

Michael Washington