C#编写软件发布公告2——服务端

news2024/11/14 13:29:32

简单说明

框架:.NET 6.0 MVC 数据库:sqlLite3(当然这是为考虑本地数据简单,可以考虑使用大型数据库)

一、界面效果展示

1、启动主页面

2、记录摘要界面

3、对应版本详细

二、实现代码逻辑

1、启动主页面

//关联日志文件写
builder.Logging.AddProvider(new CustomFileLoogerProvider(new CustomFileLoggerConfiguration()
{
    MinLevel = (LogLevel)Enum.Parse(typeof(LogLevel), builder.Configuration["FileLogPath:MinLogLevel"]),
    InLogLevel = LogLevel.Information,
    LogPath = builder.Environment.ContentRootPath + builder.Configuration["FileLogPath:LogPath"]
}));

// Add services to the container.
builder.Services.AddControllersWithViews();
//配置DBServer
builder.Services.AddSingleton<IDBServer, DBServer>();

2、数据库相关

2.1 服务接口

  public interface IDBServer
  {
      HomeViewData HomeViewData { get; }

      string RecordViewData { get; }

      List<RecordData> SNInfoLists { get; }

      void UpDataHomeViewData();

      void UpDataHistoricalSummaryViewData(string? sn);

      void UpData();

      /// <summary>
      /// 更新历史版本信息
      /// </summary>
      /// <param name="sn">版本号</param>
      /// <param name="dataTime">发行日期</param>
      /// <param name="InfoStr">详细信息</param>
      /// <returns></returns>
      bool UpDataDetailedInformation(string sn, string dataTime, string InfoStr);
  }

2.2 服务实现

 public class SqlHelp
 {
     private string connectionString = @"Data Source=MyDatabase.db;";
     private SQLiteConnection connection;

     public ILogger<DBServer> Logger { get; }

     public SqlHelp(ILogger<Server.DBServer> logger)
     {
         connection = new SQLiteConnection(connectionString);
         Logger = logger;
     }


     //仅获取简要信息 包含日期和版本号
     internal void GetReleaseBriefInfo(ref List<RecordData> list)
     {
         string sql = "SELECT * FROM ReRecord;";
         SQLiteCommand command = new SQLiteCommand(sql, connection);

         connection.Open();
         SQLiteDataAdapter adaptr = new SQLiteDataAdapter(command);
         DataTable dt = new DataTable();
         adaptr.Fill(dt);
         adaptr.Dispose();
         command.Dispose();
         list = new List<RecordData>(dt.Rows.Count);
         for (int i = 0; i < dt.Rows.Count; i++)
         {
             list.Add(new RecordData(dt.Rows[i][2].ToString(), dt.Rows[i][1].ToString()));
         }

         connection.Close();
     }

     //根据sn查找完整信息
     internal void GetReleaseInfo(string sn, ref List<RecordDataInfo> list)
     {
         string sql = "SELECT * FROM ReRecordDescribe where Sn=@sn;";
         SQLiteCommand command = new SQLiteCommand(sql, connection);
         //SQLiteParameter[] para = new SQLiteParameter[]
         //{
         //    new SQLiteParameter("@sn",sn)
         //};
         SQLiteParameter snPara = new SQLiteParameter("@sn", sn);
         command.Parameters.Add(snPara);
         connection.Open();
         SQLiteDataAdapter adaptr = new SQLiteDataAdapter(command);
         DataTable dt = new DataTable();
         adaptr.Fill(dt);
         adaptr.Dispose();
         command.Dispose();
         list = new List<RecordDataInfo>(dt.Rows.Count);
         for (int i = 0; i < dt.Rows.Count; i++)
         {
             list.Add(new RecordDataInfo(Convert.ToInt32(dt.Rows[i][2].ToString()), dt.Rows[i][3].ToString()));
         }

         connection.Close();
     }

     private bool FindSNInfo(string sn, string dateInfo)
     {
         string sql = "SELECT * FROM ReRecord where DateInfo=@DateInfo and Sn=@sn;";
         SQLiteCommand command = new SQLiteCommand(sql, connection);
         SQLiteParameter[] para = new SQLiteParameter[]
         {
             new SQLiteParameter("@sn",sn),
             new SQLiteParameter("@DateInfo",dateInfo)
         };
         command.Parameters.AddRange(para);
         connection.Open();
         try
         {
             SQLiteDataAdapter adaptr = new SQLiteDataAdapter(command);
             DataTable dt = new DataTable();
             adaptr.Fill(dt);
             adaptr.Dispose();
             command.Dispose();

             connection.Close();
             if (dt.Rows.Count == 0)//没有进行增加
             {
                 return false;
             }
             return true;
         }
         catch (Exception ex)
         {
             throw ex;
         }
         finally
         {
             connection.Close();
             command.Dispose();
         }
     }

     private void AddSnInfo(string sn, string dateInfo)
     {
         string sql = "INSERT INTO ReRecord(DateInfo,Sn) VALUES(@DateInfo,@sn);";
         SQLiteCommand command = new SQLiteCommand(sql, connection);
         SQLiteParameter[] para = new SQLiteParameter[]
         {
                 new SQLiteParameter("@sn",sn),
                 new SQLiteParameter("@DateInfo",dateInfo)
         };

         command.Parameters.AddRange(para);

         connection.Open();
         try
         {
             int a = command.ExecuteNonQuery();
         }
         catch (Exception ex)
         {
             throw ex;
         }

         connection.Close();
     }

     private void DelOrgDescribeInfo(string sn)
     {
         string sql = "DELETE FROM ReRecordDescribe WHERE Sn=@sn;";
         SQLiteCommand command = new SQLiteCommand(sql, connection);

         SQLiteParameter snPara = new SQLiteParameter("@sn", sn);
         command.Parameters.Add(snPara);
         connection.Open();

         try
         {
             int a = command.ExecuteNonQuery();
         }
         catch (Exception ex)
         {
             throw ex;
         }

         connection.Close();
     }

     private bool AddDescribeInfo(string sn, List<RecordDataInfo> list)
     {
         string sql = "INSERT INTO ReRecordDescribe(Sn,Num,Describe) VALUES(@sn,@Num,@Describe);";
         connection.Open();

         SQLiteTransaction tx = connection.BeginTransaction();
         SQLiteCommand command = new SQLiteCommand(sql, connection);
         command.Transaction = tx;
         try
         {
             for (int i = 0; i < list.Count; i++)
             {
                 SQLiteParameter[] para = new SQLiteParameter[]
                 {
                 new SQLiteParameter("@sn",sn),
                 new SQLiteParameter("@Num",list[i].Num),
                 new SQLiteParameter("@Describe",list[i].Describe)
                 };
                 command.Parameters.AddRange(para);
                 int a = command.ExecuteNonQuery();
             }
             tx.Commit();
             command.Dispose();
         }
         catch (Exception ex)
         {
             Logger.LogWarning("AddDescribeInfo:" + ex.Message);
             tx.Rollback();
         }
         connection.Close();
         return true;
     }

     //根据sn查找完整信息
     internal void UpdateInfo(string sn, string dateInfo, List<RecordDataInfo> list)
     {
         if (!FindSNInfo(sn, dateInfo))
         {
             AddSnInfo(sn, dateInfo);
         }
         DelOrgDescribeInfo(sn);
         AddDescribeInfo(sn, list);
     }
 }

