编辑 | blame | 历史 | 原始文档

C# 代码质量审查报告

概述

本报告分析了您的MES API项目中已修改的C#文件,识别出代码质量问题并提供改进建议。

主要问题总结

🔴 严重问题

  1. 命名规范不一致 - 混合使用PascalCase和camelCase
  2. SQL注入风险 - 字符串拼接构建SQL语句
  3. 事务管理混乱 - 不一致的事务处理模式
  4. 异常处理不当 - 捕获后重新抛出通用异常

🟡 中等问题

  1. 数据类型使用不当 - 过度使用string类型
  2. 缺少输入验证 - 方法参数未验证
  3. 魔法数字和字符串 - 硬编码值缺少常量定义
  4. 方法职责过多 - 单个方法包含多种逻辑

详细问题分析

1. XJPageResult.cs - DTO类设计问题

文件位置: MES.Service/Dto/service/XJPageResult.cs

问题:

public string? createUser { get; set; }    // ❌ camelCase
public string? SearchValue { get; set; }   // ✅ PascalCase
public string? startDate { get; set; }     // ❌ camelCase

建议改进:

public string? CreateUser { get; set; }
public string? SearchValue { get; set; }
public DateTime? StartDate { get; set; }   // 使用正确的数据类型
public DateTime? EndDate { get; set; }
public bool? ArrivalFilter { get; set; }   // 使用bool而不是int

原因:
- C#属性应使用PascalCase命名规范
- 日期字段应使用DateTime而不是string
- 布尔值应使用bool类型

2. MessageCenter.cs - 数据模型问题

文件位置: MES.Service/Modes/MessageCenter.cs

问题:

[SugarColumn(ColumnName = "CREATE_DATE")]
public string? CreateDate { get; set; }    // ❌ 日期应为DateTime

[SugarColumn(ColumnName = "Content_Type")]  // ❌ 数据库列名不规范
public string? ContentType { get; set; }

[SugarColumn(IsIgnore = true)] 
public int? isShow { get; set; }           // ❌ camelCase命名

建议改进:

[SugarColumn(ColumnName = "CREATE_DATE")]
public DateTime? CreateDate { get; set; }

[SugarColumn(ColumnName = "CONTENT_TYPE")]  // 统一大写下划线格式
public string? ContentType { get; set; }

[SugarColumn(IsIgnore = true)] 
public bool? IsShow { get; set; }          // 正确命名和类型

3. MessageCenterManager.cs - 服务层问题

文件位置: MES.Service/service/MessageCenterManager.cs

严重问题 - SQL注入风险:

var sql = string.Format(
    "SELECT * FROM (SELECT \"ID\",\"TABLE_NAME\"... WHERE RowIndex BETWEEN {0} AND {1} ",
    startRow, endRow);  // ❌ 存在SQL注入风险

建议改进:

public (List<MessageCenter> item, int TotalCount) GetPushFailedPage(MessageCenter query)
{
    var totalCount = IsShow(query);
    
    return Context.Queryable<MessageCenter>()
        .Where(it => it.Result == 0 && it.Seq == 1 && it.Title != null)
        .OrderByDescending(it => it.CreateDate)
        .ToPageList(query.PageIndex, query.Limit, ref totalCount);
}

其他问题:

// ❌ 硬编码的魔法数字
entity.Result = 0;
entity.DealWith = 0;
entity.Status = 1;

// ❌ 字符串格式化日期
entity.CreateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

建议改进:

// ✅ 使用常量
public static class MessageStatus 
{
    public const short Failed = 0;
    public const short Success = 1;
    public const short Pending = 0;
    public const short Processed = 1;
}

// ✅ 使用DateTime类型
entity.CreateDate = DateTime.Now;

4. LljService.cs - 业务逻辑问题

文件位置: MES.Service/service/QC/LljService.cs

严重问题:

public (List<LtsLlj> item, int TotalCount) GetPage(XJPageResult queryObj)
{
    if (queryObj.createUser.IsNullOrEmpty()) return ([], 0);  // ❌ 无输入验证
    
    var id = Convert.ToDecimal(queryObj.id);  // ❌ 可能抛出异常
}

建议改进:

public (List<LtsLlj> item, int TotalCount) GetPage(XJPageResult queryObj)
{
    // ✅ 输入验证
    if (queryObj == null)
        throw new ArgumentNullException(nameof(queryObj));
        
    if (string.IsNullOrEmpty(queryObj.CreateUser))
        return (new List<LtsLlj>(), 0);
    
    // ✅ 安全的类型转换
    if (!decimal.TryParse(queryObj.Id, out var id))
        id = 0;
}

