Asp.Net Core實戰(乾貨)

来源:https://www.cnblogs.com/sportsky/archive/2018/08/10/9400419.html
-Advertisement-
Play Games

序言 使用.NET Core,團隊可以更容易專註的在.net core上工作。比如核心類庫(如System.Collections)的更改仍然需要與.NET Framework相同的活力,但是ASP.NET Core或Entity Framework Core可以更輕鬆地進行實質性更改,而不受向後兼 ...


序言

使用.NET Core,團隊可以更容易專註的在.net core上工作。比如核心類庫(如System.Collections)的更改仍然需要與.NET Framework相同的活力,但是ASP.NET Core或Entity Framework Core可以更輕鬆地進行實質性更改,而不受向後相容性的限制。.NET Core借鑒了.NET Framework的最佳實踐,並將軟體工程的最新進展結合在一起。

寒暄、扯淡已經完畢,,,下麵是我最近時間對.Net Core整理的相關知識,覺得這些在項目中是最基礎且最會應用到的,,,,不喜歡扯理論,直接擼碼:

1、淺談Startup類

2、自定義路由

3、跨域設置

4、自定義讀取配置文件信息

5、程式集批量依賴註入

6、使用NLog寫入文件日誌

7、使用NLog寫入資料庫日誌

8、Nlog標簽解讀

一、淺談Startup類

在ASP.NET Core應用程式中,使用一個按約定Startup命名Startup,在Program.cs中使用WebHostBuilderExtensions UseStartup <TStartup>方法指定,但通常使用系統預設的startup,可以通過startup的構造函數進行依賴註入,startup類中必須包含Configure方法同時可以根據實際情況添加ConfigureServices方法,這兩個方法均在應用程式運行時被調用。Startup 類的 執行順序:構造 -> configureServices ->configure

ConfigureServices方法:主要用於服務配置,比如依賴註入(DI)的配置,使用時該方法必須在Configure方法之前

Configure方法:用於應用程式響應HTTP請求,通過向IApplicationBuilder實例添加中間件組件來配置請求管道

二、自定義路由

在Startup類的Configure方法配置

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            #region 自定義路由配置
            app.UseMvc(routes =>
            {
                // 自定義路由
                routes.MapRoute(
                  name: "default1",
                  template: "api/{controller}/{action}/{id?}",
                  defaults: new { controller = "Values", action = "Index" });
                // 預設路由
                routes.MapRoute(
                   name: "default",
                   template: "{controller}/{action}/{id?}",
                   defaults: new { controller = "Values", action = "Index" });
            });
            #endregion
        }
View Code

三、跨域設置

在Startup類的ConfigureServices方法配置

public void ConfigureServices(IServiceCollection services)
        {
            #region 跨域設置
            services.AddCors(options =>
            {
                options.AddPolicy("AppDomain", builder =>
                {
                    builder.AllowAnyOrigin() // Allow access to any source from the host
                    .AllowAnyMethod()        // Ensures that the policy allows any method
                    .AllowAnyHeader()        // Ensures that the policy allows any header
                    .AllowCredentials();     // Specify the processing of cookie
                });
            });
            #endregion

            services.AddMvc();
        }
View Code

其中“AppDomain”這個名字是自定義的,大家可以根據自己的喜好定義不同的名字,配置完成之後,在控制器上面添加[EnableCors("AppDomain")]特性即可,如果要實現全局的跨域設置,可以在Configure方法裡面配置app.UseCors("AppDomain"),即能實現全局的跨域設置

四、自定義讀取配置文件信息

 這裡是寫的一個公共方法去讀取配置文件appsettings.json

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.IO;

public class JsonConfigurationHelper
    {
        public static T GetAppSettings<T>(string key,string path= "appsettings.json") where T : class, new()
        {
            var currentClassDir = Directory.GetCurrentDirectory();
            IConfiguration config = new ConfigurationBuilder()
                .SetBasePath(currentClassDir)
                .Add(new JsonConfigurationSource { Path = path, Optional = false, ReloadOnChange = true })
                .Build();
            var appconfig = new ServiceCollection()
                .AddOptions()
                .Configure<T>(config.GetSection(key))
                .BuildServiceProvider()
                .GetService<IOptions<T>>()
                .Value;
            return appconfig;
        }
    }