3、日志文件写实现

3.1 ILogger实现

public class CustomFileLogger : ILogger
{
    private readonly string _name;
    private readonly CustomFileLoggerConfiguration _config;
    private LogLevel _logLevel;

    public CustomFileLogger(string name, CustomFileLoggerConfiguration config)
    {
        _name = name;
        _config = config;
        if (config != null)
        {
            if (!Directory.Exists(config.LogPath))
            {
                Directory.CreateDirectory(config.LogPath);
            }
        }
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return null;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return logLevel == _config.InLogLevel;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
    {
        if (!IsEnabled(logLevel))
        {
            return;
        }
        _logLevel = logLevel;
        FileLog($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:fff")} - {logLevel.ToString()} - {_name} - {formatter(state, exception)} \n");
    }

    private  void FileLog(string strLog)
    {
        string fileName = DateTime.Now.ToString("yyyy-MM-dd") + "_" + _logLevel.ToString() + ".txt";
        string filePath = _config.LogPath + "\\" + fileName;
          File.AppendAllText(filePath, strLog);
       //  File.AppendAllTextAsync(filePath, strLog);
    }
}

3.2 ILoggerProvider实现

 public class CustomFileLoogerProvider:ILoggerProvider
 {
     private readonly CustomFileLoggerConfiguration _config;
     public CustomFileLoogerProvider(CustomFileLoggerConfiguration config)
     {
         _config = config;
     }

     public ILogger CreateLogger(string categoryName)
     {
         return new CustomFileLogger(categoryName,_config);
     }

     public void Dispose()
     {
        
     }
 }

4、业务调用

 public class HomeController : Controller
 {
     private readonly ILogger<HomeController> _logger;
     private readonly IDBServer dBServer;

     public HomeController(ILogger<HomeController> logger, IDBServer dBServer)
     {
         _logger = logger;
         this.dBServer = dBServer;
     }

