【C#编程最佳实践 八】MVC流程实践

简介: 【C#编程最佳实践 八】MVC流程实践

近期参与了工作台开发任务,亲身实践了mvc一个流程:(Model层)创建数据表—(Model层)创建Entity实体类—(Model层)创建数据表和实体的映射关系或调用通用的映射关系—(Model层)创建存储过程—(Model层)创建Dao层代码—(Model层)创建Provider层代码—(Controller层)在控制层写业务逻辑接口调用Model的provider,并返回给前端(View)—(View层)前端。体会了MVC全流程实践,也体会了团队合作如何实现。

Model

Model层相当于一块功能的封装,为控制层接口提供服务。一般会涉及到对数据表的操作,那么一般会涉及到以下操作。

创建数据表

USE [***LandingSite]
GO
/****** Object:  Table [dbo].[WorkBenchScene]    Script Date: 2017/12/22 11:39:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[WorkBenchScene](
    [ID] [uniqueidentifier] NOT NULL,
    [Name] [nvarchar](200) NOT NULL,
    [PID] [uniqueidentifier] NULL,
    [Application] [nvarchar](50) NULL,
    [TenantID] [int] NULL,
    [MetaObjectName] [varchar](100) NOT NULL,
    [CreatedBy] [int] NOT NULL,
    [CreatedTime] [datetime] NOT NULL,
    [ModifiedBy] [int] NULL,
    [ModifiedTime] [datetime] NULL,
    [ProcessJson] [nvarchar](max) NOT NULL,
    [IsEnabled] [bit] NULL,
 CONSTRAINT [PK_WorkBenchScene] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Script for SelectTopNRows command from SSMS  ******/
SELECT TOP (1000) [ID]
      ,[Name]
      ,[PID]
      ,[Application]
      ,[TenantID]
      ,[MetaObjectName]
      ,[CreatedBy]
      ,[CreatedTime]
      ,[ModifiedBy]
      ,[ModifiedTime]
      ,[ProcessJson]
      ,[IsEnabled]
  FROM [***LandingSite].[dbo].[WorkBenchScene]

创建实体类

using System;
using System.Runtime.Serialization;
namespace ***.Implementation.Entity.WorkBench
{
    /// <summary>
    /// 场景表对应的实体类
    /// </summary>
    public class WorkBenchScene : BaseEntity
    {
        /// <summary>
        /// 场景名
        /// </summary>
        [DataMember]
        public string Name { get; set; }
        /// <summary>
        /// 场景父ID
        /// </summary>
        public Guid PID { get; set; }
        /// <summary>
        /// 应用名
        /// </summary>
        public string Application { get; set; }
        /// <summary>
        /// 租户ID
        /// </summary>
        public int TenantID { get; set; }
        /// <summary>
        /// 实体名
        /// </summary>
        public string MetaObjectName { get; set; }
        /// <summary>
        /// 创建人
        /// </summary>
        public int CreatedBy { get; set; }
        /// <summary>
        /// 修改人
        /// </summary>
        public int ModifiedBy { get; set; }
        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime ModifiedTime { get; set; }
        /// <summary>
        /// 流程json字符串ProcessJson
        /// </summary>
        public string ProcessJson { get; set; }
        /// <summary>
        /// 是否启用
        /// </summary>
        public bool IsEnabled { get; set; }
    }
}

创建数据表和实体的映射关系

创建自定义映射关系

#region 私有 mapper
        private ***.Data.MapperDelegates.RecordMapper<API> GetMapper()
        {
            return delegate (IRecord record, API model)
            {
                model.ID = record.Get<Guid>("ID");
                model.Application = record.GetOrDefault<string>("Application", string.Empty);
                model.ApiType = record.GetOrDefault<int>("ApiType", 0);
                model.ResourceCode = record.GetOrDefault<string>("ResourceCode", string.Empty);
                model.ResourceName = record.GetOrDefault<string>("ResourceName", string.Empty);
                model.GetListAPI = record.GetOrDefault<string>("GetListAPI", string.Empty);
                model.ImportDataAPI = record.GetOrDefault<string>("ImportDataAPI", string.Empty);
                model.Enabled = record.GetOrDefault<bool>("Enabled", true);
                model.CreatedTime = record.GetOrDefault<DateTime>("CreatedTime", DateTime.MinValue);
                model.ShowFields = record.GetOrDefault("ShowFields", string.Empty);
                model.WhiteList = record.GetOrDefault("WhiteList", string.Empty);
            };
        }
        #endregion 私有 mapper

