- IDE为VS 2019,dotnetcore版本为3.1
创建项目
- 打开VS,依次点击工具栏文件按钮->新建->项目,搜索框输入`ASP.Net Core`,语言选择`C#`,在筛选结果中选择`ASP.Net Core Web 应用程序`,点击下一步。
- 填写项目名称,再下一步,选择`3.1`版本,模板选择`Web 应用程序`,最后点击创建。
- 创建完之后,项目结构如下。
安装并应用NewLife.Cube.Core
- 右键点击项目中依赖项->点击管理NuGet程序包->搜索框输入`NewLife.Cube.Core`,选中搜索结果,点击安装。
- Startup.cs文件修改如下。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NewLife.Cube;
namespace CubeDemo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(); // 2020-12-26添加
services.AddCube();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCube();
}
}
}
- 按F5运行项目,一切顺利的话,就能看到魔方的登录页面,默认账号密码都是`admin`,登录进去,可看到内置的控制器。注意:初始化运行需要下载静态资源和驱动,生成菜单,所以出现异常或者页面样式不对,都是正常现象,稍等或重新运行项目即可。
- 有时候文档来不及更新,可以参考代码中的例子Startup.cs
添加自己的页面
新建区域
- 首先新建区域,手动创建文件夹,在此文件夹创建区域类,填入以下内容。
using System;
using System.ComponentModel;
using NewLife.Cube;
namespace CubeDemo.Areas.School
{
[DisplayName("教务系统")]
public class SchoolArea : AreaBase
{
public SchoolArea() : base(nameof(SchoolArea).TrimEnd("Area")) { }
static SchoolArea() => RegisterArea<SchoolArea>();
}
}
新建实体
- 新建数据库实体类,参考数据中间件NewLife.XCode教程。新建文件夹,将实体类放在此文件夹,具体内容参考这里 。
新建控制器
- 新建文件夹,新建ClassController、StudentController两个控制器,分别填入以下内容。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using NewLife.Cube;
using NewLife.School.Entity;
using NewLife.Web;
using XCode.Membership;
namespace CubeDemo.Areas.School.Controllers
{
[SchoolArea]
[DisplayName("班级")]
public class ClassController : EntityController<Class>
{
protected override IDictionary<MethodInfo, Int32> ScanActionMenu(IMenu menu)
{
menu.Visible = true;
return base.ScanActionMenu(menu);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using NewLife.Cube;
using NewLife.School.Entity;
using NewLife.Web;
using XCode.Membership;
namespace CubeDemo.Areas.School.Controllers
{
[SchoolArea]
[DisplayName("学生")]
public class StudentController : EntityController<Student>
{
static StudentController()
{
ListFields.RemoveField("CreateUserID");
ListFields.RemoveField("UpdateUserID");
//FormFields
}
protected override IDictionary<MethodInfo, Int32> ScanActionMenu(IMenu menu)
{
menu.Visible = true;
return base.ScanActionMenu(menu);
}
}
}
页面修改
- 此时运行,一切正常,可看到如下页面。
- 如果要修改页面,那么直接在对应位置建立对应视图文件即可自动覆盖。详细可覆盖文件参考这里。
- 比如修改学生主页,则新建文件夹,新建文件。填入以下内容。
@using NewLife;
@using NewLife.Cube
@using NewLife.Web;
@using XCode;
@using XCode.Configuration;
@using XCode.Membership
@{
var fact = ViewBag.Factory as IEntityFactory;
var page = ViewBag.Page as Pager;
var fields = ViewBag.Fields as List<FieldItem>;
}
<table class="table table-bordered table-hover table-striped table-condensed">
<thead>
<tr>
<th class="text-center hidden-md hidden-sm hidden-xs"><a href="@Html.Raw(page.GetSortUrl("ID"))">编号</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("ClassID"))">班级2</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("Name"))">名称3</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("Sex"))">性别4</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("Age"))">年龄5</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("Mobile"))">手机</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("Address"))">地址</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("CreateTime"))">创建时间</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("CreateIP"))">创建地址</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("UpdateTime"))">更新时间</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("UpdateIP"))">更新地址</a></th>
<th class="text-center"><a href="@Html.Raw(page.GetSortUrl("Remark"))">备注</a></th>
@if (this.Has(PermissionFlags.Detail, PermissionFlags.Update, PermissionFlags.Delete))
{
<th class="text-center">操作</th>
}
</tr>
</thead>
<tbody>
@foreach (var entity in Model)
{
<tr>
<td class="text-center hidden-md hidden-sm hidden-xs">@entity.ID</td>
<td>@entity.ClassName</td>
<td>@entity.Name</td>
<td class="text-center">@entity.Sex</td>
<td class="text-right">@entity.Age.ToString("n0")</td>
<td>@entity.Mobile</td>
<td>@entity.Address</td>
<td>@Utility.ToFullString(entity.CreateTime, "")</td>
<td>@entity.CreateIP</td>
<td>@Utility.ToFullString(entity.UpdateTime, "")</td>
<td>@entity.UpdateIP</td>
<td>@entity.Remark</td>
@if (this.Has(PermissionFlags.Detail, PermissionFlags.Update, PermissionFlags.Delete))
{
<td class="text-center">
@await Html.PartialAsync("_List_Data_Action", (Object)entity)
</td>
}
</tr>
}
</tbody>
</table>
- 修改后页面如下。其他页面均可按照此方式进行覆盖。