【MVC 4】3.MVC 基本工具(創建示例項目、使用 Ninject)

来源:http://www.cnblogs.com/yc-755909659/archive/2016/03/08/5220615.html
-Advertisement-
Play Games

本次將考察三類工具,它們是每一位 MVC 程式員工具庫的成員:DI容器、單元測試框架和模仿工具。 1.創建一個示例項目 創建一個空 ASP.NET MVC 4 項目 EssentiaTools 。 1.1 創建模型類 在 Models 文件夾下新建 Product.cs 類文件 using Syst


本次將考察三類工具,它們是每一位 MVC 程式員工具庫的成員:DI容器、單元測試框架和模仿工具。

1.創建一個示例項目

創建一個空 ASP.NET MVC 4 項目 EssentiaTools 。

 

1.1 創建模型類

在 Models 文件夾下新建 Product.cs 類文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string Catogory { get; set; }
    }
}

另外,再新建 LinqValueCalculator.cs 類文件,它將計算 Product 對象集合的總價。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public class LinqValueCalculator : IValueCalculator
    {
        public decimal ValueProducts(IEnumerable<Product> products)
        {
            return products.Sum(p=>p.Price);            
        }
    }
}

 

接著,再新建一個模型類 ShoppingCart ,它表示了 Product 對象的集合,並且使用 LinqValueCalculator 來確定總價。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public class ShoppingCart
    {
        private IValueCalculator calc;

        public ShoppingCart(IValueCalculator calcParam) {
            calc = calcParam;
        }

        public IEnumerable<Product> Products { get; set; }

        public decimal CalcularProductTotal() {
            return calc.ValueProducts(Products);
        }
    }
}

 

1.2 添加控制器

在 Controller 文件夾下新建控制器文件 HomeController.cs

using EssentiaTools.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EssentiaTools.Controllers
{
    public class HomeController : Controller
    {
        private Product[] products = { 
        new Product{Name="Kayak",Catogory="Watersports",Price=275M}, 
        new Product{Name="Lifejacket",Catogory="Watersports",Price=48.95M}, 
        new Product{Name="Soccer ball",Catogory="Soccer",Price=19.50M},
        new Product{Name="Corner flag",Catogory="Soccer",Price=34.95M}
        };
        public ActionResult Index()
        {
            LinqValueCalculator calc = new LinqValueCalculator();
            ShoppingCart cart = new ShoppingCart(calc) { Products = products };
            decimal totalValue = cart.CalcularProductTotal();
            return View(totalValue);
        }
    }
}

 

1.3 添加視圖

根據動作方法,創建對應的視圖文件 Index.cshtml

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Value</title>
</head>
<body>
    <div>
        Total value is $@Model
    </div>
</body>
</html>

運行程式,效果如下:

2.使用 Ninject

Ninject 是人們所喜歡的DI容器,它簡單、優雅且易用。

DI容器,其思想是對MVC 應用程式中的組件進行解耦,這是通過介面與DI 相結合來實現的。

 

2.1 理解問題

在前面示例中,構造了一個能夠用 DI 解決的問題。該項目依賴於一些緊耦合的類:ShoppingCart 類與 LinqValueCalculator 類是緊耦合的,而 HomeController 類與 ShoppingCart 和 LinqValueCalculator 都是緊耦合的。這意味著,如果想替換 LinqValueCalculator 類,就必須在與它有緊耦合關係的類中找出對它的引用,併進行修改。對這種簡單的項目來說,這不是問題。但是,在一個實際項目中,這可能會成為一個乏味且易錯的過程,尤其是,如果想在兩個不同的計算器實現之間進行切換,而不只是用另一個類來替換另一個類的情況下。

 

運用介面

通過使用 C# 介面,從計算器的實現中抽象出其功能定義,可以解決部分問題。在 Models 文件夾下添加介面文件 IValueCalculator:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EssentiaTools.Models
{
    public interface IValueCalculator
    {
        decimal ValueProducts(IEnumerable<Product> products);
    }
}

然後,可以在 LinqValueCalcular 類中實現這一介面:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public class LinqValueCalculator: IValueCalculator
    {
        public decimal ValueProducts(IEnumerable<Product> products)
        {
            return products.Sum(p=>p.Price);            
        }
    }
}

該介面能夠打斷 ShoppingCart 與 LinqValueCalcular 類之間的緊耦合關係,將該介面運用於 ShoppingCart 類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public class ShoppingCart
    {
        private IValueCalculator calc;

        public ShoppingCart(IValueCalculator calcParam) {
            calc = calcParam;
        }

        public IEnumerable<Product> Products { get; set; }

        public decimal CalcularProductTotal() {
            return calc.ValueProducts(Products);
        }
    }
}

 在上述過程中,已經解除了 ShoppingCart 與 LinqValueCalculator 之間的耦合,因為在使用 ShoppingCart時,只要為其構造器傳遞一個 IValueCalculator 介面對象就行了。於是,SHoppingCart 類與 IValueCalculator 的實現類之間不再有直接聯繫,但是C# 要求在介面實例化時需要指定其實現類。這很自然,因為它需要知道用戶想用的是哪一個實現類。這意味著,Home 控制器在創建 LinqValueCalculatoe 對象時仍有問題。

...
public ActionResult Index(){
            IValueCalculator calc = new LinqValueCalculator();
            ShoppingCart cart = new ShoppingCart(calc) { Products = products };
            decimal totalValue = cart.CalcularProductTotal();
            return View(totalValue);
}
...

使用 Ninject 的目的就是要解決這一問題,用以對 IValueCalculator 介面的實現進行實例化,但所需的實現細節卻又不是 Home 控制器代碼的一部分(即,通過 Ninject,可以去掉 Home 控制器中的這行黑體語句所示的代碼,這項工作由 Ninject 完成,這樣便去掉了 Home 控制器與總價計算器 LinqValueCalculator 之間的耦合)

 

2.2 將 Ninject 添加到 Visual Studio 項目

通過工具菜單找到 “管理解決方案的 NuGet 程式包”選項,添加 Ninject:

 

或者直接右擊項目名,找到 “管理 NuGet 程式包” 選項也可以添加 Ninject

 

2.3 Ninject 初步

為了得到 Ninject 的基本功能,要做的工作有三個步驟。給 Index 動作方法添加基本的 Ninject 功能代碼如下:

 

using EssentiaTools.Models;
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EssentiaTools.Controllers
{
    public class HomeController : Controller
    {
        private Product[] products = { 
        new Product{Name="Kayak",Catogory="Watersports",Price=275M}, 
        new Product{Name="Lifejacket",Catogory="Watersports",Price=48.95M}, 
        new Product{Name="Soccer ball",Catogory="Soccer",Price=19.50M},
        new Product{Name="Corner flag",Catogory="Soccer",Price=34.95M}
        };
        public ActionResult Index()
        {
            //第一步,準備使用 Ninject,創建一個 Ninject 內核的實例。
            //這是一個對象,它與Ninject 進行通信,並請求介面的實現。
            IKernel ninjectKernel = new StandardKernel();

            //第二步,建立應用程式中的介面和想要使用的實現類之間的關係
            //Ninject 使用C# 的類型參數創建了一種關係:
            //將想要使用的介面為 Bind 方法的類型參數,併在其返回的結果上調用To 方法。
            //將希望實例化的實現類設置為 To 方法的類型參數。 
            //該語句告訴 Ninject:
            //當要求它實現 IValueCalculator 介面時,應當創建 LinqValueCalculator 類的新實例,以便對請求進行服務。
            ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();

            //第三步,實際使用 Ninject,通過其 Get 方法完成這一工作。
            //Get 方法所使用的類型參數告訴 Ninject ,用戶感興趣的是哪一個介面,
            //而該方法的結果是剛纔用 To 方法指定的實現類型的一個實例。
            IValueCalculator calc = ninjectKernel.Get<IValueCalculator>();

ShoppingCart cart
= new ShoppingCart(calc) { Products = products }; decimal totalValue = cart.CalcularProductTotal(); return View(totalValue); } } }

 

 

 

2.4 建立MVC 依賴性註入

上面Index 動作方法所展示的三個步驟的結果是:在 Ninject 中已經建立了一些相關的知識,即使用哪一個實現類來完成對 IValueCalculator 介面的請求。但是,應用程式未做任何改進,因為 Home 控制器與 LinqValueCalculator 類仍然是緊耦合的。

 

創建依賴解析器

示例要做的第一個修改時創建一個自定義的依賴解析器。MVC 框架需要使用依賴解析器來創建類的實例,以便對請求進行服務。通過創建自定義解析器,保證每當要創建一個對象時,便使用 Ninject 。

在項目中添加新文件夾 Infrastructure ,並添加一個類文件 NinjectDependencyResolver.cs

using EssentiaTools.Models;
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EssentiaTools.Infrastructure
{
    public class NinjectDependencyResolver:IDependencyResolver
    {
        private IKernel kernel;

        public NinjectDependencyResolver() {
            kernel = new StandardKernel();
            AddBindings();
        }

        public object GetService(Type serviceType) {
            return kernel.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType) {
            return kernel.GetAll(serviceType);
        }

        private void AddBindings()
        {
            kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
        }

    }
}

