C# MVC中避免重复代码的通用视图和控制器
在我的MVC项目中,我有很多基本结构相同的模型。所以,我创建了一个主类,如下所示C# MVC中避免重复代码的通用视图和控制器,c#,asp.net-mvc,generics,interface,C#,Asp.net Mvc,Generics,Interface,在我的MVC项目中,我有很多基本结构相同的模型。所以,我创建了一个主类,如下所示 public class MasterTemplate { [Key] public int Id { get; set; } [Required] [StringLength(255)] public string Description { get; set; } public DateTime?
public class MasterTemplate
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Description { get; set; }
public DateTime? UpdatedOn { get; set; }
public string UpdatedBy { get; set; }
}
public class Industry : MasterTemplate
{
}
public class Caste : MasterTemplate
{
}
public class Gender : MasterTemplate
{
}
public class Qualification : MasterTemplate
{
}
public class BloodGroup: MasterTemplate
{
}
我创建了我所有的模型类,如下所示
public class MasterTemplate
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Description { get; set; }
public DateTime? UpdatedOn { get; set; }
public string UpdatedBy { get; set; }
}
public class Industry : MasterTemplate
{
}
public class Caste : MasterTemplate
{
}
public class Gender : MasterTemplate
{
}
public class Qualification : MasterTemplate
{
}
public class BloodGroup: MasterTemplate
{
}
像这样的还有很多。以下是我的IndustryController代码
public class IndustryController : Controller
{
private ApplicationDbContext _context { get; set; }
private string UserId { get; set; }
public IndustryController()
{
_context = new ApplicationDbContext();
UserId = System.Web.HttpContext.Current.User.Identity.GetUserId();
}
public ActionResult Index(int id = 0)
{
Industry data = new Industry();
if (id > 0)
data = _context.Industries.SingleOrDefault(c => c.Id == id);
if (data == null)
data = new Industry();
return View("Industry", data);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(Industry data)
{
if (!ModelState.IsValid)
return View("Industry", data);
var record = _context.Industries.Where(c => c.Description.Trim().ToLower() == data.Description.Trim().ToLower() && c.Id != data.Id);
if (record.Count() > 0)
{
ModelState.AddModelError("Duplicate Industry", "Industry already exist");
return View("Industry", data);
}
Industry cm = new Industry();
if (data.Id >= 1)
{
cm = _context.Industries.SingleOrDefault(c => c.Id == data.Id);
cm.Description = data.Description;
cm.UpdatedOn = DateTime.Now;
cm.UpdatedBy = UserId;
}
else
{
cm = data;
_context.Industries.Add(cm);
}
_context.SaveChanges();
return RedirectToAction("Index", new { id = 0 });
}
下面是我的工业视图代码
@model Industry
@{
ViewBag.Title = "Industries";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>Industries Management</h3>
<div class="row">
<div class="col-md-4">
@using (@Html.BeginForm("Save", "Industry"))
{
@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)
</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>
Industries
</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/industries",
dataSrc: ""
},
columns: [
{
data: "description"
},
{
data: "id",
render: function (data) {
var url = '@Url.Action("Index", "Industry", new { id = "__data__" })';
return '<a href="' + url.replace('__data__', data) + '">Edit</a>';
}
}
]
});
});
</script>
}
是否有人可以指导我正确的方向,需要为我的项目中的所有类似模型创建一个通用控制器和视图。我还没有运行它,但我很有信心,这应该可以做到!实际上,唯一真正通用的部分是控制器。其他的东西就是通常的多态性。谢谢你的灵感。想到这样的解决方案很有趣。也许我将来会建造类似的东西 注意:您将把控制器的名称绑定到每个模型的名称。请注意这一点!必须保留一个命名模式,否则您将破坏它。
public class[ModelName]Controller:MasterController
{
ajax端点将以[PluralName]
的值结束(请在视图中继续阅读,了解我的意思)。 在主模板中需要一个附加属性。理想情况下,将其抽象化,这样您就不会忘记在派生类中实现它。这用于视图标题中的复数名称和视图中的ajax调用
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"
}
制作一个真正的通用控制器,并从中派生所有其他控制器,如
public class IndustryController : MasterController<Industry>
{
//done everthing else is in the master :)
}
公共类工业控制器:主控制器
{
//完成所有其他的事情都在主目录中:)
}
这里是通用主控制器
public class IndustryController : Controller
{
private ApplicationDbContext _context { get; set; }
private string UserId { get; set; }
public IndustryController()
{
_context = new ApplicationDbContext();
UserId = System.Web.HttpContext.Current.User.Identity.GetUserId();
}
public ActionResult Index(int id = 0)
{
Industry data = new Industry();
if (id > 0)
data = _context.Industries.SingleOrDefault(c => c.Id == id);
if (data == null)
data = new Industry();
return View("Industry", data);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(Industry data)
{
if (!ModelState.IsValid)
return View("Industry", data);
var record = _context.Industries.Where(c => c.Description.Trim().ToLower() == data.Description.Trim().ToLower() && c.Id != data.Id);
if (record.Count() > 0)
{
ModelState.AddModelError("Duplicate Industry", "Industry already exist");
return View("Industry", data);
}
Industry cm = new Industry();
if (data.Id >= 1)
{
cm = _context.Industries.SingleOrDefault(c => c.Id == data.Id);
cm.Description = data.Description;
cm.UpdatedOn = DateTime.Now;
cm.UpdatedBy = UserId;
}
else
{
cm = data;
_context.Industries.Add(cm);
}
_context.SaveChanges();
return RedirectToAction("Index", new { id = 0 });
}
public类MasterController:Controller其中T:MasterTemplate,new()
{
私有应用程序上下文_上下文{get;set;}
私有字符串用户标识{get;set;}
公共主控官()
{
_context=新的ApplicationDbContext();
UserId=System.Web.HttpContext.Current.User.Identity.GetUserId();
}
公共操作结果索引(int id=0)
{
T数据=(id>0)
?数据=_context.Set().SingleOrDefault(c=>c.Id==Id)??新的T()
:新T();
返回视图(“视图”,数据);
}
[HttpPost]
[ValidateAntiForgeryToken]
公共操作结果保存(T数据)
{
如果(!ModelState.IsValid)
返回视图(“视图”,数据);
var record=_context.Set()。其中(c=>c.Description.Trim().ToLowerInvariant()==data.Description.Trim().ToLowerInvariant()&&c.Id!=data.Id);
if(record.Count()>0)
{
AddModelError($“重复的{typeof(T).Name}”,$“{typeof(T).Name}已经存在”);
返回视图(“视图”,数据);
}
如果(data.Id>=1)
{
tcm=_context.Set().SingleOrDefault(c=>c.Id==data.Id);
cm.Description=数据.Description;
cm.UpdatedOn=DateTime.Now;
cm.UpdatedBy=用户ID;
}
其他的
{
_context.Set().Add(数据);
}
_SaveChanges();
返回重定向操作(“索引”,新的{id=0});
}
将视图命名为“视图”(或与您在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>
}
@model主模板
@{
字符串名称=Model.GetType().name;
ViewBag.Title=名称;
Layout=“~/Views/Shared/_Layout.cshtml”;
}
@Model.PluralName管理
@使用(@Html.BeginForm(“Save”,name))
{
@Html.ValidationSummary(“请更正以下内容”)
@Html.HiddenFor(m=>m.Id)
@LabelFor(m=>m.Description)
@TextBoxFor(m=>m.Description,新的{@class=“formcontrol”,autocomplete=“off”})
@Html.ValidationMessageFor(m=>m.Description,$“{name}是必需的。”,新的{@class=“text danger”})
@Html.AntiForgeryToken()
拯救
}
@(姓名)
@节脚本
{
@Scripts.Render(“~/bundles/jqueryval”)
$(文档).ready(函数(){
$(“#mydata”).DataTable({
阿贾克斯:{
url:“/api/get/@(Model.PluralName)”,
dataSrc:“
},
栏目:[
{
数据:“说明”
},
{
数据:“id”,
渲染:函数(数据){
var url='@url.Action(“Index”,“@(name)”,new{id=“\uuuuu data\uuuuuuuu”});
返回“”;
}
}
]
});
});
}
好问题,我问了一个白色的问题,这可能会有帮助。哇,我想我们都遵循相同的模式,我从这个问题中删除了所有存储库,没有工作模式代码以保持简单,请查看我的其他问题,请检查您是否对此有答案,是否会继续阅读您的其他答案我不确定asp.netmvc允许我们创建通用控制器或自定义通用视图,但我认为如果您创建通用控制器或视图,您也需要自定义ioc管理器。我不能100%确定@name是否在整个视图中都可用。如果不是,请将“name”替换为“Model.GetType().name”。非常感谢您的回答,.GetTable()给出了一个错误,我是否应该导入任何缺少的名称空间。将其替换为.Set(),将在完全构建后让您知道它是否工作这也很简单:,我相应地编辑了文章。我在