Asp.Net Core Blazor 开发体验

Blazorhttps://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-5.0Blazor是一个使用.NET开发交互式Web UI客户端的框架( Blazor is a framework for building interactive client-side web UI with .NET.)

优势是:使用C#替代Javascript开发富交互式UI界面, 浏览器的广泛支持,可充分利用.NET库及生态。直接开发体验完成一个增、删、改、查的功能。

1:创建Blazor 项目:

这里选择Blazor Server 应用,如图所示:还有一个Blazor WebAssembly项目。

区别可以参考“Blazor宿主模型”。 大白话解释:Blazor Server是客户端、服务器模式,使用SingleR通讯交换客户端数据。WebAssembly是把精简的.net运行时及Blazor项目编译后的文件发给浏览器端,App运行在浏览器端。

2: 项目模板的改造:

对步骤1利用模板创建的项目 稍微改造一下:使界面布局变成如下所示:

 这里利用了BootStrap 5.0的样式:头部导航菜单,和底部的Footer,中间为页面内容部分。

3:增删改查操作:

 Blazor 的开发类似Vue.js前端框架的组件开发,可充分利用组件复用的便捷。

这里模拟产品的CURD操作:

1:创建产品列表组件:

添加Razor组件,命名规则为组件名+Component.razor。

填入如下Razor语法代码:

@page指示页面路由,

@inject 指令代表Asp.net core Blazor 的依赖注入功能,由Blazor自动实例化此对象实例。

@page "/productlist";
@inject IProductRepository product;

<div>
    <h4 class="top-row-title">产品列表</h4>
    <div class="top-row-right">
        <button type="button" class="btn btn-primary"><i class="bi bi-plus-square-fill"></i> 新增</button>
    </div>
</div>
@if (productCollection != null && productCollection.Count() > 0)
{
    <table class="table table-hover">
        <thead>
            <tr>
                <td>编号</td>
                <td>产品名称</td>
                <td>单位</td>
                <td>价格</td>
                <td>描述</td>
            </tr>
        </thead>
        <tbody>
            @foreach (var p in productCollection)
            {
                <tr>
                    <td>@p.Id</td>
                    <td>@p.ProductName</td>
                    <td>@p.PackageUnit</td>
                    <td>@(Math.Round(p.Price,2))</td>
                    <td>@p.Description</td>
                </tr>
            }
        </tbody>
    </table>
}
else
{
    <p>未检索到任何数据</p>
}

@code {
    private IEnumerable<Product> productCollection;
    protected override void OnInitialized()
    {
        base.OnInitialized();
        productCollection = product.GetAll();
    }
}

在产品列表Razor组件页面中使用了 Blazor的CSS隔离特性:

  

IProductRepository的依赖注册为:

在项目的Startup.cs文件下:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<WeatherForecastService>();
            services.AddSingleton<IProductRepository, LocalProductRepository>();
        }
  public class LocalProductRepository : IProductRepository
    {
        List<Product> _products = new List<Product>();
        public LocalProductRepository()
        {

            _products.AddRange(new[] {
                new Product(){ Id=1, ProductName="产品1", PackageUnit="只", Description="产品1描述" },
                new Product(){ Id=2, ProductName="产品2", PackageUnit="个", Description="产品2描述" },
                new Product(){ Id=3, ProductName="产品3", PackageUnit="包", Description="产品3描述" },
            });
        }
        public void Add(Product t)
        {
            if (_products.Any(x => x.ProductName.Equals(t.ProductName, StringComparison.OrdinalIgnoreCase))) return;
            if (_products.Count == 0)
                t.Id = 1;
            else
            {
                var maxId = _products.Max(x => x.Id);
                t.Id = maxId + 1;
            }
            _products.Add(t);
        }

        public void Delete(Product t)
        {
            var targetProduct = _products.FirstOrDefault(x => x.Id == t.Id);
            if (targetProduct != null)
            {
                _products.Remove(targetProduct);
            }
        }

        public IEnumerable<Product> GetAll()
        {
            return _products;
        }

        public Product GetProductById(int id)
        {
            return _products.FirstOrDefault(x => x.Id == id);
        }

        public void Insert(Product t)
        {
            _products.Add(t);
        }

        public void Update(Product t)
        {
            var p = GetProductById(t.Id);
            if (p != null)
            {
                p.Description = t.Description;
                p.PackageUnit = t.PackageUnit;
                p.Price = t.Price;
                p.ProductName = t.ProductName;
            }
        }
    }

 添加导航链接:

  <NavLink class="nav-link  px-2 link-dark" href="productlist"> 产品列表</NavLink>

预览:

 2:新增产品:

参考MSDN链接:ASP.NET Core Blazor 窗体和验证

 AddProductComponent.razor

@page "/addproduct";
@inject IProductRepository productRepo;
@inject NavigationManager navigator;

<h3>新增产品</h3>