调用默认的映射关系

注意,默认的映射规则,实体的属性名和数据表的列名一定要对的上。

protected ***.Data.MapperDelegates.RecordMapper<T> GetMapper()
        {
            return delegate (IRecord record, T model)
            {
                if (Properties != null)
                {
                    foreach (var item in Properties)
                    {
                        try
                        {
                            SetValue(item, record, ref model);
                        }
                        catch (Exception e)
                        {
                            System.Console.WriteLine($"error: {EntityName}.{ item.Name}"); //todo ....logger
                        }
                    }
                }
            };
        }
        private static void SetValue(PropertyInfo item, IRecord record, ref T model)
        {
            var fieldName = item.Name;
            switch (item.PropertyType.FullName)
            {
                case "System.Int32":
                    item.SetValue(model, record.GetOrDefault<int>(fieldName, 0));
                    break;
                case "System.String":
                    item.SetValue(model, record.GetOrDefault<string>(fieldName, string.Empty));
                    break;
                case "System.Boolean":
                    item.SetValue(model, record.GetOrDefault<Boolean>(fieldName, false));
                    break;
                case "System.DateTime":
                    item.SetValue(model, record.GetOrDefault<DateTime>(fieldName, DateTime.MinValue));
                    break;
                case "System.Float":
                    item.SetValue(model, record.GetOrDefault<float>(fieldName, 0));
                    break;
                case "System.Double":
                    item.SetValue(model, record.GetOrDefault<Double>(fieldName, 0));
                    break;
                case "System.Guid":
                    item.SetValue(model, record.GetOrDefault<Guid>(fieldName, Guid.Empty));
                    break;
                default:
                    throw new TypeLoadException($"未知字段类型异常.fieldName:{fieldName},type:{item.PropertyType.FullName}");
            }
        }

创建存储过程

