简体   繁体   中英

how to display list page in blazor

I am working with codefirst approach in blazor and mydatabase created successfully using code first approach

fist I create a project and then select a visual studio 2019 -> blazor app -> blazor server app

why my employee list page not render in blazor

I want to display emp table record in blazor but issue is not render

Emp.cs

namespace BlazorServerApp.Pages
{
    public class Emp
    {
        public int empid { get; set; }
        public string empname { get; set; }
        public string empcountry { get; set; }
    }
}

EmployeAccessLayer.css

namespace BlazorServerApp.DataAccess
{
    public interface IEmployeAccessLayer
    {
        IEnumerable GetAllEmployees();
    }

    public class EmployeAccessLayer : IEmployeAccessLayer
    {
        private MyDbContext _context;
        public EmployeAccessLayer(MyDbContext context)
        {
            _context = context;
        }

        public IEnumerable GetAllEmployees()
        {
            try
            {
                return _context.emps.ToList();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}

EmployeeController.css

namespace BlazorServerApp.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        IEmployeAccessLayer _employeAccessLayer;

        public EmployeeController(IEmployeAccessLayer employeAccessLayer)
        {
            _employeAccessLayer = employeAccessLayer;
        }

        [HttpGet]
        [Route("api/Employee/Index")]
        public IEnumerable<Emp> Index()
        {
            return (IEnumerable<Emp>)_employeAccessLayer.GetAllEmployees();
        }
    }
}

GetEmployee.razor

@*@page "/employee/GetEmployee"*@
@*@page  "/employee"*@
@page  "/employee/"
@inject HttpClient Http

<h3>GetEmployee</h3>

@code {

}
@if (empList == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class='table'>
        <thead>
            <tr>
                <th>EmpID</th>
                <th>EmpName</th>
                <th>EmpCountry</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var emp in empList)
            {
                <tr>
                    <td>@emp.empid</td>
                    <td>@emp.empname</td>
                    <td>@emp.empcountry</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    Emp[] empList;
}

NavMenu.razor

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
    </ul>
</div>

see my database image I have 2 record in table I want to display them in blazor

在此处输入图片说明

see my blazor output

在此处输入图片说明

hierarchy of myproject

在此处输入图片说明

here give an message sorry at this nothing address

Edit: I add this line in GetEmployee.razor

@code {
    Emp[] empList;
    protected override async Task OnInitializedAsync() =>
        empList = await Http.GetJsonAsync<Emp[]>("api/Employee/Index");
}

but when I am run the project and write this line in address bar then give below error

在此处输入图片说明

Startup.cs

namespace BlazorServerApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("sqlserverconn")));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetRequiredService<MyDbContext>();
                context.Database.EnsureCreated();
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

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

you forget call to your API see the docs

  protected override async Task OnInitializedAsync() => 
        empList= await Http.GetFromJsonAsync<Emp[]>("api/Employee/Index");

Futhermore, remember the direction of your page must be localhost:44326/employee

HttpClient is not registered as service in the Startup.cs which is the cause i think of this issue https://i.stack.imgur.com/zSpC6.png .

public void ConfigureServices(IServiceCollection services)
{
  services.AddScoped<HttpClient>();
  .....
}

In your startup class in the configure service method you should have something along the lines of:

 services.AddHttpClient("httpClient",client => 
 {
    client.BaseAddress = new Uri("https://localhost:44326/");
 });

or if you follow the documentation :

services.AddScoped(sp => 
  new HttpClient
  {
   BaseAddress = new Uri("https://localhost:44326/")
  });

Your controller routing is not correct.

if you have [Route("api/[controller]")] on your controller you only need [Route("Index")] above your method.

the way you have it in your code the api route is looking for api/Employee/api/Employee/Index

change your api code to:

namespace BlazorServerApp.Controllers
{
  [Route("api/[controller]")]
  [ApiController]
  public class EmployeeController : ControllerBase
  {
   //.....your code here
   // .... your code here
    [HttpGet]
    [Route("Index")]
    public IEnumerable<Emp> Index()
    {
       return (IEnumerable<Emp>)_employeAccessLayer.GetAllEmployees();
    }
  }
}

I personally prefer using the GetAsync(...) like this:

protected override async Task OnInitializedAsync()
{    
    var response = await Http.GetAsync("api/employee/index", HttpCompletionOption.ResponseContentRead);
    if (response.IsSuccessStatusCode)
    {
      empList = await JsonSerializer.DeserializeAsync<Emp[]>(await response.Content.ReadAsStreamAsync(), new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });      
    }
    else                
      empList = new List<Emp>();
}

That way you get a bit more information about why the call to the api failed.

Why do you want to provide a rest-api with you blazor server app? You can directly query the database with the injected DbContext in you code section.

You add the dbcontext to the service collection (ConfigureServices). Now you can use these context in your code section:

@page  "/employee/"
@using Microsoft.EntityFrameworkCore;
@inject MyDbContext Context

<h3>GetEmployee</h3>

@if (empList == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class='table'>
        <thead>
            <tr>
                <th>EmpID</th>
                <th>EmpName</th>
                <th>EmpCountry</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var emp in empList)
            {
                <tr>
                    <td>@emp.empid</td>
                    <td>@emp.empname</td>
                    <td>@emp.empcountry</td>
                </tr>
            }
        </tbody>
    </table>
}


@code {

    private List<Emp> empList;

    protected override async Task OnInitializedAsync()
    {
        this.empList = await Context.emps.ToListAsync();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM