[asp.net mvc 奇淫巧技] 03 - 枚舉特性擴展解決枚舉命名問題和支持HtmlHelper

来源:http://www.cnblogs.com/emrys5/archive/2017/05/31/Enum-rename-htmlhelper.html
-Advertisement-
Play Games

一、需求 我們在開發中經常會遇到一些枚舉,而且這些枚舉類型可能會在表單中的下拉中,或者單選按鈕中會用到等。 這樣用是沒問題的,但是用過的人都知道一個問題,就是枚舉的命名問題,當然有很多人枚舉直接中文命名,我是不推薦這種命名規則,因為實在不夠友好。 那有沒有可以不用中文命名,而且可以顯示中文的方法呢。 ...


一、需求

我們在開發中經常會遇到一些枚舉,而且這些枚舉類型可能會在表單中的下拉中,或者單選按鈕中會用到等。

 

這樣用是沒問題的,但是用過的人都知道一個問題,就是枚舉的命名問題,當然有很多人枚舉直接中文命名,我是不推薦這種命名規則,因為實在不夠友好。

那有沒有可以不用中文命名,而且可以顯示中文的方法呢。答案是肯定的。

 

二、特性解決枚舉命名問題

那就是用特性解決命名問題,這樣的話既可以枚舉用英文命名,顯示又可以是中文的,豈不兩全其美。

/// <summary>
    /// 性別
    /// </summary>
    public enum Gender
    {
        /// <summary>
        /// 女性
        /// </summary>
        [Description("女性")]
        Female = 1,

        /// <summary>
        /// 男性
        /// </summary>
        [Description("男性")]
        Male = 2,

        /// <summary>
        /// 未知
        /// </summary>
        [Description("未知")]
        Unknown = 3,

        /// <summary>
        /// 人妖
        /// </summary>
        [Description("人妖")]
        Demon = 4
    }

 

1、新建枚舉的特性類

首先我們需要新建枚舉的特性,用來描述枚舉,這樣既可以解決枚舉的命名問題,又可以解決枚舉的顯示問題。

我們在下拉框或者單選按鈕上顯示各個枚舉項,可能會出現一些排序問題,所以在枚舉的特性上不僅有顯示的名稱還有排序。

  /// <summary>
    /// 枚舉特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    public class DescriptionAttribute : Attribute
    {
        /// <summary>
        /// 排序
        /// </summary>
        public int Order { get; set; }

        /// <summary>
        /// 名稱
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 顯示自定義描述名稱
        /// </summary>
        /// <param name="name">名稱</param>
        public DescriptionAttribute(string name)
        {
            Name = name;
        }

        /// <summary>
        /// 顯示自定義名稱
        /// </summary>
        /// <param name="name">名稱</param>
        /// <param name="order">排序</param>
        public DescriptionAttribute(string name, int order)
        {
            Name = name;
            Order = order;
        }

    }

 新建好枚舉的特性類以後,我們就可以在枚舉的欄位上添加自定義的特性Description

/// <summary>
/// 性別
/// </summary> 
public enum Gender
{
    /// <summary>
    /// 女性
    /// </summary>
    [Description("女性", 2)]
    Female = 1,

    /// <summary>
    /// 男性
    /// </summary>
    [Description("男性", 1)]
    Male = 2,

    /// <summary>
    /// 未知
    /// </summary>
    [Description("未知", 3)]
    Unknown = 3,

    /// <summary>
    /// 人妖
    /// </summary>
    [Description("人妖", 4)]
    Demon = 4
}

特性第一個參數為名稱,第二個為排序(int 類型,正序),這就是就是我們新建枚舉時在需要顯示和枚舉名稱不一樣的枚舉欄位上添加即可。這個Gender枚舉,在後面文章中會一直用到(Gender)。

 

2、新建枚舉擴展方法獲取枚舉特性的描述

我們前面的工作已經把特性和在枚舉上添加特性已經完成了,後面我們需要的就是要獲取我們添加的描述和排序。

/// <summary>
/// 枚舉幫助類
/// </summary>
public static class EnumTools
{