USE [***LandingSite]
GO
/****** Object:  StoredProcedure [dbo].[WorkBenchScene_GetByMetaObjectName]    Script Date: 2017/12/22 12:09:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      tianmaolin
-- Create date: 2017-12-22
-- Description: 根据实体编码获取场景
-- =============================================
ALTER PROCEDURE [dbo].[WorkBenchScene_GetByMetaObjectName](
@MetaObjectName varchar(100)
)
AS
SELECT  *  FROM dbo.WorkBenchScene where MetaObjectName=@MetaObjectName

创建Dao层代码

创建Provider层代码

Controller层

/// <summary>
        /// 公有方法:通过实体名获取场景名和场景ID列表组
        /// </summary>
        /// <param name="metaObjectName"></param>
        /// <returns></returns>
        [HttpGet]   //通过get方式获取
        public JsonResult GetByMetaObjectName(string metaObjectName)
        {
            if (!string.IsNullOrEmpty(metaObjectName))
            {
                List<WorkBenchScene> lw = WorkBenchSceneProvider.Instance.GetByMetaObjectName(metaObjectName);  //获取场景列表
                if (lw == null || lw.Count == 0)
                {
                    return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "场景列表获取失败" }, JsonRequestBehavior.AllowGet);
                }
                List<WorkBenchDic> list = new List<WorkBenchDic>();
                foreach (var item in lw)
                {
                    list.Add(new WorkBenchDic(item.ID.ToString(), item.Name));
                }
                return Json(new Helper.OperationResult { code = (int)CodeType.Success, message = "获取成功", param = list }, JsonRequestBehavior.AllowGet);
            }
            return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "参数为空" }, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// 公有方法:通过场景id获取该场景详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public JsonResult GetByID(Guid id)
        {
            if (!string.IsNullOrEmpty(id.ToString()))
            {
                WorkBenchScene wbs = WorkBenchSceneProvider.Instance.GetById(id); //获取确定场景
                if (wbs == null)
                {
                    return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "场景获取失败" }, JsonRequestBehavior.AllowGet);
                }
                return Json(new Helper.OperationResult { code = (int)CodeType.Success, message = "获取成功", param = wbs.ProcessJson }, JsonRequestBehavior.AllowGet);
            }
            return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "参数为空" }, JsonRequestBehavior.AllowGet);
        }

View层

SettingValue是页面

相关文章
|
4月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
139 8
|
1月前
|
存储 机器学习/深度学习 监控
公司监控软件有哪些?监测方案:基于布隆过滤器的 C# 异常行为检测实践探索
本文探讨了布隆过滤器在公司监控软件中的技术应用,介绍其原理、优势及C#实现代码,助力企业高效构建数据安全防护体系。
56 0
|
3月前
|
监控 算法 安全
公司电脑监控软件关键技术探析:C# 环形缓冲区算法的理论与实践
环形缓冲区(Ring Buffer)是企业信息安全管理中电脑监控系统设计的核心数据结构,适用于高并发、高速率与短时有效的多源异构数据处理场景。其通过固定大小的连续内存空间实现闭环存储,具备内存优化、操作高效、数据时效管理和并发支持等优势。文章以C#语言为例,展示了线程安全的环形缓冲区实现,并结合URL访问记录监控应用场景,分析了其在流量削峰、关键数据保护和高性能处理中的适配性。该结构在日志捕获和事件缓冲中表现出色,对提升监控系统效能具有重要价值。
99 1
|
4月前
|
存储 监控 算法
基于 C# 时间轮算法的控制局域网上网时间与实践应用
在数字化办公与教育环境中,局域网作为内部网络通信的核心基础设施,其精细化管理水平直接影响网络资源的合理配置与使用效能。对局域网用户上网时间的有效管控,已成为企业、教育机构等组织的重要管理需求。这一需求不仅旨在提升员工工作效率、规范学生网络使用行为,更是优化网络带宽资源分配的关键举措。时间轮算法作为一种经典的定时任务管理机制,在局域网用户上网时间管控场景中展现出显著的技术优势。本文将系统阐述时间轮算法的核心原理,并基于 C# 编程语言提供具体实现方案,以期深入剖析该算法在局域网管理中的应用逻辑与实践价值。
106 5
|
10月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
203 3
|
9月前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
553 12
|
9月前
|
XML 前端开发 安全
Spring MVC:深入理解与应用实践
Spring MVC是Spring框架提供的一个用于构建Web应用程序的Model-View-Controller(MVC)实现。它通过分离业务逻辑、数据、显示来组织代码,使得Web应用程序的开发变得更加简洁和高效。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring MVC,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
499 2
|
10月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
398 4
|
11月前
|
测试技术 C# 数据库
C# 一分钟浅谈:测试驱动开发 (TDD) 实践
【10月更文挑战第18天】测试驱动开发(TDD)是一种软件开发方法论,强调先编写测试代码再编写功能代码,以确保代码质量和可维护性。本文从 TDD 的基本概念入手,详细介绍了其核心步骤——编写测试、运行测试并失败、编写代码使测试通过,以及“红绿重构”循环。文章还探讨了 TDD 的优势,包括提高代码质量、促进设计思考、减少调试时间和文档化。此外,文中分析了常见问题及解决方案,如测试覆盖率不足、测试代码过于复杂、忽视重构和测试依赖过多,并通过一个简单的计算器类的代码案例,展示了 TDD 的实际应用过程。
192 1
|
11月前
|
数据采集 C# 数据库
数据验证与错误处理:C#中的实践
【10月更文挑战第1天】在软件开发中,数据验证与错误处理至关重要,不仅能提升程序的健壮性和安全性,还能改善用户体验。本文从基础概念入手,详细介绍了C#中的数据验证方法,包括使用自定义属性和静态方法验证数据,以及常见的错误处理技巧,如Try-Catch-Finally结构和自定义异常。通过具体示例,帮助读者掌握最佳实践,构建高质量应用。
328 4