Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC中避免重复代码的通用视图和控制器_C#_Asp.net Mvc_Generics_Interface - Fatal编程技术网

C# 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?

在我的MVC项目中,我有很多基本结构相同的模型。所以,我创建了一个主类,如下所示

    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(),将在完全构建后让您知道它是否工作这也很简单:,我相应地编辑了文章。我在