View Code
/// <summary>
        /// 讀取配置文件
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public dynamic JsonConfig()
        {
            var jsonStr = JsonConfigurationHelper.GetAppSettings<ConfigDTO>("config");
            return Ok(jsonStr);
        }

        /// <summary>
        /// 實體類
        /// </summary>
        public class ConfigDTO
        {
            public dynamic name { get; set; }
        }
View Code
{
  "config": {
    "name": "Core.Api"
  }
}
View Code

截圖看效果

五、程式集批量依賴註入

我們都知道依賴註入主要是為了方便解耦,解除應用程式之間的依賴關係,在我看來DI、IOC這兩者差不多是一樣的,DI是從應用程式的角度而IOC是從容器的角度,它們主要是對同一件事情的不同角度的描述。然而,,,,,,當我們項目業務比較多的時候,如果要實現多個業務的註入,通常方法是手動一個個的添加註入,這樣可能有點太繁瑣,所以就想到了利用反射實現批量註入,,,,,,

幫助類

public class RuntimeHelper
    {
        /// <summary>
        /// 獲取項目程式集,排除所有的系統程式集(Microsoft.***、System.***等)、Nuget下載包
        /// </summary>
        /// <returns></returns>
        public static IList<Assembly> GetAllAssemblies()
        {
            var list = new List<Assembly>();
            var deps = DependencyContext.Default;
            var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");//排除所有的系統程式集、Nuget下載包
            foreach (var lib in libs)
            {
                try
                {
                    var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
                    list.Add(assembly);
                }
                catch (Exception)
                {
                    // ignored
                }
            }
            return list;
        }

        public static Assembly GetAssembly(string assemblyName)
        {
            return GetAllAssemblies().FirstOrDefault(assembly => assembly.FullName.Contains(assemblyName));
        }

        public static IList<Type> GetAllTypes()
        {
            var list = new List<Type>();
            foreach (var assembly in GetAllAssemblies())
            {
                var typeInfos = assembly.DefinedTypes;
                foreach (var typeInfo in typeInfos)
                {
                    list.Add(typeInfo.AsType());
                }
            }
            return list;
        }

        public static IList<Type> GetTypesByAssembly(string assemblyName)
        {
            var list = new List<Type>();
            var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
            var typeInfos = assembly.DefinedTypes;
            foreach (var typeInfo in typeInfos)
            {
                list.Add(typeInfo.AsType());
            }
            return list;
        }

        public static Type GetImplementType(string typeName, Type baseInterfaceType)
        {
            return GetAllTypes().FirstOrDefault(t =>
            {
                if (t.Name == typeName &&
                    t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
                {
                    var typeInfo = t.GetTypeInfo();
                    return typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.IsGenericType;
                }
                return false;
            });
        }
    }
View Code
public static class ServiceExtension
    {
        /// <summary>
        /// 用DI批量註入介面程式集中對應的實現類。
        /// </summary>
        /// <param name="service"></param>
        /// <param name="interfaceAssemblyName"></param>
        /// <returns></returns>
        public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName)
        {
            if (service == null)
                throw new ArgumentNullException(nameof(service));
            if (string.IsNullOrEmpty(interfaceAssemblyName))
                throw new ArgumentNullException(nameof(interfaceAssemblyName));

            var assembly = RuntimeHelper.GetAssembly(interfaceAssemblyName);
            if (assembly == null)
            {
                throw new DllNotFoundException($"the dll \"{interfaceAssemblyName}\" not be found");
            }

            //過濾掉非介面及泛型介面
            var types = assembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);

            foreach (var type in types)
            {
                var implementTypeName = type.Name.Substring(1);
                var implementType = RuntimeHelper.GetImplementType(implementTypeName, type);
                if (implementType != null)
                    service.AddSingleton(type, implementType);
            }
            return service;
        }

        /// <summary>
        /// 用DI批量註入介面程式集中對應的實現類。
        /// </summary>
        /// <param name="service"></param>
        /// <param name="interfaceAssemblyName">介面程式集的名稱(不包含文件擴展名)</param>
        /// <param name="implementAssemblyName">實現程式集的名稱(不包含文件擴展名)</param>
        /// <returns></returns>
        public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName, string implementAssemblyName)
        {
            if (service == null)
                throw new ArgumentNullException(nameof(service));
            if (string.IsNullOrEmpty(interfaceAssemblyName))
                throw new ArgumentNullException(nameof(interfaceAssemblyName));
            if (string.IsNullOrEmpty(implementAssemblyName))
                throw new ArgumentNullException(nameof(implementAssemblyName));

            var interfaceAssembly = RuntimeHelper.GetAssembly(interfaceAssemblyName);
            if (interfaceAssembly == null)
            {
                throw new DllNotFoundException($"the dll \"{interfaceAssemblyName}\" not be found");
            }

            var implementAssembly = RuntimeHelper.GetAssembly(implementAssemblyName);
            if (implementAssembly == null)
            {
                throw new DllNotFoundException($"the dll \"{implementAssemblyName}\" not be found");
            }

            //過濾掉非介面及泛型介面
            var types = interfaceAssembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);

            foreach (var type in types)
            {
                //過濾掉抽象類、泛型類以及非class
                var implementType = implementAssembly.DefinedTypes
                    .FirstOrDefault(t => t.IsClass && !t.IsAbstract && !t.IsGenericType &&
                                         t.GetInterfaces().Any(b => b.Name == type.Name));
                if (implementType != null)
                {
                    service.AddSingleton(type, implementType.AsType());
                }
            }

            return service;
        }
    }
