Blazor一個簡單的示例讓我們來起飛

Blazor

Blazor他是一個開源的Web框架,不,這不是重點,重點是它可以使c#開發在瀏覽器上運行Web應用程序.它其實也簡化了SPA的開發過程.

Blazor = Browser + Razor

為什么選擇Blazor?

Blazor可以讓.NET附有全棧開發功能,它可以使Web開發變得輕松而高效.而且Blazor是開源的,它得到了社區的大力支持,而且發展速度會很快.

它還擁有SPA的一些功能比如:

  • 路由
  • 依賴注入
  • 服務端渲染
  • Layout
    等等

創建應用

如果說無法在看到Blazor WebAssembly App那么執行如下命令即可.

dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview5.20216.8

項目結構如下所示

我們可以看到上圖中的項目結構

  • BlazorServerCRUDSample.Client:該項目工程中包含了客戶端的相關代碼頁面等文件
  • BlazorServerCRUDSample.Server:該項目工程中包含了webapi.
  • BlazorServerCRUDSample.Shared:該類庫中用于存放客戶端和服務端之間的共享代碼.

BlazorServerCRUDSample.Server

控制器代碼如下所示

    [Route("api/[controller]")]
    public class StudentController : Controller
    {
        private readonly Shared.Data.AppContext _dbcontext;

        public StudentController(Shared.Data.AppContext dbcontext)
        {
            this._dbcontext = dbcontext;
        }
        [HttpGet]
        public async Task<List<Student>> Get()
        {
            return await _dbcontext.Students.AsQueryable().ToListAsync();
        }
        [HttpGet("{id}")]
        public async Task<Student> Get(int id)
        {
            return await _dbcontext.Students.FindAsync(id);
        }
        [HttpPost]
        public async Task Post([FromBody] Student student)
        {
            student.CreateTime = DateTime.Now;
            if (ModelState.IsValid)
                await _dbcontext.AddAsync(student);
           await _dbcontext.SaveChangesAsync();
        }
        [HttpPut]
        public void Put([FromBody] Student student)
        {
            if (ModelState.IsValid)
                _dbcontext.Update(student);
            _dbcontext.SaveChanges();
        }
        [HttpDelete("delete/{id}")]
        public void Delete(int id)
        {
            var entity = _dbcontext.Students.Find(id);
            _dbcontext.Students.Remove(entity);
            _dbcontext.SaveChanges();
        }



    }
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseConfiguration(new ConfigurationBuilder()
                    .AddCommandLine(args)
                    .Build())
                .UseStartup<Startup>()
                .Build();
    }

對于Startup類,我們可以看到在開發模式下,啟動Blazor調試,并且我們可以看到我們通過UseClientSideBlazorFiles來啟動我們的客戶端Startup


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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddResponseCompression();
            services.AddDbContext<AppContext>(options =>
            {
                options.UseSqlServer("Data Source=.;Initial Catalog=BlazorServerCRUDSample;User ID=sa;Password=sa;MultipleActiveResultSets=true;");
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseResponseCompression();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBlazorDebugging();
            }

            app.UseStaticFiles();
            app.UseClientSideBlazorFiles<Client.Startup>();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
            });
        }
    }

BlazorServerCRUDSample.Client

如下所示我創建了一個列表頁面,在代碼中我們可以看到@page他定義了該頁面的url,當然在razor中也是這樣的,而且下最下面我通過HttpClient進行我們的api調用,在這 System.Net.Http.Json這篇文章中我們也可以看到他簡直就是為了我們blazor而生的大大減少了我們的代碼量.

而且在我的代碼中最后一部分有一個@functions片段,它包含了頁面所有的業務邏輯,在我們頁面初始化時我們通過OnInitializedAsync方法進行調用我們的api然后將其進行填充賦值并填充到我們的html中.

@page "/fetchstudent"
@inject HttpClient Http
@using BlazorServerCRUDSample.Shared.Models

    <h1>Students</h1>
<p>
    <a href="/addstudent">Create New</a>
</p>
@if (students == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class='table'>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Description</th>
                <th>CreateTime</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var student in students)
            {
                <tr>
                    <td>@student.Id</td>
                    <td>@student.Name</td>
                    <td>@student.Description</td>
                    <td>@student.CreateTime</td>
                        <td>
                            <a href='/editstudent/@student.Id'>Edit</a>  |
                            <a href='/delete/@student.Id'>Delete</a>
                        </td>
                </tr>

            }
        </tbody>
    </table>
}

@functions {
    Student[] students;
    protected override async Task OnInitializedAsync()
    {
        students = await Http.GetJsonAsync<Student[]>("api/student");
    }
}  

如下代碼中我們還是對我們的頁面提供了url,其中Id是將從url中的參數傳遞到我們的@functions代碼中,在Id上面指定 [Parameter] 屬性,該屬性指定的就是url中的參數值.在這我們通過使用 @bind 來將我們的html組件和類對象進行雙向綁定.

@page "/editstudent/{Id}"
@inject HttpClient Http
@using BlazorServerCRUDSample.Shared.Models
@inject Microsoft.AspNetCore.Components.NavigationManager Navigation

    <h2>Edit Student</h2>
<hr />
<div class="row">
    <div class="col-md-4">
        <form @onsubmit="@(async () => await UpdateStudent())">
            <div class="form-group">
                <label for="Name" class="control-label">Name</label>
                <input for="Name" class="form-control" @bind="@student.Name" />
            </div>
            <div class="form-group">
                <label asp-for="Description" class="control-label">Description</label>
                <textarea asp-for="Description" class="form-control" @bind="@student.Description"> </textarea>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
                <input type="submit" value="Cancel" @onclick="@cancel" class="btn btn-warning" />
            </div>
        </form>
    </div>
</div>

@functions {
    [Parameter]
    public string id { get; set; }
    public Student student = new Student();
    protected override async Task OnInitializedAsync()
    {
        student = await Http.GetJsonAsync<Student>("/api/Student/" + Convert.ToInt32(id));
    }
    protected async Task UpdateStudent()
    {
        await Http.SendJsonAsync(HttpMethod.Put, "api/Student", student);
        Navigation.NavigateTo("/fetchstudent");
    }
    void cancel()
    {
         Navigation.NavigateTo("/fetchstudent");
    }
}  

在ConfigureServices方法中,可以在依賴項注入容器中注冊本地服務。

   public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }

        public void Configure(IComponentsApplicationBuilder app)
        {
            app.AddComponent<App>("app");
        }
    }

BlazorWebAssemblyHost可以用于在DI容器中定義接口和實現。

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
            BlazorWebAssemblyHost.CreateDefaultBuilder()
                .UseBlazorStartup<Startup>();
    }

Blazor可以基于服務端運行但是需要注意服務端的話需要為每一個客戶端打開連接,并且我們必須一直與服務端保持連接才行.如果說切換到WebAssembly客戶端版本,限制是完全不同的,但是目前來說的話他首次需要下載一些運行時文件到瀏覽器中.

通過如上代碼我們可以看到一個簡單的blazor應用程序的建立,詳細代碼的話大家可以看一下github倉庫中的內容.通過源碼的話直接啟動BlazorServerCRUDSample.Server即可,希望可以通過本示例幫助到你~共同學習共同進步.

Reference

https://github.com/hueifeng/BlazorCRUDSample

http://www.afvbyw.live/shanyou/p/12825845.html

posted @ 2020-05-05 22:48  HueiFeng  閱讀(...)  評論(...編輯  收藏
ag二分彩