    /// <summary>
    /// 獲取當前枚舉值的描述
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static string GetDescription(this Enum value)
    {
        int order;
        return GetDescription(value, out order);
    }

    /// <summary>
    /// 獲取當前枚舉值的描述和排序
    /// </summary>
    /// <param name="value"></param>
    /// <param name="order"></param>
    /// <returns></returns>
    public static string GetDescription(this Enum value, out int order)
    {
        string description = string.Empty;

        Type type = value.GetType();

        // 獲取枚舉
        FieldInfo fieldInfo = type.GetField(value.ToString());

        // 獲取枚舉自定義的特性DescriptionAttribute
        object[] attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
        DescriptionAttribute attr = (DescriptionAttribute)attrs.FirstOrDefault(a => a is DescriptionAttribute);

        order = 0;
        description = fieldInfo.Name;

        if (attr != null)
        {
            order = attr.Order;
            description = attr.Name;
        }
        return description;

    }

        
}

 

3、獲取枚舉描述和排序

至此:我們可以很容易獲取到枚舉添加的特性描述和排序。

var des = Gender.Male.GetDescription();
// des = “男性”

var name = Gender.Male.ToString();
// name= "Male"

var key = (int)Gender.Male;
// key = 2

int order;
var des1 = Gender.Female.GetDescription(out order);
// des1 = “女性”, order= 2

這樣我們就很好的解決了枚舉命名問題, 可以很容易的獲取到枚舉的描述信息,也就是要顯示的信息。但是我們需要的是一次性可以查詢全部的枚舉信息,以便我們進行顯示。

 

三、獲取所有枚舉的描述和值,以便迴圈使用

我們已經可以很容易的獲取到枚舉的值,名稱和描述了,所以後面的就很簡單了。

/// <summary>
/// 枚舉幫助類
/// </summary>
public static class EnumTools
{ 

    /// <summary>
    /// 獲取當前枚舉的所有描述
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static List<KeyValuePair<int, string>> GetAll<T>()
    {
        return GetAll(typeof(T));
    }

    /// <summary>
    /// 獲取所有的枚舉描述和值
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static List<KeyValuePair<int, string>> GetAll(Type type)
    {

        List<EnumToolsModel> list = new List<EnumToolsModel>();

        // 迴圈枚舉獲取所有的Fields
        foreach (var field in type.GetFields())
        {
            // 如果是枚舉類型
            if (field.FieldType.IsEnum)
            {
                object tmp = field.GetValue(null);
                Enum enumValue = (Enum)tmp;
                int intValue = Convert.ToInt32(enumValue);
                int order;
                string showName = enumValue.GetDescription(out order); // 獲取描述和排序
                list.Add(new EnumToolsModel { Key = intValue, Name = showName, Order = order });
            }
        }

        // 排序並轉成KeyValue返回
        return list.OrderBy(i => i.Order).Select(i => new KeyValuePair<int, string>(i.Key, i.Name)).ToList();

    }
}

調用:這樣我們就很容易的獲取枚舉所有欄位的描述,如我們需要在cshtml中調用

<select class="form-control">
    @{ var genders = EnumTools.GetAll<Gender>();}   // 或者EnumTools.GetAll<>(Typeof(Gender))
    @foreach (var item in genders)
    {
        <option value="@item.Key"> 
            @item.Value
        </option>
    }
</select>

生成的html為:

<select class="form-control">
    <option value="2">男性</option>
    <option value="1">女性</option>
    <option value="3">未知</option>
    <option value="4">人妖</option>
</select>

 

 這樣我們就已順利的解決了枚舉的命名以及排序顯示等問題。

 

四、枚舉特性擴展至HtmlHelper

我們已經解決了枚舉的命名以及排序顯示問題,但是我們想做的更好,比如每次都要寫一個foreach獲取所有的枚舉然後在判斷預設值和哪個相等,迴圈遍歷,周而複始,重覆造輪子,bad code。所以我們要進行封裝,封裝成與 @Html.DropDownList一樣好用的HtmlHelper擴展。

