1 回答

TA贡献1825条经验 获得超6个赞
我还没有运行它,但我很有信心,这应该做的伎俩!实际上,唯一真正通用的部分是控制器。另一个就是常见的多态性。谢谢你的启发。想到这样的解决办法,真是有趣。也许将来我也会造类似的东西。
提醒一句:您将把控制器的名称绑定到每个Model的名称。只是要注意这一点!必须保留一个命名架构,否则会破坏它。
公共类[模型名称]控制器:主控制器<型号Name>
{
}
阿贾克斯端点将以[PluralName]的值结束
(请继续阅读《观点》,了解我的意思。)
您将需要在MasterTemplate中添加一个属性。理想情况下使其抽象,这样您就不会忘记在派生类中实现它。这适用于视图头中的复数名称和视图中的阿贾克斯调用。
public abstract class MasterTemplate
{
[Key]
public int Id { get; set; }
public abstract string PluralName {get;}
[Required]
[StringLength(255)]
public string Description { get; set; }
public DateTime? UpdatedOn { get; set; }
public string UpdatedBy { get; set; }
}
工业就会像这样
public class Industry: MasterTemplate
{
public override string PluralName => "Industries"
}
创建一个真正通用的Controller,并从它派生所有其他Controller,如
public class IndustryController : MasterController<Industry>
{
//done everthing else is in the master :)
}
这里是通用的MasterController< T>。
public class MasterController<T> : Controller where T : MasterTemplate, new()
{
private ApplicationDbContext _context { get; set; }
private string UserId { get; set; }
public MasterController()
{
_context = new ApplicationDbContext();
UserId = System.Web.HttpContext.Current.User.Identity.GetUserId();
}
public ActionResult Index(int id = 0)
{
T data = (id > 0)
? data = _context.Set<T>().SingleOrDefault(c => c.Id == id) ?? new T()
: new T();
return View("View", data);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(T data)
{
if (!ModelState.IsValid)
return View("View", data);
var record = _context.Set<T>().Where(c => c.Description.Trim().ToLowerInvariant() == data.Description.Trim().ToLowerInvariant() && c.Id != data.Id);
if (record.Count() > 0)
{
ModelState.AddModelError($"Duplicate {typeof(T).Name}", $"{typeof(T).Name} already exist");
return View("View", data);
}
if (data.Id >= 1)
{
T cm = _context.Set<T>().SingleOrDefault(c => c.Id == data.Id);
cm.Description = data.Description;
cm.UpdatedOn = DateTime.Now;
cm.UpdatedBy = UserId;
}
else
{
_context.Set<T>().Add(data);
}
_context.SaveChanges();
return RedirectToAction("Index", new { id = 0 });
}
将视图命名为“View”(或与您在MasterController中的称呼相同),并将其放置在共享文件夹中,以便每个控制器都能在那里找到它。
@model MasterTemplate
@{
string name = Model.GetType().Name;
ViewBag.Title = name;
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>@Model.PluralName Management</h3>
<div class="row">
<div class="col-md-4">
@using (@Html.BeginForm("Save", name))
{
@Html.ValidationSummary("Please correct the following")
@Html.HiddenFor(m => m.Id)
<div class="form-group">
<div>
@Html.LabelFor(m => m.Description)
@Html.TextBoxFor(m => m.Description, new { @class = "form-control", autocomplete = "off" })
@Html.ValidationMessageFor(m => m.Description, $"{name} is required.", new { @class = "text-danger" })
</div>
</div>
@Html.AntiForgeryToken()
<button type="submit" class="btn btn-primary btn-sm">Save</button>
}
</div>
<div class="col-md-8">
<table class="table table-sm" id="mydata">
<thead>
<tr>
<th>
@(name)
</th>
<th>
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
@section scripts
{
@Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function () {
$("#mydata").DataTable({
ajax: {
url: "/api/get/@(Model.PluralName)",
dataSrc: ""
},
columns: [
{
data: "description"
},
{
data: "id",
render: function (data) {
var url = '@Url.Action("Index", "@(name)", new { id = "__data__" })';
return '<a href="' + url.replace('__data__', data) + '">Edit</a>';
}
}
]
});
});
</script>
}
- 1 回答
- 0 关注
- 104 浏览
添加回答
举报