View Code

 在Startupl類的ConfigureServices方法中添加

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region 程式集批量依賴註入
            services.RegisterAssembly("Core.BLL");
            #endregion

            services.AddMvc();
        }
View Code

調用(Ps:Core.BLL這個類庫裡面分別有一個介面IAccountService和一個類AccountService,AccountService類去繼承介面IAccountService並實現介面裡面的方法)

public interface IAccountService
    {
        int GetLst();
    }

public class AccountService: IAccountService
    {
        public int GetLst()
        {
            return 1;
        }
    }
View Code
public class ValuesController : Controller
    {
        private readonly IAccountService _accountService;
        public ValuesController(IAccountService accountService)
        {
            _accountService = accountService;
        }

        [HttpGet]
        public dynamic GetAccount()
        {
            var result = this._accountService.GetLst();
            return Ok();
        }
}
View Code

 六、使用NLog寫入文件日誌

新建配置文件命名為Nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    
<!--寫入文件-->
    <target
     xsi:type="File"
     name="DebugFile"
     fileName="Logs\Debug\${shortdate}.log"
     layout="日誌時間:${longdate}${newline}日誌來源:${callsite}${newline}日誌級別:${uppercase:${level}}${newline}消息內容:${message}${newline}異常信息:${exception}${newline}==============================================================${newline}" >
    </target>
    <target 
      xsi:type="File" 
      name="InfoFile" 
      fileName="Logs\Info\${shortdate}.log"
      layout="日誌時間:${longdate}${newline}日誌來源:${callsite}${newline}日誌級別:${uppercase:${level}}${newline}消息內容:${message}${newline}異常信息:${exception}${newline}==============================================================${newline}" >
    </target>
    <target 
      xsi:type="File" 
      name="ErrorFile" 
      fileName="Logs\Error\${shortdate}.log"
      layout="日誌時間:${longdate}${newline}日誌來源:${callsite}${newline}日誌級別:${uppercase:${level}}${newline}消息內容:${message}${newline}異常信息:${exception}${newline}==============================================================${newline}" >
    </target>    

  <rules>
    <logger name="FileLogger" minlevel="Debug" maxLevel="Debug" writeTo="DebugFile" />
    <logger name="FileLogger" minlevel="Info" maxLevel="Info" writeTo="InfoFile" />
    <logger name="FileLogger" minlevel="Error" maxLevel="Error" writeTo="ErrorFile" />
  </rules>