MVC  框架在需要一個類實例以便對一個傳入的請求進行服務時,會調用GetService 或 GetServices 方法。依賴解析器要做的工作便是創建這一實例 —— 這是一項要通過 Ninject 的 TryGet 和 GetAll 方法來完成的任務。 TryGet 方法的工作方式類似於前面所用的Get 方法,但當沒有合適的綁定時,它會返回 null ,而不是拋出異常。GetAll 方法支持對單一類型的多個綁定,當多個不同的服務提供器可用時,可以使用它。

上述依賴解析器類也是建立 Ninject 綁定的地方。在AddBindings 方法中,本例用Bind 和 To 方法建立了 IValueCalculator 介面和 LinqValueCalculator 類之間的關係。

 

註冊依賴解析器

必須告訴 MVC 框架,用戶希望使用自己的依賴解析器,此事可以通過修改 Global.asax 文件來完成。

using EssentiaTools.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace EssentiaTools
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            //通過這裡添加的語句,能讓 Ninject 來創建 MVC 框架所需的任何對象實例,
            //這便將 DI 放到了這一示例應用程式中
            DependencyResolver.SetResolver(new NinjectDependencyResolver());

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }
}

 

重構 Home 控制器

最後一個步驟是重構 Home 控制器,以使它能夠利用前面所建立的工具。

using EssentiaTools.Models;
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EssentiaTools.Controllers
{
    public class HomeController : Controller
    {
        private Product[] products = { 
        new Product{Name="Kayak",Catogory="Watersports",Price=275M}, 
        new Product{Name="Lifejacket",Catogory="Watersports",Price=48.95M}, 
        new Product{Name="Soccer ball",Catogory="Soccer",Price=19.50M},
        new Product{Name="Corner flag",Catogory="Soccer",Price=34.95M}
        };

        private IValueCalculator calc;

        public HomeController(IValueCalculator calcParam)
        {
            calc = calcParam;
        }

        public ActionResult Index()
        {
            ShoppingCart cart = new ShoppingCart(calc) { Products = products };
            decimal totalValue = cart.CalcularProductTotal();
            return View(totalValue);
        }
    }
}

所做的主要修改時添加了一個構造器,它接受 IValueCalculator 介面的實現。示例並未指定想要使用的是哪一個實現,而且已經添加了一個名為“calc”的實例變數,可以在整個控制器中用它來表示構造器所接收到的 IValueCalculator 。

所做的另一個修改時刪除了任何關於 Ninject 或 LinqValueCalculator 類的代碼 —— 最終打破了 HomeController 和 LinqValueCalculator 類之間的緊耦合。

運行結果和前例一樣:

示例創建的是一個構造器註入示例,這是依賴性註入的一種形式。以下是運行示例應用程式,且 Internet Explorer 對應用程式的跟 URL 發送請求時所發生的情況。

 (1)瀏覽器向 MVC 框架發送一個請求 Home 的URL, MVC 框架猜出該請求意指 Home 控制器,於是會創建 HomeController 類實例。

 (2)MVC 框架在創建 HomeController 類實例過程中會發現其構造器有一個對 IValueCalculator 介面的依賴項,於是會要求依賴性解析器對此依賴項進行解析,將該介面指定為依賴性解析器中 GetService 方法所使用的類型參數。

 (3)依賴項解析器會將傳遞過來的類型參數交給 TryGet 方法,要求 Ninject 創建一個新的 IValueCalculator 介面類實例。

 (4)Ninject 會檢測到該介面與其實現類 LinqValueCalculator 具有綁定關係,於是為該介面創建一個 LinqValueCalculator 類實例,並將其回遞給依賴性解析器。

 (5)依賴性解析器將 Ninject 所返回的 LinqValueCalculator 類作為 IValueCalculator 介面實現類實例回遞給 MVC 框架。

 (6)MVC 框架利用依賴性解析器返回的介面類實例創建 HomeController 控制器實例,並使用控制器實例度請求進行服務。

 

這裡所採取的辦法其好處之一是,任何控制器都可以在其構造器中聲明一個 IValueCalculator ,並通過自定義依賴性解析器使用 Ninject 來創建一個在 AddBindings 方法中指定的實現實例。

所得到的最大好處是,在希望用另一個實現來替代 LinqValueCalculator 時,只需要對依賴性解析器類進行修改,因為為了滿足對於 IValueCalculator 介面的請求,這裡是唯一一處為該介面指定實現類的地方。

 

創建依賴性鏈

