ASP.NET Core 1.0 開發記錄

来源:http://www.cnblogs.com/xishuai/archive/2016/12/01/aspnet-core1-record.html
-Advertisement-
Play Games

官方資料: "https://github.com/dotnet/core" "https://docs.microsoft.com/en us/aspnet/core" "https://docs.microsoft.com/en us/ef/core" 相關文章: "ASP.NET 5 RC1 ...


官方資料:

相關文章:ASP.NET 5 RC1 升級 ASP.NET Core 1.0 RC2 記錄

ASP.NET Core 1.0 更新比較快(可能後面更新就不大了),閱讀註意時間節點,這篇博文主要記錄用 ASP.NET Core 1.0 開發簡單應用項目的一些記錄,以備查閱。

ASP.NET Core 1.0 相關 Nuget 程式包源:https://api.nuget.org/v3/index.json

閱讀目錄:

  • 理解 .NET Platform Standard
  • Startup 配置
    • Sample.BootStrapper.Startup 配置
    • ASP.NET Core 1.0 Startup 配置
  • UnitTest 單元測試
    • 類庫項目單元測試
    • WebApi 項目單元測試
  • Microsoft.EntityFrameworkCore
    • 基本配置(MySql)
    • ModelBuilderExtenions 擴展
    • 記錄執行 SQL
    • EntityFrameworkCore 遷移
  • CLI 命令

1. 理解 .NET Platform Standard

參考文章:

在用 ASP.NET Core 1.0 開發之前,理解 .NET Platform Standard(.NET 平臺標準)是非常有必要的,因為部署是跨平臺的,ASP.NET Core 1.0 應用程式的配置不同,部署環境也會不同,並且項目之間的相容也會存在一些問題。

.NET Platform Standard 列表(2016 上半年):

Target Platform Name Alias
.NET Platform Standard netstandard 1.0 1.1 1.2 1.3 1.4 1.5 1.6
.NET Core netcoreapp 1.0
.NET Framework net 4.6.3
4.6.2
4.6.1
4.6
4.5.2
4.5.1
4.5
Universal Windows Platform uap 10.0
Windows win 8.1
8.0
Windows Phone wpa 8.1
Windows Phone Silverlight wp 8.1
8.0
Mono/Xamarin Platforms *
Mono *

上面圖表時間雖然有點老,但和現在的發展是一樣的,只不過版本有所更新,主要的三個平臺:

  • .NET Platform Standard(netstandard):.NET 平臺標準,或者稱為 .NET 通用平臺,是 .NET 部署所有平臺的一種通用標準規範(包含 Windows、Mac、Linux 等),建議使用,現在最新版本是 1.6 (2.0 版本快發佈)。
  • .NET Core(netcoreapp):.NET Core SDK running on CoreCLR/CoreFx,簡單來說,可以跑在安裝 CoreCLR/CoreFx 的任何平臺上(包含 Windows、Mac、Linux 等),前提必須是有 .NET Core 的運行環境,建議使用,現在最新版本是 1.1.0
  • .NET Framework(net):.Net Framework SDK running on Desktop CLR / Full BCL and FCL,簡單來說,只能跑在 Windows 平臺上,不建議使用,最新版本是 4.6.3。

我們在開發 ASP.NET Core 1.0 應用程式的時候,一般是選擇netstandardnetcoreapp版本,並且這兩個平臺版本是相互相容的,分別看一下示例:

netstandard1.6平臺:

{
  "version": "1.0.0",

  "dependencies": {
    "Microsoft.EntityFrameworkCore": "1.0.0",
    "NETStandard.Library": "1.6.1"
  },

  "frameworks": {
    "netstandard1.6": {
      "imports": "dnxcore50"
    }
  }
}
  • "imports": "dnxcore50" 的意思是相容之前dnxcore50平臺(dnxcore50現在已被廢棄,並被netcoreapp取代),比如你之前有個類庫是用dnxcore50平臺開發的,現在使用netstandard平臺開發的類庫,如果不添加此配置,是會報錯的。
  • "NETStandard.Library": "1.6.1"包含了一系列和netstandard相關的 Nuget 程式包,配置netstandard平臺,必須添加此配置,如果沒有的話,.NET 基礎的命名空間是訪問不到的。

netcoreapp1.1.0平臺:

{
  "version": "1.0.0",

  "dependencies": {
    "Microsoft.EntityFrameworkCore": "1.0.0"
  },

  "frameworks": {
    "netcoreapp1.1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.1.0"
        }
      }
    },
      "imports": [
        "dotnet5.6",
        "portable-net45+win10"
      ]
    }
  }
}