/// <summary>
/// 枚舉下拉
/// </summary>
/// <typeparam name="T">枚舉類型</typeparam>
/// <param name="html"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, object htmlAttributes = null)
{
    return html.EnumToolsSelect(typeof(T), int.MaxValue, htmlAttributes);
}


/// <summary>
/// 枚舉下拉
/// </summary>
/// <typeparam name="T">枚舉類型</typeparam>
/// <param name="html"></param>
/// <param name="selectedValue">選擇項</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, int selectedValue, object htmlAttributes = null)
{
    return html.EnumToolsSelect(typeof(T), selectedValue, htmlAttributes);
}

/// <summary>
/// 枚舉下拉
/// </summary>
/// <typeparam name="T">枚舉類型</typeparam>
/// <param name="html"></param>
/// <param name="selectedValue">選擇項</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, T selectedValue, object htmlAttributes = null)
{
    return html.EnumToolsSelect(typeof(T), Convert.ToInt32(selectedValue), htmlAttributes);
}



/// <summary>
/// 枚舉下拉
/// </summary>
/// <param name="html"></param>
/// <param name="enumType">枚舉類型</param>
/// <param name="selectedValue">選擇項</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelect(this HtmlHelper html, Type enumType, int selectedValue, object htmlAttributes = null)
{
    // 創建標簽
    TagBuilder tag = new TagBuilder("select");

    // 添加自定義標簽
    if (htmlAttributes != null)
    {
        RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        tag.MergeAttributes(htmlAttr);
    }
    // 創建option集合
    StringBuilder options = new StringBuilder();
    foreach (var item in GetAll(enumType))
    {
        // 創建option
        TagBuilder option = new TagBuilder("option");

        // 添加值
        option.MergeAttribute("value", item.Key.ToString());

        // 設置選擇項
        if (item.Key == selectedValue)
        {
            option.MergeAttribute("selected", "selected");
        }

        // 設置option
        option.SetInnerText(item.Value);
        options.Append(option.ToString());
    }
    tag.InnerHtml = options.ToString();

    // 返回MVCHtmlString
    return MvcHtmlString.Create(tag.ToString());

}

 

 然後調用

@(Html.EnumToolsSelect<Gender>())
@(Html.EnumToolsSelect<Gender>(Gender.Unknown))
@(Html.EnumToolsSelect<Gender>(1))
@(Html.EnumToolsSelect<Gender>(Gender.Female, new { @class = "form-control" }))
@(Html.EnumToolsSelect(typeof(Gender), 1)

這樣就可以生成你所需要的下拉框的html,一行代碼就可以解決複雜的枚舉下拉。

你以為就這樣結束了嗎,很明顯沒有,因為不是我風格,我的風格是繼續封裝。

 

五、枚舉特性擴展至HtmlHelper Model

這個可能有很多不會陌生,因為很多HtmlHelper都有一個For結尾的,如@Html.DropDownListFor等等,那我們也要有For結尾的,要不然都跟不上潮流了。

關於For的一些擴展和沒有For的擴展的區別,簡單來說帶For就是和Model一起用的,如:@Html.TextBoxFor(i => i.Name)

這樣就可以更加一步的封裝,如Id,name,model的Name值以及驗證等等。

話不多說,直接代碼

/// <summary>
/// 下拉枚舉
/// </summary>
/// <typeparam name="TModel">Model</typeparam>
/// <typeparam name="TProperty">屬性</typeparam>
/// <param name="htmlHelper"></param>
/// <param name="expression"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString EnumToolsSelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
    // 獲取元數據meta
    ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

    Type enumType = modelMetadata.ModelType;

    // 設置id name的屬性值
    var rvd = new RouteValueDictionary
    {
        { "id", modelMetadata.PropertyName },
        { "name", modelMetadata.PropertyName }
    };

    // 添加自定義屬性
    if (htmlAttributes != null)
    {
        RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        foreach (var item in htmlAttr)
        {
            rvd.Add(item.Key, item.Value);
        }
    }

    // 獲取驗證信息
    IDictionary<string, object> validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(modelMetadata.PropertyName, modelMetadata);

    // 添加至自定義屬性
    if (validationAttributes != null)
    {
        foreach (var item in validationAttributes)
        {
            rvd.Add(item.Key, item.Value);
        }
    }
    return htmlHelper.EnumToolsSelect(enumType, Convert.ToInt32(modelMetadata.Model), rvd);
}