     public IActionResult Index()
     {
         dBServer.UpDataHomeViewData();
         return View("Index", dBServer.HomeViewData);
     }

     public IActionResult HistoricalSummary(string? SN)
     {
         dBServer.UpDataHistoricalSummaryViewData(SN);
         return View("HistoricalSummary", dBServer.HomeViewData);
     }

     public IActionResult RecordInfo()
     {
         dBServer.UpData();
         this.ViewData["info"] = DateTime.Now.ToString() + dBServer.RecordViewData;

         return View("RecordInfo", dBServer.SNInfoLists);
     }

     [HttpPost]
     public string PostInfo(string SN, string DateTime, string Info)
     {
         if (dBServer.UpDataDetailedInformation(SN, DateTime, Info))
         {
             return "更新成功!";
         }
         return "更新失败!";
     }

     public IActionResult About()
     {
         return View();
     }

     [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
     public IActionResult Error()
     {
         return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
     }
 } public class HomeController : Controller
 {
     private readonly ILogger<HomeController> _logger;
     private readonly IDBServer dBServer;

     public HomeController(ILogger<HomeController> logger, IDBServer dBServer)
     {
         _logger = logger;
         this.dBServer = dBServer;
     }

     public IActionResult Index()
     {
         dBServer.UpDataHomeViewData();
         return View("Index", dBServer.HomeViewData);
     }

     public IActionResult HistoricalSummary(string? SN)
     {
         dBServer.UpDataHistoricalSummaryViewData(SN);
         return View("HistoricalSummary", dBServer.HomeViewData);
     }

     public IActionResult RecordInfo()
     {
         dBServer.UpData();
         this.ViewData["info"] = DateTime.Now.ToString() + dBServer.RecordViewData;

         return View("RecordInfo", dBServer.SNInfoLists);
     }

     [HttpPost]
     public string PostInfo(string SN, string DateTime, string Info)
     {
         if (dBServer.UpDataDetailedInformation(SN, DateTime, Info))
         {
             return "更新成功!";
         }
         return "更新失败!";
     }

     public IActionResult About()
     {
         return View();
     }

     [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
     public IActionResult Error()
     {
         return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
     }
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1957227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

音频处理过程

1、音频 &#xff08;1&#xff09;打开设备 &#xff08;2&#xff09;从音频设备中读取数据 &#xff08;3&#xff09;将音频设备中读取的数据写入文件夹中 &#xff08;4&#xff09; 通过界面控制开始录制和结束录制&#xff08;使用多线程和状态码控制&#xff09; &…

Spring监听器不同的注册方式下带来的监听范围的变化

事件监听注册的几种方式 ApplicationContext下面简称AC 1.构建SpringApplication时注册&#xff08;可以监听AC启动阶段事件&#xff09; // 方式一: //写法1 SpringApplication application new SpringApplicationBuilder().listeners(new ApplicationPidFileWriter()).bu…

网课录制新技能,声画同步,三款录屏软件助力教师高效授课

在数字化教育的浪潮中&#xff0c;教师和培训讲师们越来越依赖于录制网课来提升教学效果。无论是PPT课件的深入讲解&#xff0c;Word文档的详细演示&#xff0c;还是操作手册的直观展示&#xff0c;一款出色的录屏软件都能使这一过程更加生动和高效。今天&#xff0c;我将为大家…

【C++/STL】:哈希 -- 线性探测哈希桶

目录 &#x1f4a1;前言一&#xff0c;unordered系列容器二&#xff0c;哈希2.1 哈希的概念2.2 哈希函数2.3 哈希冲突 三&#xff0c;哈希冲突解决(重点)3.1 开放定址法3.2 哈希桶(重点) 四&#xff0c;线性探测的实现4.1 线性探测的基本框架4.2 插入操作4.3 查找操作4.4 删除操…

【C++】类和对象——Lesson1

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C &#x1f680;本系列文章为个人学习笔记…

【Golang 面试 - 基础题】每日 5 题(十)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

关联映射和缓存机制学习笔记

学习视频&#xff1a;4001 关联映射概述_哔哩哔哩_bilibili~4007 案例&#xff1a;商品的类别_哔哩哔哩_bilibili 目录 1.关联映射概述 1.1关联映射关系 一对一关系 一对多关系 多对多关系 Java对象如何描述事物之间的关系 1.2一对一查询 元素 a.嵌套查询方式 b.嵌套结果方…

Spring Cache常用注解

依赖代码如下&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency> 常用注解详解 1. Cacheable 作用&#xff1a;主要用于配置方法&#xff0c;使其…

第九届全球渲染大赛来了!CG爱好者准备好了吗!

在CG界的日历上&#xff0c;二月和八月总是特别繁忙的月份。这两个月&#xff0c;全球CG艺术界最盛大的赛事——全球渲染大赛&#xff0c;都会开放报名&#xff0c;吸引着世界各地的CG艺术家和爱好者参与。备受期待的第九届全球渲染大赛&#xff0c;已经定于2024年8月3日在美国…

微信私域运营工具分享

解决微信多管理难的问题&#xff0c;多微信工作重复做&#xff0c;效率低的问题&#xff0c;防止飞单、删除客户&#xff0c;解决私域运营的难题

在双碳目标下,如何实现工厂的数字化改造升级

在"双碳"目标下&#xff0c;如何实现工厂的数字化改造升级 在“双碳”目标&#xff0c;即2030年前实现碳达峰、2060年前实现碳中和的宏伟蓝图下&#xff0c;企业作为经济社会活动的主体&#xff0c;其改造升级不仅是响应国家战略的必然要求&#xff0c;也是实现可持…

软件压力测试知识大揭秘,专业软件测评公司推荐

在信息技术迅猛发展的今天&#xff0c;软件已经成为各个行业运作的核心。有助于提升工作效率和管理水平的&#xff0c;软件的稳定性和性能也变得尤为重要。而软件压力测试&#xff0c;作为一种重要的测试手段&#xff0c;逐渐受到了更多企业的重视。 软件压力测试&#xff0c;…

【ROS 最简单教程 001/300】ROS 概念介绍

ROS&#xff1a;Robot Operating System 【适用于机器人的开源元操作系统】 ROS Plumbing Tools Capabilities Ecosystem 通讯 Plumbing ⭐ 实现ROS不同节点之间的交互工具 Tools ⭐ 工具软件包 (ROS中的开发和调试工具)&#xff0c;提供 仿真 功能&#xff1b;功能 Capabi…

图文好物和无人直播实操:定位/涨粉/养号/橱窗/作品/制作/剪辑/开播/等等

1.前言 各位小伙伴大家好&#xff0c;这里是天夏共创&#xff0c;免费分享副业/创业精品项目资源&#xff0c;打破互联网创业/副业信息壁垒&#xff0c;和您一起共享副业/创业项目资源&#xff0c;开启智能化创业/副业新时代&#xff01;致力于每天免费分享全网互联网精品VIP项…

React类组件生命周期与this关键字

类组件生命周期 参考链接 一图胜千言&#xff08;不常用的生命周期函数已隐藏&#xff09; 代码&#xff1a; //CC1.js import { Component } from "react";export default class CC1 extends Component {constructor(props) {super(props);console.log("con…

基于IDEA+Mysql+SpringBoot开发的社区养老服务管理系统

基于IDEAMysqlSpringBoot开发的社区养老服务管理系统 项目介绍&#x1f481;&#x1f3fb; node -version 14.21.3 在当前社会老龄化趋势日益加剧的背景下&#xff0c;构建一个高效、便捷的社区网养老服务管理系统显得尤为重要。本项目基于Spring Boot框架开发&#xff0c;旨…

网站打不开怎么办,收藏以备不时之需

DNS设置示范教程 部分地区有使用移动网络的小伙伴们吐槽无法访问部分网站的情况&#xff0c;同样的网站&#xff0c;使用电信和联通的用户就能正常访问。 这其实有很大几率是由于运营商的网络问题导致的&#xff0c;容易出现网站打不开的结果。 要解决移动网络无法访问的情况…

【React Hooks原理 - useTransition】

概述 在上一篇中我们介绍了useDeferredValue的基本原理&#xff0c;本文主要介绍一下useTransition这个Hook&#xff0c;之所以在这里提到useDeferredValue&#xff0c;是因为这两个Hook都是在React18引入的进行渲染优化的Hooks&#xff0c;在某些功能上是重叠的&#xff0c;主…

YOLO入门教程(一)——训练自己的模型【含教程源码 + 故障排查】

目录 引言前期准备Step1 打标训练Step2 格式转换Step3 整理训练集Step4 训练数据集4.1创建yaml文件4.2训练4.3故障排查4.3.1OpenCV版本故障&#xff0c;把OpenCV版本升级到4.0以上4.3.2NumPy版本故障&#xff0c;把NumPy降低版本到1.26.44.3.3没有安装ultralytics模块4.3.4Aria…

自闭症儿童上学指南:帮助孩子适应校园生活

在自闭症儿童成长的道路上&#xff0c;校园生活是他们融入社会、学习新知、发展社交技能的重要一步。作为星启帆自闭症儿童康复机构&#xff0c;我们深知这一过程对于孩子及其家庭而言既充满挑战也极具意义。 一、前期准备&#xff1a;建立坚实的支持体系 1. 深入了解孩子需求 …