复杂方法问题:

// ❌ autoResult方法过于复杂(100+行),包含多种职责
private int autoResult(MesQaItemsDetectDetail12 detail)
{
    // 查询检验项目
    // 计算检验结果  
    // 更新检验状态
    // 更新检验单状态
    // 业务逻辑判断
    // 数据库更新
}

建议改进:

// ✅ 拆分为多个职责单一的方法
public int ProcessInspectionResult(MesQaItemsDetectDetail12 detail)
{
    var inspectionItem = GetInspectionItem(detail.MainId);
    var inspectionCounts = CalculateInspectionCounts(detail.MainId);
    var result = DetermineInspectionResult(inspectionCounts, inspectionItem);
    
    UpdateInspectionDetail(detail, result, inspectionCounts);
    
    if (IsInspectionComplete(detail.ReleaseNo))
    {
        UpdateInspectionOrder(detail);
    }
    
    return 1;
}

5. MessageCenterController.cs - 控制器问题

文件位置: MESApplication/Controllers/Base/MessageCenterController.cs

问题:

// ❌ 重复的异常处理模式
[HttpPost("ResetUpdate")]
public ResponseResult ResetUpdate([FromBody] MessageCenter data)
{
    try
    {
        dynamic resultInfos = new ExpandoObject();  // ❌ 使用dynamic
        resultInfos.tbBillList = m.ResetUpdate(data);
        return new ResponseResult { status = 0, message = "OK", data = resultInfos };
    }
    catch (Exception ex)
    {
        return ResponseResult.ResponseError(ex);  // ❌ 重复代码
    }
}

建议改进:

// ✅ 使用强类型响应和基类方法
[HttpPost("ResetUpdate")]
public ResponseResult ResetUpdate([FromBody] MessageCenter data)
{
    return ExecuteWithErrorHandling(() => 
    {
        var result = m.ResetUpdate(data);
        return CreateSuccessResponse(result);
    });
}

// ✅ 基类方法减少重复代码
protected ResponseResult ExecuteWithErrorHandling<T>(Func<T> action)
{
    try
    {
        var result = action();
        return CreateSuccessResponse(result);
    }
    catch (Exception ex)
    {
        return ResponseResult.ResponseError(ex);
    }
}

改进建议优先级

🔥 立即修复 (高优先级)

  1. 修复SQL注入风险 - MessageCenterManager.cs:20-22
  2. 统一命名规范 - 所有属性使用PascalCase
  3. 安全的类型转换 - 添加TryParse验证

⚡ 尽快修复 (中优先级)

  1. 正确的数据类型 - 日期使用DateTime,布尔值使用bool
  2. 输入验证 - 所有公共方法添加参数验证
  3. 常量定义 - 替换魔法数字和字符串

💡 逐步改进 (低优先级)

  1. 方法重构 - 拆分复杂方法
  2. 统一异常处理 - 使用基类方法减少重复
  3. 强类型化 - 避免使用dynamic和ExpandoObject

代码规范建议

命名规范

// ✅ 正确的命名
public class MessageCenter           // PascalCase for classes
{
    public string TableName { get; set; }     // PascalCase for properties
    public DateTime CreateDate { get; set; }   // PascalCase for properties
    
    private readonly string _connectionString; // camelCase with underscore for private fields
    
    public void ProcessMessage() { }           // PascalCase for methods
}

类型安全

// ✅ 使用正确的数据类型
public class InspectionDto
{
    public DateTime? StartDate { get; set; }   // 而不是 string
    public bool IsCompleted { get; set; }      // 而不是 int
    public decimal Quantity { get; set; }      // 而不是 string
}

异常处理

// ✅ 具体的异常处理
public decimal ParseId(string idString)
{
    if (string.IsNullOrEmpty(idString))
        throw new ArgumentException("ID cannot be null or empty", nameof(idString));
        
    if (!decimal.TryParse(idString, out var id))
        throw new FormatException($"Invalid ID format: {idString}");
        
    return id;
}

总结

您的代码整体结构良好,但在以下几个方面需要改进:

  1. 命名规范一致性 - 严格遵循C#命名约定
  2. 类型安全 - 使用适当的数据类型
  3. 安全性 - 避免SQL注入和输入验证
  4. 可维护性 - 减少代码重复,拆分复杂方法

建议按照优先级逐步改进,从安全问题开始,然后是命名规范,最后是代码结构优化。