關於使用:

首先我們需要返回view時需要返回Model

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new Person { Age = 1, Name = "Emrys", Gender = Gender.Male });
    }

} 

public class Person
{
    public string Name { get; set; } 
    public int Age { get; set; }  
    public Gender Gender { get; set; } 
}

cshtm調用

@Html.EnumToolsSelectFor(i => i.Gender)

生成html代碼

<select data-val="true" data-val-required="Gender 欄位是必需的。" id="Gender" name="Gender">
    <option selected="selected" value="2">男性</option>
    <option value="1">女性</option>
    <option value="3">未知</option>
    <option value="4">人妖</option>
</select>

 

六、全部枚舉特性和HtmlHelper代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace Emrys.EnumTools
{

    /// <summary>
    /// 枚舉幫助類
    /// </summary>
    public static class EnumTools
    {

        /// <summary>
        /// 獲取當前枚舉值的描述
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum value)
        {
            int order;
            return GetDescription(value, out order);
        }

        /// <summary>
        /// 獲取當前枚舉值的描述和排序
        /// </summary>
        /// <param name="value"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum value, out int order)
        {
            string description = string.Empty;

            Type type = value.GetType();

            // 獲取枚舉
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // 獲取枚舉自定義的特性DescriptionAttribute
            object[] attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            DescriptionAttribute attr = (DescriptionAttribute)attrs.FirstOrDefault(a => a is DescriptionAttribute);

            order = 0;
            description = fieldInfo.Name;

            if (attr != null)
            {
                order = attr.Order;
                description = attr.Name;
            }
            return description;

        }

        /// <summary>
        /// 獲取當前枚舉的所有描述
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static List<KeyValuePair<int, string>> GetAll<T>()
        {
            return GetAll(typeof(T));
        }

        /// <summary>
        /// 獲取所有的枚舉描述和值
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static List<KeyValuePair<int, string>> GetAll(Type type)
        {

            List<EnumToolsModel> list = new List<EnumToolsModel>();

            // 迴圈枚舉獲取所有的Fields
            foreach (var field in type.GetFields())
            {
                // 如果是枚舉類型
                if (field.FieldType.IsEnum)
                {
                    object tmp = field.GetValue(null);
                    Enum enumValue = (Enum)tmp;
                    int intValue = Convert.ToInt32(enumValue);
                    int order;
                    string showName = enumValue.GetDescription(out order); // 獲取描述和排序
                    list.Add(new EnumToolsModel { Key = intValue, Name = showName, Order = order });
                }
            }

            // 排序並轉成KeyValue返回
            return list.OrderBy(i => i.Order).Select(i => new KeyValuePair<int, string>(i.Key, i.Name)).ToList();

        }


        /// <summary>
        /// 枚舉下拉
        /// </summary>
        /// <typeparam name="T">枚舉類型</typeparam>
        /// <param name="html"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, object htmlAttributes = null)
        {
            return html.EnumToolsSelect(typeof(T), int.MaxValue, htmlAttributes);
        }


        /// <summary>
        /// 枚舉下拉
        /// </summary>
        /// <typeparam name="T">枚舉類型</typeparam>
        /// <param name="html"></param>
        /// <param name="selectedValue">選擇項</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, int selectedValue, object htmlAttributes = null)
        {
            return html.EnumToolsSelect(typeof(T), selectedValue, htmlAttributes);
        }

        /// <summary>
        /// 枚舉下拉
        /// </summary>
        /// <typeparam name="T">枚舉類型</typeparam>
        /// <param name="html"></param>
        /// <param name="selectedValue">選擇項</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect<T>(this HtmlHelper html, T selectedValue, object htmlAttributes = null)
        {
            return html.EnumToolsSelect(typeof(T), Convert.ToInt32(selectedValue), htmlAttributes);
        }



        /// <summary>
        /// 枚舉下拉
        /// </summary>
        /// <param name="html"></param>
        /// <param name="enumType">枚舉類型</param>
        /// <param name="selectedValue">選擇項</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelect(this HtmlHelper html, Type enumType, int selectedValue, object htmlAttributes = null)
        {
            // 創建標簽
            TagBuilder tag = new TagBuilder("select");

            // 添加自定義標簽
            if (htmlAttributes != null)
            {
                RouteValueDictionary htmlAttr = htmlAttributes as RouteValueDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                tag.MergeAttributes(htmlAttr);
            }
            // 創建option集合
            StringBuilder options = new StringBuilder();
            foreach (var item in GetAll(enumType))
            {
                // 創建option
                TagBuilder option = new TagBuilder("option");

                // 添加值
                option.MergeAttribute("value", item.Key.ToString());

                // 設置選擇項
                if (item.Key == selectedValue)
                {
                    option.MergeAttribute("selected", "selected");
                }

                // 設置option
                option.SetInnerText(item.Value);
                options.Append(option.ToString());
            }
            tag.InnerHtml = options.ToString();

            // 返回MVCHtmlString
            return MvcHtmlString.Create(tag.ToString());

        }
        /// <summary>
        /// 下拉枚舉
        /// </summary>
        /// <typeparam name="TModel">Model</typeparam>
        /// <typeparam name="TProperty">屬性</typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString EnumToolsSelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlH

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

-Advertisement-
Play Games
更多相關文章
  • var lst = new List<ModelTest>(); lst.Add(new ModelTest() { Code = "1", Name = "一" }); lst.Add(new ModelTest() { Code = "2", Name = "二" }); lst.Add(new ...
  • 最近項目上要用到跑馬燈的效果,和網上不太相同的是,網上大部分都是連續的,而我們要求的是不連續的。 也就是是,界面上就展示4項(展示項數可變),如果有7項要展示的話,則不斷的在4個空格裡左跳,當然,銜接上效果不是很好看。 然後,需要支持點擊以後進行移除掉不再顯示的內容。 效果如下: 思路大致如下: 1 ...
  • jlink 如何 離開 keil、IAR 監控變數呢? 目前 jlink的 api 可以做到,自己可以用C# 做一個 上位機,監控RAM裡面的變數。而不用打開keil 調試。還可以 刷寫 flash,可以用在產品量產的刷寫上。 SEGGER 的 jlink sdk並不是免費的,在調試API 過程中, ...
  • 最近在做一個資源對接項目,對方的介面中要求我們把文件的md5值傳過去,搜了一下找到這個方法,記錄之。 ...
  • 一、目標樣式 我們要實現上圖中的效果,需要如下的操作: 二、資源分享代碼 註:Client.Share.SendURL("URL地址") 分享文本:Client.Share.SendText("文本") 分享圖片:Client.Share.SendImage("圖片") 分享截屏:Client.Sh ...
  • 在angularjs中,想在文本框中,驗證用戶輸入的字元串是否為日期時間。剛開始時,Insus.NET想到的是正則,這隻是驗證到日期與時間的格式是否正確而已,而對於2月最後一天或是30或是31號,還是無能為力。 因此,Insus.NET想使用angularjs的自定義指令來驗證解決此問題。在ASP. ...
  • 1,這是因為用線程式控制制子窗體,刷新數據的時候會影響主窗體,因為主次窗體是以 Main man = new Main(); man.ShowDialog();形式存在 2,解決辦法: 新建公共類,Bool屬性並賦值,在需要調用刷新數據方法地方通過給刷新數據的方法套一個事件,在通過Timer 控制項結束當 ...
  • 接上一篇,眾所周知一個網站的用戶登錄是非常重要,一站式的登錄(SSO)也成了大家討論的熱點。微軟在這個Demo中,把登錄單獨拉了出來,形成了一個Service,用戶的註冊、登錄、找回密碼等都在其中進行。這套service是基於IdentityServer4開發的, 它是一套基於 .Net Core的... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...