【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是页面

相关文章
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
34 3
|
15天前
|
XML 前端开发 安全
Spring MVC:深入理解与应用实践
Spring MVC是Spring框架提供的一个用于构建Web应用程序的Model-View-Controller(MVC)实现。它通过分离业务逻辑、数据、显示来组织代码,使得Web应用程序的开发变得更加简洁和高效。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring MVC,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
43 2
|
29天前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
45 4
|
2月前
|
测试技术 C# 数据库
C# 一分钟浅谈:测试驱动开发 (TDD) 实践
【10月更文挑战第18天】测试驱动开发(TDD)是一种软件开发方法论,强调先编写测试代码再编写功能代码,以确保代码质量和可维护性。本文从 TDD 的基本概念入手,详细介绍了其核心步骤——编写测试、运行测试并失败、编写代码使测试通过,以及“红绿重构”循环。文章还探讨了 TDD 的优势,包括提高代码质量、促进设计思考、减少调试时间和文档化。此外,文中分析了常见问题及解决方案,如测试覆盖率不足、测试代码过于复杂、忽视重构和测试依赖过多,并通过一个简单的计算器类的代码案例,展示了 TDD 的实际应用过程。
45 1
|
2月前
|
存储 JSON API
HTTP 请求与响应处理:C#中的实践
【10月更文挑战第4天】在现代Web开发中,HTTP协议至关重要,无论构建Web应用还是API开发,都需要熟练掌握HTTP请求与响应处理。本文从C#角度出发,介绍HTTP基础知识,包括请求与响应结构,并通过`HttpClient`库演示如何发送GET请求及处理响应,同时分析常见错误并提供解决方案,助你更高效地完成HTTP相关任务。
102 2
|
2月前
|
数据采集 C# 数据库
数据验证与错误处理:C#中的实践
【10月更文挑战第1天】在软件开发中,数据验证与错误处理至关重要,不仅能提升程序的健壮性和安全性,还能改善用户体验。本文从基础概念入手,详细介绍了C#中的数据验证方法,包括使用自定义属性和静态方法验证数据,以及常见的错误处理技巧,如Try-Catch-Finally结构和自定义异常。通过具体示例,帮助读者掌握最佳实践,构建高质量应用。
113 3
|
2月前
|
开发框架 缓存 算法
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
|
2月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
135 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
55 0
|
7月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
212 0