前端小白学习asp.net的一些碎碎念和记录,使用的开发软件是vs2022,框架:asp.net core mvc 6.0,前端控件:DevExpress,数据库:sqlserver 2008 R2。
1.在appsettings.json中 添加连接数据库地址。在数据库中用sql建表并添加一些数据。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MVCSqlContext": "Server=localhost;Database=testDevDemoSql;User ID=sa;Password=sa;TrustServerCertificate=true"
}
}
2.安装所需的包,因为很小白所以能用的包都安装上了,在未启动项目时右键依赖项,点击管理NuGet程序包进行安装,图片中的包可以按需添加,红色箭头指向的几个是必须添加。由于这里使用的是asp.net 6.0的所以安装微软的包也是安装最高为6.0中的最高版本,例如截至目前为止版本为(6.0.29)。
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Microsoft.VisualStudio.Web.CodeGeneration.Design
DevExtreme.AspNet.Core
DevExtreme.AspNet.Data
3.在Program.cs中添加这几行代码
builder.Services.AddDbContext<MVCSqlContext>(
options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("MVCSqlContext"));
});
builder.Services.AddControllersWithViews();
4.在Models文件夹中添加一个模型类,里面存放跟数据库的MenuListTable表一样的参数,且数据类型也必须和数据库表中的一致。
using System.ComponentModel.DataAnnotations;
using static DevExtremeAspNetCoreApp1.Models.MyComponentViewOrder;
namespace DevExtremeAspNetCoreApp1.Models
{
public class MyComponentViewModel
{
public class MenuListTable
{
[Key]
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string Icon { get; set; }
public string PathAddress { get; set; }
}
}
}
5.在Models文件夹中添加一个名为MVCSqlContext.cs的类。
using Microsoft.EntityFrameworkCore;
namespace DevExtremeAspNetCoreApp1.Models
{
public class MVCSqlContext : DbContext
{
public MVCSqlContext(DbContextOptions<MVCSqlContext> options) : base(options) { }
// 这里获取数据库的表数据,定义的获取数据名称必须与数据库表名一致
public DbSet<MyComponentViewModel.MenuListTable> MenuListTable { get; set; }
}
}
6.在Views/Home中添加一个测试用的视图。
7.在HomeController中添加这些代码。
using DevExtremeAspNetCoreApp1.Models;
using Microsoft.AspNetCore.Mvc;
namespace DevExtremeAspNetCoreApp1.Controllers
{
public class HomeController : Controller
{
private readonly MVCSqlContext _context;
public HomeController(MVCSqlContext context)
{
_context = context;
}
public IActionResult Index1()
{
// 使用_context.MenuListTable.ToList()获取数据库该表的数据
// 通过ViewData传递参数给Views/Home/Index1.cshtml
ViewData["MenuListTable"] = _context.MenuListTable.ToList();
return View();
}
}
}
8.在Views/Home/Index1.cshtml中接收HomeController的数据并循环渲染使用DevExpress的TreeView生成菜单栏。
@if (ViewData["MenuListTable"] != null)
{
var menuList = ViewData["MenuListTable"] as List<DevExtremeAspNetCoreApp1.Models.MyComponentViewModel.MenuListTable>;
@(Html.DevExtreme().TreeView()
.Items(items =>
{
foreach (var item in menuList)
{
if (item.PathAddress.Contains("/") && item.ParentId == 0)
{
items.Add()
.Text(item.Title)
.Icon(item.Icon)
.Option("path", GetUrl(item.PathAddress))
.Selected(IsCurrentUrl(item.PathAddress));
}
else if (item.ParentId == 0)
{
items.Add()
.Text(item.Title)
.Icon(item.Icon)
.HasItems(true).Items(citems =>
{
var childMenu = menuList.Where<MyComponentViewModel.MenuListTable>(m => m.ParentId == item.Id);
foreach (var item2 in childMenu)
{
citems.Add()
.Text(item2.Title)
.Icon(item2.Icon)
.Option("path", GetUrl(item2.PathAddress))
.Selected(IsCurrentUrl(item2.PathAddress));
}
});
}
}
items.Add()
.Text("About")
.Icon("info")
.Option("path", Url.Content("~/About/Index"))
.Selected(IsCurrentUrl("/About/Index"));
})
.ExpandEvent(TreeViewExpandEvent.Click)
.SelectionMode(NavSelectionMode.Single)
.ExpandedExpr("Expanded")
.SelectedExpr("selected")
.FocusStateEnabled(true)
.Width(250)
)
}
写在最后可能会出现的一些报错:
可能会出现的报错1:如果数据库表中有某个字段是可以为null的话,而模型类中没有注明可为null则会报错:System.Data.SqlTypes.SqlNullValueException:“Data is Null. This method or property cannot be called on Null values.”。解决该报错则需要在模型类中把该字段的数据类型后增加一个问号用来标识此字段可为null。
可能会可能出现的报错2:如果数据库表的字段的数据类型跟模型类中的字段数据类型不一致的话会报这个错误:System.InvalidCastException:“Unable to cast object of type 'System.Decimal' to type 'System.Int32'.”。比如数据库中这个表的result字段的数据类型为:numeric(4, 1),而模型类中该字段的数据类型要为:decimal
可能出现的报错3: 如果数据库表没有设置主键或者表中有主键但是模型类中没有为有主键的字段添加标识,都有可能会报这个错:System.InvalidOperationException:“The entity type 'sd_tMenus' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'. For more information on keyless entity types, see https://go.microsoft.com/fwlink/?linkid=2141943.”。
解决方案有两个:1. 是数据表中有设置主键,模型类中没有设置,则在模型类中为该字段增加[Key]作为标识主键。
2.如果数据表中不想设置主键,可以在这个MVCSqlContext.cs类中添加以下代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 为此表添加无需主键标识
modelBuilder.Entity<MyComponentViewModel.MenuListTable>(entity =>
{
entity.HasNoKey();
});
}