目录
介绍
在此提示中,您将看到一个简短的示例,用于创建具有分层结构的ASP.NET Web清单(清单 -> 有标题 -> 有条目)。
背景
基于最近的一个项目,我想为那些需要类似任务灵感的人发布一个例子。PJ使用的是EF Core,ASP.NET Core .NET 6。
模型
public class Checklist
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Notes { get; set; }
public virtual ChecklistType ChecklistType { get; set; }
public virtual List<ChecklistCaption> ChecklistCaptions { get; set; }
}
public class ChecklistCaption
{
[Key]
public int CaptionId { get; set; }
public string CaptionName { get; set; }
public string HtmlId { get; set; }
public int SortOrder { get; set; }
public List<ChecklistEntry> Entries { get; set; }
}
public class ChecklistEntry
{
[Key]
public int EntryId { get; set; }
public string Name { get; set; }
public int SortOrder { get; set; }
public string HtmlId { get; set; }
public int ResponsibleUserId { get; set; }
public string TaskName { get; set; }
public int HideField { get; set; }
public string Description { get; set; }
public string HelpLink { get; set; }
public int Radio { get; set; }
public string RadioValue1Name { get; set; }
public string RadioValue2Name { get; set; }
public string RadioValue3Name { get; set; }
public int RadioValue1 { get; set; }
public int RadioValue2 { get; set; }
public int RadioValue3 { get; set; }
public string InputText { get; set; }
}
稍后您将看到负值Radio将把控件切换到InputText为Text-Field-Container的输入字段。
我在EF中使用代码优先和依赖项注入。数据库是本地SQLEXpress。
使实体框架在控制器中可用所需的步骤
Startup.cs(添加服务):
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// this is the DbContext registration code
services.AddDbContextFactory<ChecklistContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("WebApiDatabase")));
}
DBContext(定DBSet):
public class ChecklistContext : DbContext
{
protected readonly DbContextOptions<ChecklistContext> _dbContextOptions;
public ChecklistContext(DbContextOptions<ChecklistContext> dbContextOptions)
: base(dbContextOptions)
{
_dbContextOptions = dbContextOptions;
}
public DbSet<Checklist> Checklists { get; set; }
}
带注入的控制器:
public class ChecklistController : Controller
{
private readonly IDbContextFactory<ChecklistContext> _contextFactory;
private readonly IConfiguration _configuration;
public ChecklistController(IDbContextFactory<ChecklistContext> contextFactory,
IConfiguration configuration)
{
_contextFactory = contextFactory;
_configuration = configuration;
}
public ActionResult Index()
{
return View("Index");
}
public ActionResult Edit(int? Id)
{
using (var context = _contextFactory.CreateDbContext())
{
var checklist = context.Checklists
.Where(x => x.Id == Id)
.Include(x => x.ChecklistCaptions).ThenInclude
(x => x.Entries) //Include fields
.FirstOrDefault();
if (checklist == null)
{
return NotFound();
}
return View(checklist);
}
}
视图:
@model ChecklistCore3.Models.Checklist
<script type="text/javascript">
$(document).ready(function () {
});
</script>
<h2>@Model.Title (Id: @Model.Id)</h2>
@using (Html.BeginForm("UpdateChecklist", "Checklist",
FormMethod.Post, new { @id = "myform" }))
{
@Html.AntiForgeryToken()
<fieldset>
<table class="table checklist-table">
@Html.HiddenFor(model => model.Id)
<tr>
<td>
<h3>
@Html.LabelFor(model => Model.Title)
</h3>
</td>
<td colspan="4">
<h3>
@Html.TextBoxFor(model => Model.Title, new { @class = "w800p" })
</h3>
</td>
</tr>
@{
for (int i = 0; i < Model.ChecklistCaptions.Count(); i++)
{
<tr id="caption-@Model.ChecklistCaptions[i].HtmlId">
<td class="checklist-caption" colspan="6">
<span>@Model.ChecklistCaptions[i].CaptionName</span>
@Html.HiddenFor(model =>
Model.ChecklistCaptions[i].CaptionId)
</td>
</tr>
for (int j = 0; j < Model.ChecklistCaptions[i].Entries.Count(); j++)
{
<tr class="checklist-row responsible-
@((Model.ChecklistCaptions[i].Entries[j].
ResponsibleUserId > 0 && ViewBag.CurrUserId==
Model.ChecklistCaptions[i].Entries[j].
ResponsibleUserId).ToString())"
id="@Model.ChecklistCaptions[i].Entries[j].HtmlId">
<td class="checklist-sortorder">
@Html.DisplayTextFor(model =>
Model.ChecklistCaptions[i].Entries[j].SortOrder)
</td>
<td class="checklist-taskname">
@Html.HiddenFor(model =>
Model.ChecklistCaptions[i].Entries[j].TaskName)
@Html.HiddenFor(model =>
Model.ChecklistCaptions[i].Entries[j].EntryId)
@Html.HiddenFor(model =>
Model.ChecklistCaptions[i].Entries[j].HideField,
new { @class = "HideField" })
@Html.DisplayTextFor(model =>
Model.ChecklistCaptions[i].Entries[j].TaskName)
</td>
<td class="checklist-description">
@Html.HiddenFor(model =>
Model.ChecklistCaptions[i].Entries[j].Description)
@Html.DisplayTextFor(model =>
Model.ChecklistCaptions[i].Entries[j].Description)
@if (!string.IsNullOrEmpty
(Model.ChecklistCaptions[i].Entries[j].HelpLink))
{
<a href="@Model.ChecklistCaptions[i].
Entries[j].HelpLink" target="_blank">->
Link<span class="glyphicon
glyphicon-question-sign"></span></a>
}
</td>
<td class="checklist-checkbox">
@if (Model.ChecklistCaptions[i].Entries[j].Radio >= 0)
{
<div class="editor-field-radio">
@if (!string.IsNullOrEmpty
(Model.ChecklistCaptions[i].Entries[j].
RadioValue1Name))
{
<label class="dp-check-block">
@Html.RadioButtonFor(model =>
Model.ChecklistCaptions[i].Entries[j].
Radio, Model.ChecklistCaptions[i].
Entries[j].RadioValue1)
<span class="big">
@Model.ChecklistCaptions[i].Entries[j].
RadioValue1Name</span></label>
}
@if (!string.IsNullOrEmpty
(Model.ChecklistCaptions[i].Entries[j].
RadioValue2Name))
{
<label class="dp-check-block">
@Html.RadioButtonFor(model =>
Model.ChecklistCaptions[i].Entries[j].
Radio, Model.ChecklistCaptions[i].
Entries[j].RadioValue2)
<span class="big">
@Model.ChecklistCaptions[i].
Entries[j].RadioValue2Name</span></label>
}
@if (!string.IsNullOrEmpty
(Model.ChecklistCaptions[i].Entries[j].
RadioValue3Name))
{
<label class="dp-check-block">
@Html.RadioButtonFor(model =>
Model.ChecklistCaptions[i].Entries[j].
Radio, Model.ChecklistCaptions[i].
Entries[j].RadioValue3)
<span class="big">
@Model.ChecklistCaptions[i].
Entries[j].RadioValue3Name</span>
</label>
}
</div>
}
else
{
<div class="editor-field-radio">
@Html.HiddenFor(model =>
Model.ChecklistCaptions[i].Entries[j].Radio)
@Html.EditorFor(model =>
Model.ChecklistCaptions[i].Entries[j].
InputText)
</div>
}
</td>
</tr>
}
}
}
<tr>
<td>
@Html.LabelFor(model => Model.Notes)
</td>
<td colspan="5">
@Html.TextAreaFor(model => Model.Notes,
new { rows = "5", @class = "checklist-notes-textarea" })
@Html.ValidationMessageFor(model => Model.Notes)
</td>
</tr>
<tr>
<td colspan="5">
<div class="submit-div-checklist" title="Save checklist">
<p>
<input id="submit-btn" type="submit" value="Save"
class="btn btn-success fright">
</p>
</div>
</td>
</tr>
</table>
</fieldset>
}
View循环访问标题和条目以创建清单。
Model.ChecklistCaptions[i].Entries[j].TaskName
模型绑定能够在提交表单时基于该结构重新创建类。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UpdateChecklist(Checklist checklist)
{
//ToDo...
return View("Edit",checklist);
}
https://www.codeproject.com/Tips/5338618/ASP-NET-MVC-Checklist-Based-on-Templates-with-EF-A