</nlog>
View Code

 在Startup類Configure方法中添加配置

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            #region NLog配置
            loggerFactory.AddNLog(); // 添加NLog
            loggerFactory.ConfigureNLog($"{Directory.GetCurrentDirectory()}\\Nlog.config"); // 添加Nlog.config配置文件
            loggerFactory.AddDebug();
            #endregion
        }
View Code

寫入日誌到文件

public class ValuesController : Controller
    {
        private readonly Logger _logger;
       
        public ValuesController()
        {
            _logger = LogManager.GetLogger("FileLogger");
        }

        /// <summary>
        /// 寫入文件日誌
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public dynamic WriteLogToFile()
        {
            _logger.Info("寫入Info文件");
            _logger.Debug("寫入Debug文件");
            _logger.Error("寫入Error文件");
            return Ok();
        }
}
View Code

七、使用NLog寫入資料庫日誌

添加依賴項:Microsoft.Extensions.LoggingNLog.Extensions.Logging

新建配置文件命名為Nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>

    <!--寫入資料庫-->
    <target xsi:type="Database" name="Database"
            connectionString="Data Source=.;Initial Catalog=MyDb;Persist Security Info=True;User ID=sa;Password=123456"
            commandText="insert into NLog_Log([CreateOn],[Origin],[LogLevel], [Message], [Exception],[StackTrace],[Desc]) values (getdate(), @origin, @logLevel, @message,@exception, @stackTrace,@desc)">
      
      <!--日誌來源-->
      <parameter name="@origin" layout="${callsite}"/>
      <!--日誌等級-->
      <parameter name="@logLevel" layout="${level}"/>
      <!--日誌消息-->
      <parameter name="@message" layout="${message}"/>
      <!--異常信息-->
      <parameter name="@exception" layout="${exception}" />
      <!--堆棧信息-->
      <parameter name="@stackTrace" layout="${stacktrace}"/>
      <!--自定義消息內容-->
      <parameter name="@desc" layout="${event-context:item=Desc}"/>
    </target>
  </targets>

  <rules>
    <logger name="DbLogger" levels="Trace,Debug,Info,Error"  writeTo="Database"/>
  </rules>
</nlog>
View Code

同第六項代碼一樣,也是在Configure方法設置,寫入日誌到資料庫

/// <summary>
        /// 將日誌寫入資料庫
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public dynamic WriteLogToDb()
        {
            Logger _dblogger = LogManager.GetLogger("DbLogger");
            LogEventInfo ei = new LogEventInfo();
            ei.Properties["Desc"] = "我是自定義消息";
            _dblogger.Info(ei);
            _dblogger.Debug(ei);
            _dblogger.Trace(ei);
            return Ok();
        }
View Code
USE [MyDb]
GO