當要求 Ninject 創建一個類型時,它會檢查該類型與其他類型之間的耦合。如果有額外的依賴性, Ninject 會自動地解析這些依賴性,並創建所需要的所有類型實例。

 在 Models 文件夾下新建文件 Discount.cs ,並定義了一個新的介面及其實現類:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public interface IDiscountHelper
    {
        //將一個折扣運用於一個十進位的值
        decimal ApplyDiscount(decimal totalParam);
    }

    public class DefaultDiscountHelper : IDiscountHelper
    {
        //實現介面 IDiscountHelper,並運用固定的10% 折扣
        public decimal ApplyDiscount(decimal totalParam)
        {
            return (totalParam - (10m / 100m * totalParam));
        }
    }
}

然後在 LinqValueCalculator 類中添加一個依賴性,修改 LinqValueCalculator 類,以使它執行計算時使用 IDiscountHelper 介面:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EssentiaTools.Models
{
    public class LinqValueCalculator : IValueCalculator
    {
        private IDiscountHelper discounter;

        public LinqValueCalculator(IDiscountHelper discountParam)
        {
            discounter = discountParam;
        }
        public decimal ValueProducts(IEnumerable<Product> products)
        {
            return discounter.ApplyDiscount(products.Sum(p => p.Price));
        }
    }
}

新添加的構造器以 IDiscountHelper 的介面實現為參數,然後將其用於 ValueProducts 方法,以便對所處理的 Products 對象的累計值運用一個折扣。

就像對 IValueCalculator 所做的那樣,在 NinjectDependencyResolver 類中,用 Ninject 內核將 IDiscountHelper 介面與其實現類進行了綁定,將另一個介面綁定到它的實現:

using EssentiaTools.Models;
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EssentiaTools.Infrastructure
{
    public class NinjectDependencyResolver:IDependencyResolver
    {
        private IKernel kernel;

        public NinjectDependencyResolver() {
            kernel = new StandardKernel();
            AddBindings();
        }

        public object GetService(Type serviceType) {
            return kernel.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType) {
            return kernel.GetAll(serviceType);
        }

        private void AddBindings()
        {
            kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
            kernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>();
        }

    }
}

 上述這一做法已經創建了一個 Ninject 可以輕鬆解析的依賴性鏈,這是通過在自定義依賴性解析器中所定義的綁定實現的。為了滿足對 HomeController 類的請求,Ninject 會意識到它需要創建一個用於 IValueCalculator 類的實現,通過考察其綁定,便會看出該介面的實現策略是使用 LinqValueCalculator 類。但在創建 LinqValueCalculator 對象過程, Ninject 又會意識到它需要使用 IDiscountHelper 介面實現,因此會查看其綁定,並創建一個 DefaultDiscountHelper 對象。 Ninject 會創建這一 DefaultDiscountHelper ,並將其傳遞給 LinqValueCalculator 對象的構造器, LinqValueCalculator 對象又轉而被傳遞給 HomeController 類的構造器,最後所得到的 HomeController 用於對用戶的請求進行服務。 Ninject 會以這種方式檢查它要實例化的每一個依賴性類,無論其依賴性鏈有多長,多複雜。

 

2.5 指定屬性與構造器參數值

在把介面綁定到它的實現時,可以提供想要運用到屬性上的一些屬性細節,以便對 Ninject 創建的類進行配置。修改 DefaultDiscountHelper 類,以使它定義一個 DiscountSize屬性,該屬性用於計算折扣量:

    public class DefaultDiscountHelper : IDiscountHelper
    {
        public decimal DiscountSize { get; set; }
        public decimal ApplyDiscount(decimal totalParam)
        {
            return (totalParam - (DiscountSize / 100m * totalParam));
        }
    }

在用 Ninject 將具體類綁定到類型時,可以使用 WithPropertyValue 方法來設置 DefaultDiscountHelper 類中的 DiscountSize 屬性的值。

        ...
        private void AddBindings()
        {
            kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
            kernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithPropertyValue("DiscountSize",50M);
        }
        ...

註意,必須提供一個字元串值作為要設置的屬性名。既不需要修改任何綁定,也不需要修改使用 Get 方法獲取 ShoppingCart 類實例的方式。

該屬性值會按照 DefaultDiscountHelper 的構造進行設置,並起到半價的效果。顯示結果如下:

如果需要設置多個屬性值,可以鏈接調用 WithPropertyValue 方法涵蓋所有這些屬性,也可以用構造器參數做同樣的事情。可以重寫 DefaultDiscountHelper 類如下,以便折扣大小作為構造器參數進行傳遞。

    public class DefaultDiscountHelper : IDiscountHelper
    {
        public decimal discountSize;

        public DefaultDiscountHelper(decimal discountParam)
        {
            discountSize = discountParam;
        }
        public decimal ApplyDiscount(decimal totalParam)
        {
            return (totalParam - (discountSize / 100m * totalParam));
        }
    }