netstandard1.1.0平臺和上面netstandard1.6平臺配置差不多,Microsoft.NETCore.App 和 NETStandard.Library 是一樣目的,dotnet5.6dnxcore50一樣,都是 .NET Core 之前平臺的廢棄代號。

portable 的意思是便攜型,如果添加了此配置,表示應用程式發佈部署不攜帶依賴的程式包,而是使用系統中安裝配置的。

還有一點需要註意的是,netcoreapp1.1.0平臺和netstandard1.6平臺開發是相互相容的,比如我們開發一些自己的 Nuget 程式包,使用的平臺版本可以是上面兩個,但最好是使用netstandard低一點的版本,因為以後netstandard可能是微軟平臺的一種標準規範,比如我現在開發 Nuget 程式包平臺使用netcoreapp1.1.0,ASP.NET Core 1.0 應用程式使用netcoreapp1.1.0平臺,後者就可以引用前者,因為第三方 Nuget 程式包使用平臺版本可能比較低,所以我們開發的 ASP.NET Core 1.0 應用程式平臺版本也相應低一些。

2. Startup 配置

Startup 需要添加額外的配置,以便於單元測試的進行,比如 EF、依賴註入和 AutoMapper 配置,需要獨立進行配置,而不是放在 ASP.NET Core 1.0 應用程式中的 Startup 配置中。

2.1 Sample.BootStrapper.Startup 配置

比如這樣的一個項目 Sample.BootStrapper:

public static class Startup
{
    public static void Configure(this IServiceCollection services, string connectionString)
    {
        services.AddDbContext<SampleDbContext>(options =>
            options.UseMySQL(connectionString, b => b.MigrationsAssembly("Sample.WebApi"))
        );
        services.AddTransient<IUnitOfWork, UnitOfWork>();
        services.AddScoped<IDbContext, CommodityDbContext>();

        ConfigureMapper();
    }

    private static void ConfigureMapper()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<SupplierItem, PurchaseItemDTO>()
                .ForMember(d => d.ItemDetailDTOs, opt => opt.MapFrom(s => s.SupplierItemSkus));
            cfg.CreateMap<SupplierItemSku, PurchaseItemDetailDTO>();
        });
    }
}

project.json 配置:

{
  "version": "1.0.0-*",

  "dependencies": {
    "System.ComponentModel.Primitives": "4.1.0",
    "Microsoft.NETCore.App": ""
  },

  "frameworks": {
    "netcoreapp1.1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.1.0"
        }
      }
    }
  }
}

上面代碼主要是對 IServiceCollection 的 Configure 方法進行了擴展,這樣對 Domain、Repository 和 AppliactionService 進行獨立的單元測試了,只需要在構造函數中進行添加調用即可,後面再說這一點。

2.2 ASP.NET Core 1.0 Startup 配置

另外,ASP.NET Core 1.0 應用程式的 Startup 示例代碼:

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
#if DEBUG
        var path = Directory.GetCurrentDirectory();
#else
        var path = env.ContentRootPath;
#endif
        var builder = new ConfigurationBuilder()
            .SetBasePath(path)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();

        Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Error()
        .WriteTo.RollingFile(Path.GetFullPath("logs/log-{Date}.txt"))
        .CreateLogger();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {  
        // Add framework services.
        // 配置 WebApi 返回 Json 數據大小寫問題,預設數據會首字母小寫。
        services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

        // 註意這裡
        services.Configure(Configuration["data:ConnectionString"]);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddSerilog();

        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        app.UseStaticFiles();
        app.UseMvc();
    }
}

日誌服務使用的是 Serilog,日誌級別有多種進行選擇(可以 Debug、Error 等),日誌和連接字元串的配置可以放在 appsettings.json 文件中,ConfigureServices 裡面調用 Sample.BootStrapper.StartUp 的配置。

project.json 示例代碼:

{
  "dependencies": {
    "Microsoft.AspNetCore.Mvc": "1.0.1",
    "Microsoft.AspNetCore.Routing": "1.0.1",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.1.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
    "Microsoft.AspNetCore.Cors": "1.0.0",
    "Serilog": "2.3.0",
    "Serilog.Extensions.Logging":"1.3.1",
    "Serilog.Sinks.RollingFile": "3.2.0",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
    "Sample.BootStrapper": "1.0.0-*",
    "Microsoft.EntityFrameworkCore.Design": {
      "type": "build",
      "version": "1.0.0-preview2-final"
    }
  },

  "tools": {
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "netcoreapp1.0.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }
      },
      "imports": [
        "dotnet5.6",
        "portable-net45+win10"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

appsettings.json 示例代碼:

{
  "data": {
    "ConnectionString": ""
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Error",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

另外,在 Program.cs 中可以配置選擇伺服器,比如 IIS 或 Kestrel 等。

3. UnitTest 單元測試

相關文章:

單元測試主要包含兩方面:類庫項目單元測試和 WebApi 項目單元測試。

3.1 類庫項目單元測試

類庫項目單元測試代碼示例:

using Microsoft.Extensions.DependencyInjection;
using Xunit.Abstractions;
using Sample.BootStrapper;

public class UnitTest
{
    private readonly ITestOutputHelper output;
    private IServiceProvider provider;
    private IProductRepository _productRepository;

    public UnitTest(ITestOutputHelper output)
    {
        var connectionString = "";
        var services = new ServiceCollection();
        this.output = output;
        services.Configure(connectionString);
        provider = services.BuildServiceProvider();

        _productRepository = provider.GetService<IProductRepository>();
    }

    [Fact]
    public async Task GetTest()
    {
        Assert.True(true);
    }
}

provider.GetService 手動獲取依賴註入的對象,ITestOutputHelper 的目的是取代Console.WriteLine(因為不支持),但現在 ITestOutputHelper 好像也輸出不了,之前 RC2 的時候是可以的,不知道啥原因。

3.1 WebApi 項目單元測試

WebApi 項目單元測試示例代碼:

using Xunit.Abstractions;
using Microsoft.AspNetCore.TestHost;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Sample.WebApi;

public class UnitTest
{
    private readonly ITestOutputHelper output;
    private readonly TestServer _server;
    private readonly HttpClient _client;

    public UnitTest(ITestOutputHelper output)
    {
        _server = new TestServer(new WebHostBuilder()
            .UseStartup<Startup>());
        _client = _server.CreateClient();
    }

    [Fact]
    public async Task GetTest()
    {
        var ids = new List<int>{1, 2};
        var httpContent = new StringContent(JsonConvert.SerializeObject(ids), Encoding.UTF8, "application/json");
        var response = await _client.PostAsync($"/products", httpContent);

        response.EnsureSuccessStatusCode();
        Console.WriteLine(await response.Content.ReadAsStringAsync());
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

RC2 版本是無法對 WebApi 進行單元測試的,因為 TestHost 不支持,現在 ASP.NET Core 1.0 版本和 ASP.NET WebApi 2 是差不多的了,使用也很方便,不過 HttpClient 沒有了 PostAsJsonAsync 方法,需要使用 JsonConvert 手動轉換一下。

project.json 配置代碼:

{
  "version": "1.0.0-*",
  "testRunner": "xunit",
  "dependencies": {
    "xunit": "2.2.0-beta4-build3444",
    "dotnet-test-xunit": "2.2.0-preview2-build1029",
    "Microsoft.AspNetCore.TestHost": "1.0.0",
    "Microsoft.Extensions.DependencyInjection": "1.1.0",
    "Sample.BootStrapper": "1.0.0-*",
    "Sample.WebApi": "1.0.0-*"
  },

  "frameworks": {
    "netcoreapp1.0.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }
      },
      "imports": [
        "dotnet5.6",
        "portable-net45+win10"
      ]
    }
  }
}

我之前用netstandard1.6平臺,但配置 xunit 的時候,發現不支持最新的版本,後來就該用了netcoreapp1.0.1testRunner 配置後可以在 Test Explorer 視窗中看到單元測試,也可以在方法的視窗上看到,主要用於調試目的。

單元測試命令:dotnet test

4. Microsoft.EntityFrameworkCore

相關資料:Entity Framework Core

4.1 基本配置

Microsoft.EntityFrameworkCore 和 EntityFramework 7 的用法差不多,現在項目使用的 MySql 資料庫,示例配置代碼:

public class SampleDbContext : DbContext
{
    public SampleDbContext(DbContextOptions<SampleDbContext> options)
        : base(options)
    { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.AddEntityConfigurationsFromAssembly(GetType().GetTypeInfo().Assembly); 
    }
}

Map 映射配置(可能多個):

public class ProductMap : EntityMappingConfiguration<Product>
{
    public override void Map(EntityTypeBuilder<Product> builder)
    {
        builder.HasKey(p => p.Id);
    }
}

4.2 ModelBuilderExtenions 擴展

AddEntityConfigurationsFromAssembly 是對 ModelBuilder 的擴展,這樣如果有多個實體映射配置,OnModelCreating 中只需要一行代碼就可以了,擴展代碼

public interface IEntityMappingConfiguration
{
    void Map(ModelBuilder b);
}

public interface IEntityMappingConfiguration<T> : IEntityMappingConfiguration where T : class
{
    void Map(EntityTypeBuilder<T> builder);
}

public abstract class EntityMappingConfiguration<T> : IEntityMappingConfiguration<T> where T : class
{
    public abstract void Map(EntityTypeBuilder<T> b);

    public void Map(ModelBuilder b)
    {
        Map(b.Entity<T>());
    }
}

public static class ModelBuilderExtenions
{
    private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
    {
        return assembly
            .GetTypes()
            .Where(x =>
                !x.GetTypeInfo().IsAbstract &&
                x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
    }

    public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
    {
        var mappingTypes = assembly.GetMappingTypes(typeof(IEntityMappingConfiguration<>));

        foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMappingConfiguration>())
            config.Map(modelBuilder);
    }
}

project.json 示例代碼:

{
  "version": "1.0.0-*",

  "dependencies": {
    "MySql.Data.EntityFrameworkCore": "7.0.6-IR31",
    "MySql.Data": "7.0.6-IR31",
    "System.Reflection.TypeExtensions": "4.3.0",
    "Microsoft.Extensions.DependencyInjection": "1.1.0"
  },

  "frameworks": {
    "netcoreapp1.0.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }
      }
    }
  }
}

EntityFrameworkCore 針對 MySql 微軟沒有開放相應的 Nuget 程式包,第三方有很多的程式包,但或多或少的有些問題,MySql.Data.EntityFrameworkCore 是 EntityFrameworkCore GitHub Issue 中出現最多的,並且是 MySql 自己開發的,所以使用的話沒什麼問題。

如果在查詢的時候報這個錯誤:

System.MissingMethodException was unhandled
HResult=-2146233069
Message=Method not found: 'Void Microsoft.EntityFrameworkCore.Query.QueryContextFactory..ctor(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IStateManager, Microsoft.EntityFrameworkCore.Internal.IConcurrencyDetector, Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IChangeDetector)'.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalQueryContextFactory..ctor(IStateManager stateManager, IConcurrencyDetector concurrencyDetector, IRelationalConnection connection, IChangeDetector changeDetector)
--- End of stack trace from previous location where exception was thrown ---

解決方式是引用 MySql.Data.EntityFrameworkCore 程式包的類庫,移除 Microsoft.EntityFrameworkCore 程式包,參考資料:MissingMethodException DbSet.ToList

4.3 記錄執行 SQL

另外,關於 EntityFrameworkCore 如何記錄執行 SQL,Google 找了好久也沒找到好的解決方案,最後找到了一個別人寫的 IQueryable 擴展方法

public static class IQueryableExtensions
{
    private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();

    private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler");

    private static readonly PropertyInfo NodeTypeProviderField = QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider");

    private static readonly MethodInfo CreateQueryParserMethod = QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser");

    private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");

    private static readonly FieldInfo QueryCompilationContextFactoryField = typeof(Database).GetTypeInfo().DeclaredFields.Single(x => x.Name == "_queryCompilationContextFactory");

    public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
    {
        if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
        {
            throw new ArgumentException("Invalid query");
        }

        var queryCompiler = (IQueryCompiler)QueryCompilerField.GetValue(query.Provider);
        var nodeTypeProvider = (INodeTypeProvider)NodeTypeProviderField.GetValue(queryCompiler);
        var parser = (IQueryParser)CreateQueryParserMethod.Invoke(queryCompiler, new object[] { nodeTypeProvider });
        var queryModel = parser.GetParsedQuery(query.Expression);
        var database = DataBaseField.GetValue(queryCompiler);
        var queryCompilationContextFactory = (IQueryCompilationContextFactory)QueryCompilationContextFactoryField.GetValue(database);
        var queryCompilationContext = queryCompilationContextFactory.Create(false);
        var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor();
        modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
        var sql = modelVisitor.Queries.First().ToString();

        return sql;
    }
}

調用示例:

var query = _productRepository.Get(1);
var sql = query.ToSql();
Console.WriteLine(sql);

不過暫時只能輸出單表查詢的,多表關聯查詢的執行 SQL 輸出不了。

4.4 EntityFrameworkCore 遷移

相關文章:

相對於 EntityFramework 7,EntityFrameworkCore 遷移改變很多,

首先,ASP.NET Core 1.0 project.json 中添加如下配置:

{
    "dependencies": {
        "Microsoft.EntityFrameworkCore.Design": {
            "type": "build",
            "version": "1.0.0-preview2-final"
        }
    },

    "tools": {
        "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
    },

    "frameworks": {
        "netcoreapp1.0.1": { }
    }
}

Sample.BootStrapper.Startup 中 Configure 修改如下:

public static void Configure(this IServiceCollection services, string connectionString)
{
    services.AddDbContext<CommodityDbContext>(options =>
        options.UseMySQL(connectionString, b => b.MigrationsAssembly("Sample.WebApi"))//添加 MigrationsAssembly
    );

    ///to do...

然後 CMD 直接切換到 Sample.WebApi 文件目錄下,執行如下命令:

  • dotnet ef migrations add 名稱
  • dotnet ef database update

5. CLI 命令

相關資料:.NET Core 命令行介面工具

dotnet 具有以下命令:

  • dotnet new:初始化 C# 或 F # 控制台應用程式項目。
  • dotnet restore:還原給定應用程式的依賴項。
  • dotnet build:生成 .NET Core 應用程式。
  • dotnet publish:發佈 .NET 可移植或獨立應用程式。
  • dotnet run:從源運行應用程式。
  • dotnet test:使用 project.json 中指定的測試運行程式運行測試。
  • dotnet pack:創建代碼的 NuGet 包。

CLI 還支持持續集成,不過沒試過,我第一次用 dotnet pack,結合 Nuget Package Explorer 可以很方便的發佈管理程式包。


大概就記錄這些。



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

-Advertisement-
Play Games
更多相關文章
  • 在微軟官方關於ef7的介紹中強調,ef7將捨棄database first、model first,只保留code first的使用。這引起了很多人的擔憂,擔憂源自對code first的錯誤理解。因為很多人認為code first是區別於database first與model first的第三種 ...
  • 在目前的軟體項目中,都會較多的使用到對文檔的操作,用於記錄和統計相關業務信息。由於系統自身提供了對文檔的相關操作,所以在一定程度上極大的簡化了軟體使用者的工作量。 在.NET項目中如果用戶提出了相關文檔操作的需求,開發者較多的會使用到微軟自行提供的插件,在一定程度上簡化了開發人員的工作量,但是同時也 ...
  • 1.設置gridview裡面的屬性中ShowFooter="True",就是把gridview的頁腳顯示出來 this.gvData.OptionsView.ShowFooter = true; 2.設置要彙總的列,例如彙總"ReceiveMoney"金額列 3.給gridView添加CustomS ...
  • 假設有如下代碼所示的多線程: 這個新建的線程t在執行完Test()方法後會自動銷毀嗎?還是需要寫代碼手動銷毀呢? 下麵就多線程的非主線程銷毀機製做個總結: 1).t結束就自動銷毀了 2).設置線程屬性IsBackground=true 將線程t作為後臺線程,隨著主線程結束而一起結束,不管這個線程有沒 ...
  • 最近一直在研究Paypal的支付平臺,因為本人之前沒有接觸過介面這一塊,新來一家公司比較不清楚流程就要求開發兩個支付平臺一個是支付寶(這邊就不再這篇文章裡面贅述了),但還是花了2-3天的時間通過自己研究和借鑒別人的文章以及強大的Paypal官方技術文檔搞清楚了真正的原理和開發過程。(如有不同見解或者 ...
  • 上個月月底,VS2017RC版發佈了,一個很大的特點就是將原來的xProj文件又改回了csproj了。 這樣一改,其實很多新的問題也暴露出來了,最嚴重的問題就是Net版本相容性。 原來的Net體系大致是NetFramework,Net Core這樣的,雖然也有Net Standard 這樣的概念,但 ...
  • 本隨筆續接:.NET 實現並行的幾種方式(三) 八、await、async - 非同步方法的秘密武器 1) 使用async修飾符 和 await運算符 輕易實現非同步方法 前三篇隨筆已經介紹了多種方式、利用多線程、充分利用多核心CPU以提高運行效率。但是以前的方式在WebAPI和GUI系統上、 使用起來 ...
  • 用法一、this代表當前實例,用this.來調用當前實例的成員方法,變數,屬性,欄位等 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...