/****** Object:  Table [dbo].[NLog_Log]    Script Date: 08/09/2018 17:13:20 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[NLog_Log](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Origin] [nvarchar](500) NULL,
    [LogLevel] [nvarchar](500) NULL,
    [Message] [nvarchar](500) NULL,
    [Desc] [nvarchar](500) NULL,
    [Exception] [nvarchar](500) NULL,
    [StackTrace] [nvarchar](500) NULL,
    [CreateOn] [datetime] NULL
) ON [PRIMARY]

GO
View Code

八、Nlog標簽解讀

NLog的使用方式基本上和其它的Log庫差不多,用於輸出日誌的級別包括:Trace,Debug,Info,Warn,Error,Fatal

<nlog>標簽 autoReload 修改配置文件後是否允許自動載入無須重啟程式 throwExceptions 內部日誌系統拋出異常 internalLogLevel 可選Trace|Debug|Info|Warn|Error|Fatal決定內部日誌的級別 Off 關閉 internalLogFile 把內部的調試和異常信息都寫入指定文件里 建議throwExceptions的值設為“false”,這樣由於日誌引發的問題不至於導致應用程式的崩潰。 <targets>標簽 <target />區域定義了日誌的目標或者說輸出 ,,在這裡可以按需設置文件名稱和格式,輸出方式。 name:自定義該target的名字,可供rule規則里使用 type: 定義類型,官方提供的可選類型有: Chainsaw|ColoredConsole |Console |Database|Debug|Debugger|EventLog|File|LogReceiverService|Mail|Memory|MethodCall|Network |NLogViewer|Null |OutputDebugString|PerfCounter|Trace|WebService 不過常用的還是 File \Database \Colored Console\ Mail

layouts 用來規定佈局樣式,語法“${屬性}”,可以把上下文信息插入到日誌中,更多佈局渲染器可參考https://github.com/nlog/NLog/wiki/Layout%20Renderers

<rules>標簽

各種規則配置在logger里 name - 記錄者的名字 minlevel - 最低級別 maxlevel - 最高級別 level - 單一日誌級別 levels - 一系列日誌級別,由逗號分隔。 writeTo - 規則匹配時日誌應該被寫入的一系列目標,由逗號分隔。      

 目前只整理了這些,後續會持續更新到這裡面,如有不合理的地方,請大家加以斧正,,,希望能和大家共同學習、共同進步,,

 

 

權責申明

作者:SportSky 出處: http://www.cnblogs.com/sportsky/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。如果覺得還有幫助的話,可以點一下右下角的【推薦】,希望能夠持續的為大家帶來好的技術文章!想跟我一起進步麽?那就【關註】我吧。

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 資料庫的配置 1 django預設支持sqlite,mysql, oracle,postgresql資料庫。 <1> sqlite django預設使用sqlite的資料庫,預設自帶sqlite的資料庫驅動 , 引擎名稱:django.db.backends.sqlite3 <2> mysql 引擎 ...
  • RocketMQ是一款分散式、隊列模型的消息中間件,具有以下特點: 能夠保證嚴格的消息順序 提供豐富的消息拉取模式 高效的訂閱者水平擴展能力 實時的消息訂閱機制 億級消息堆積能力 RocketMQ網路部署特 (1)NameServer是一個幾乎無狀態的節點,可集群部署,節點之間無任何信息同步 (2) ...
  • 註:本面試題來源於網路,轉載自http://www.cnblogs.com/goodhacker/p/3366618.html。 1. (1)python下多線程的限制以及多進程中傳遞參數的方式 python多線程有個全局解釋器鎖(global interpreter lock),這個鎖的意思是任一 ...
  • Java代碼自動部署 【 ①Java代碼自動部署-總結簡介】 代碼部署是每一個軟體開發項目組都會有的一個流程,也是從開發環節到發佈功能必不可少的環節。對於Java開發者來說,Java代碼的發佈部署也是經常需要做的一件事,特別是互聯網公司。代碼的發佈上線關係到保證生產環境能夠正常啟動及功能是否能正常運 ...
  • class HelloA { public HelloA() { System.out.println("HelloA"); } { System.out.println("I'm A class"); } static { System.out.println("static A"); } } p... ...
  • C++智能指針,指針容器原理及簡單實現(auto_ptr,scoped_ptr,ptr_vector). [TOC] 前言 最近再寫一個muduo的非同步日誌接觸了很多智能指針,但是又不打算用boost庫,只好模一個來用用了. 智能指針本身是一個對象,它在棧上創建,構造的時候分配堆上資源,析構的時候釋 ...
  • 1.函數的動態參數: 1.*args 位置參數動態傳參 結果:1 2 3 4 5 順序:位置參數=>*args=>預設值參數 *在這裡表示接收位置參數的動態傳參,接收到的是元組 結果為:1 2 3 4 5 將第一個值賦值給a,後面的值都給b 2.**kwargs 關鍵字參數動態傳參 結果為: 1 { ...
  • 不知什麼時候 ,出現了這樣的一個奇怪問題,簡單的httpClient.GetAsync("xxxx")居然報錯了。 一、問題描述 把原來的程式從2.0升級到2.1,突然發現原本正常運行的httpClient.GetAsync("xxxx")居然不工作了。 為了排除項目中其他引用的干擾,新建了一個乾凈 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...