為了用 Ninject 綁定這個類,可以在 AddBindings 方法中使用 WithConstructorArgument 方法來指定構造器參數的值:

        ...
        private void AddBindings()
        {
            kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
            kernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithConstructorArgument("discountParam",50M);
        }
        ...

這一技術允許用戶將一個值註入到構造器中。同樣,可以將這些方法調用鏈接在一起,以提供多值,並與依賴性混合和匹配。 Ninject 會判斷出用戶的需要,並依此來創建它。

 

2.6 使用條件綁定

Ninject 支持多個條件的綁定方法,這能夠指定用哪一個類對某一特定的請求進行響應。

在 Models 文件夾下新建類文件 FlexibleDiscountHelper.cs :

namespace EssentiaTools.Models
{
    public class FlexibleDiscountHelper : IDiscountHelper
    {

        public decimal ApplyDiscount(decimal totalParam)
        {
            decimal discount = totalParam > 100 ? 70 : 25;
            return (totalParam - (discount / 100M * totalParam));
        }
    }
}

FlexibleDiscountHelper 類根據要打折的總額大小運用不同的折扣,然後修改  NinjectDependencyResolver 的 AddBindings 方法,以告訴 Ninject 何時使用 FlexibleDiscountHelper ,何時使用 DefaultDiscountHelper:

        ...
        private void AddBindings()
        {
            kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
            kernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithConstructorArgument("discountParam",50M);
            kernel.Bind<IDiscountHelper>().To<FlexibleDiscountHelper>().WhenInjectedInto<LinqValueCalculator>();
        }
        ...

上述綁定指明,在 Ninejct 要將一個實現註入LinqValueCalculator 對象時,應該使用 FlexibleDiscountHelper 類作為 IDiscountHelper 介面的實現。

本例在適當的位置留下了對 IDiscountHelper 的原有綁定。 Ninject 會嘗試找出最佳匹配,而且這有助於對同一類或介面採用一個預設綁定,以便在條件判據不能得到滿足時,讓 Ninject 能夠進行回滾。 Ninject 有許多不同的條件綁定方法,最有用的一些條件綁定如下:

 

 

源碼地址:https://github.com/YeXiaoChao/EssentiaTools


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

-Advertisement-
Play Games
更多相關文章
  • centos7安裝要註意的地方。然後還有關於centOS共用win7文件夾的操作。
  • 已ubuntu為例在linux上安裝drupal
  • 這幾天突發奇想,想學習一下Python。看了點基礎,覺得有點枯燥,所以想搞點什麼。想了想,就隨便弄個檢測Linux用戶登錄的小工具吧~ 首先,明確一下功能: 1、能夠捕獲 linux 用戶登錄的信息。(這個很容易,方法比較多) 2、能夠將捕捉的信息記錄下來。(不然要這信息幹嘛……) 3、最好能夠一發
  • 最近好久沒有更新文章了,因為好久沒有寫代碼了,以至於我不知道同大家分享些什麼,剛好,今天突然叫我學習下jenkins每日構建,我就把今天的學習筆記記錄下來,這其中很多東西都是公司同事之前調研總結的,我在他的基礎上進行了更加詳細的整理,並自己一步一步的對著實現了一下。 環境準備 下載jenkins的w
  • 由於在官方下載的ueditor包是在vs2012下開發的,可以在vs2010中使用,但在vs2008中就會報錯。折騰了一翻,現將解決方法分享給需要的朋友,其實就是把裡面包含.net4.0的元素換成.net3.5的 1、下載.net framework 3.5版的Newtonsoft.Json.dll
  • 原來用的是Kindeditor這個編輯器,但很久沒更新了,最新版是13年更新的。現在要換成百度的Ueditor, 在這裡記錄Ueditor的使用流程和遇到的問題。 一、下載 1.Ueditor官網 這裡有三個版本:1.UBuilder:可以自定義選擇自已需要的功能,然後會下載對應的文件。 2.開發版
  • 那天在調試API的時候,發現用c#寫的SHA1加密出來的結果和PHP中sha1()出來的不一樣,找了半天的原因後來才弄出來 在調試微信介面的時候大多的幫助文檔都是提供的是PHP的方法,所以在.net中實現的時候會出現很多的問題,最典型的就是token通不過驗證 現在提供一個結果與Php一樣 的SHA
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...