<EditForm Model="productModel" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div class="mb-3 row">
        <label for="product-name" class="col-sm-2 col-form-label">产品名称</label>
        <div class="col-sm-10">
            <InputText id="product-name" class="form-control" @bind-Value="productModel.ProductName" />
        </div>
    </div>
    <div class="mb-3 row">
        <label for="product-price" class="col-sm-2 col-form-label">价格</label>
        <div class="col-sm-10">
            <InputNumber id="product-price" class="form-control" @bind-Value="productModel.Price" @bind-Value:format="f2" />
        </div>
    </div>
    <div class="mb-3 row">
        <label for="product-price" class="col-sm-2 col-form-label">包装单位</label>
        <div class="col-sm-10">
            <InputSelect id="productUnit" class="form-select" @bind-Value="productModel.PackageUnit">
                <option value="">请选择</option>
                @foreach (var item in packageUnits)
                {
                    <option value="@item">@item</option>
                }
            </InputSelect>
        </div>
    </div>
    <div class="mb-3 row">
        <label for="product-desc" class="col-sm-2 col-form-label">描述</label>
        <div class="col-sm-10">
            <InputText id="product-desc" class="form-control" @bind-Value="productModel.Description"  />
        </div>
    </div>
    <button type="submit" class="btn btn-primary">保存</button>
</EditForm>
@code {

    private Product productModel;
    private IList<string> packageUnits;
    protected override void OnInitialized()
    {
        base.OnInitialized();
        productModel = new Product();
        packageUnits = EumeHelper<PackageUnit>.GetKeys();
    }

    private void HandleValidSubmit()
    {
        productRepo.Add(productModel);
        navigator.NavigateTo("/productlist");
    }
}

 Product添加验证特性:来自命名空间:System.ComponentModel.DataAnnotations

  public class Product
    {
        public int Id { get; set; }

        [Required(ErrorMessage = "产品名称不可为空")]
        [MaxLength(20,ErrorMessage = "产品名称超出许可长度")]
        public string ProductName { get; set; }

        [Required(ErrorMessage = "产品单位不可为空")]
        public string  PackageUnit { get; set; }

        [Required(ErrorMessage ="价格不可为空")]
        [Range(0,1000,ErrorMessage ="价格范围输入错误")]
        public decimal? Price { get; set; }

        public string Description { get; set; }
    }

 效果预览:

3:编辑、删除产品

在产品列表组件中添加一个操作列:

  <td width="140px">
     <button type="button" class="btn btn-link" @onclick="@(()=> { EditProduct(p.Id); })"><i class="bi bi-pencil-fill"></i></button>
     <button type="button" class="btn btn-link" style="color:red;" @onclick="@(()=> { Delete(p); })"><i class="bi bi-trash3-fill"></i></button>
  </td>

对应的code方法为:

  void EditProduct(int pid)
    {
        navigator.NavigateTo($"/editproduct/{pid}");
    }

    void Delete(Product p)
    {
        product.Delete(p);
    }

把新增组件复制修改为EditProductComponent.razor

@page "/editproduct/{productid:int?}";
@inject IProductRepository productRepo;
@inject NavigationManager navigator;

<h3>编辑产品</h3>

<EditForm Model="productModel" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div class="mb-3 row">
        <label for="product-name" class="col-sm-2 col-form-label">产品名称</label>
        <div class="col-sm-10">
            <InputText id="product-name" class="form-control" @bind-Value="productModel.ProductName" />
        </div>
    </div>
    <div class="mb-3 row">
        <label for="product-price" class="col-sm-2 col-form-label">价格</label>
        <div class="col-sm-10">
            <InputNumber id="product-price" class="form-control" @bind-Value="productModel.Price" @bind-Value:format="f2" />
        </div>
    </div>
    <div class="mb-3 row">
        <label for="product-price" class="col-sm-2 col-form-label">包装单位</label>
        <div class="col-sm-10">
            <InputSelect id="productUnit" class="form-select" @bind-Value="productModel.PackageUnit">
                <option value="">请选择</option>
                @foreach (var item in packageUnits)
                {
                    <option value="@item">@item</option>
                }
            </InputSelect>
        </div>
    </div>
    <div class="mb-3 row">
        <label for="product-desc" class="col-sm-2 col-form-label">描述</label>
        <div class="col-sm-10">
            <InputText id="product-desc" class="form-control" @bind-Value="productModel.Description" />
        </div>
    </div>
    <button type="submit" class="btn btn-primary">更新</button>
</EditForm>
@code {

    [Parameter]
    public int ProductId { get; set; }
    private Product productModel;
    private IList<string> packageUnits;
    protected override void OnInitialized()
    {
        base.OnInitialized();

        packageUnits = EumeHelper<PackageUnit>.GetKeys();
    }

    private void HandleValidSubmit()
    {
        productRepo.Update(productModel);
        navigator.NavigateTo("/productlist");
    }

    protected override void OnParametersSet()
    {
        productModel = productRepo.GetProductById(ProductId);
        base.OnParametersSet();
    }
}

其中传递参数的部分,参考ASP.NET Core Blazor 路由和导航

至此一个简单的功能就完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值