项目作者: sulmar

项目描述 :
Przykłady ze szkolenia .NET Core
高级语言: C#
项目地址: git://github.com/sulmar/altkom-dotnet-core-201910.git
创建时间: 2019-10-28T16:08:51Z
项目社区:https://github.com/sulmar/altkom-dotnet-core-201910

开源协议:

下载


.NET Core

Przydatne komendy CLI

  • dotnet --list-sdks - wyświetlenie listy zainstalowanych SDK
  • dotnet new globaljson - utworzenie pliku global.json
  • dotnet new globaljson --sdk-version {version} - utworzenie pliku global.json i ustawienie wersji SDK
  • dotnet new --list - wyświetlenie listy dostępnych szablonów
  • dotnet new {template} - utworzenie nowego projektu na podstawie wybranego szablonu
  • dotnet new {template} -o {output} - utworzenie nowego projektu w podanym katalogu
  • dotnet restore - pobranie bibliotek nuget na podstawie pliku projektu
  • dotnet build - kompilacja projektu
  • dotnet run - uruchomienie projektu
  • dotnet run {app.dll} - uruchomienie aplikacji
  • dotnet test - uruchomienie testów jednostkowych
  • dotnet run watch - uruchomienie projektu w trybie śledzenia zmian
  • dotnet test - uruchomienie testów jednostkowych w trybie śledzenia zmian
  • dotnet add {project.csproj} reference {library.csproj} - dodanie odwołania do biblioteki
  • dotnet remove {project.csproj} reference {library.csproj} - usunięcie odwołania do biblioteki
  • dotnet new sln - utworzenie nowego rozwiązania
  • dotnet sln {solution.sln} add {project.csproj} - dodanie projektu do rozwiązania
  • dotnet sln {solution.sln} remove {project.csproj} - usunięcie projektu z rozwiązania
  • dotnet publish -c Release -r {platform} - publikacja aplikacji
  • dotnet publish -c Release -r win10-x64 - publikacja aplikacji dla Windows
  • dotnet publish -c Release -r linux-x64 - publikacja aplikacji dla Linux
  • dotnet publish -c Release -r osx-x64 - publikacja aplikacji dla MacOS
  • dotnet add package {package-name} - dodanie pakietu nuget do projektu
  • dotnet remove package {package-name} - usunięcie pakietu nuget do projektu

Struktura projektu

  1. + Solution
  2. |
  3. + - Console
  4. |
  5. + - Models
  6. |
  7. + - Infrastructure
  8. |
  9. + - Api

HTTP Client

  • Instalacja

    1. dotnet add package ServiceStack.HttpClient
  • Pobranie listy obiektów

    1. public async Task<IEnumerable<Customer>> Get()
    2. {
    3. var url = $"{baseUri}/api/customers";
    4. var json = await url.GetJsonFromUrlAsync();
    5. var customers = json.FromJson<ICollection<Customer>();
    6. return customers;
    7. }
  • Przekazanie parametrów
    ~~~ csharp

public async Task> Get(CustomerSearchCriteria customerSearchCriteria)
{
var url = $”{baseUri}/api/customers”;

url = AddQueryCustomerParams(customerSearchCriteria, url);

var json = await url.GetJsonFromUrlAsync();

var customers = json.FromJson>();

return customers;
}

private static string AddQueryCustomerParams(CustomerSearchCriteria searchCriteria, string url)
{
if (!string.IsNullOrEmpty(searchCriteria.CustomerNumber))
url = url.AddQueryParam(nameof(CustomerSearchCriteria.CustomerNumber), searchCriteria.CustomerNumber);

  1. if (!string.IsNullOrEmpty(searchCriteria.City))
  2. url = url.AddQueryParam(nameof(CustomerSearchCriteria.City), searchCriteria.City);
  3. if (!string.IsNullOrEmpty(searchCriteria.Street))
  4. url = url.AddQueryParam(nameof(CustomerSearchCriteria.Street), searchCriteria.Street);
  5. if (!string.IsNullOrEmpty(searchCriteria.Country))
  6. url = url.AddQueryParam(nameof(CustomerSearchCriteria.Country), searchCriteria.Country);
  7. return url;

}

  1. ## .NET Standard

.NET Framework | .NET Core |

.NET Standard

  1. ## Protokół HTTP
  2. żądanie (request)

GET /docs/index.html HTTP/1.1
host: www.altkom.pl
{blank line}

  1. odpowiedź (response)

HTTP/1.1 200 OK
Content-Length: 308
Content-Type: text/html


Hello World!


  1. ----
  2. żądanie (request)

GET /api/customers HTTP/1.1
host: www.altkom.pl
Accept: application/json
{blank line}

  1. odpowiedź (response)

HTTP/1.1 200 OK
Content-Length: 308
Content-Type: application/xml



John

  1. ## SOAP
  2. żądanie (request)

POST /myservice.asmx HTTP/1.1
host: www.altkom.pl
Content-Type: application/xml



John

  1. ## REST API
  2. | Akcja | Opis |
  3. |--------|-----------------------|
  4. | GET | Pobierz |
  5. | POST | Utwórz |
  6. | PUT | Podmień |
  7. | DELETE | Usuń |
  8. | PATCH | Zmień częściowo |
  9. | HEAD | Czy zasób istnieje |
  10. prawidłowe

GET api/customers
GET api/customers/10
GET api/customers/altkom
GET api/customers?city=Katowice&Street=Opolska
DELETE api/customers/10

  1. nieprawidłowe

GET api/customers?Id=10
GET api/customers/delete?Id=10
GET api/customers/GetCustomerByCity?city=Poznan

  1. ## Porównanie ASP.NET MVC i .NET Core
  2. ASP.NET MVC

Controller ApiController
View(model) Ok(model)

  1. .NET Core

Controller -> BaseController
View(model) Ok(model)

  1. ## Wstrzykiwanie zależności
  2. DI/IoC
  3. ~~~ csharp
  4. interface Factory
  5. {
  6. T Create<T>();
  7. }
  1. | Key | Value | Cykl zycia
  2. | ICustomerRepository | FakeCustomerRepository | Singleton
  3. | CustomerFaker | CustomerFaker |
  4. | AddressFaker | AddressFaker |
  • Przykładowe frameworki
    Unity, AutoFac, Ninject, LightInject

Baza danych

  • Przykładowe frameworki
    1. ADO.NET | Dapper/PetaPOCO | EF Core/nHibernate

Konfiguracja

  • Utworzenie klasy opcji
    1. public class CustomerOptions
    2. {
    3. public int Quantity { get; set; }
    4. }
  • Plik konfiguracyjny appsettings.json
  1. {
  2. "CustomersModule": {
  3. "Quantity": 40
  4. },
  • Instalacja biblioteki
  1. dotnet add package Microsoft.Extensions.Options
  • Użycie opcji
  1. public class FakeCustomersService
  2. {
  3. private readonly CustomerOptions options;
  4. public FakeCustomersService(IOptions<CustomerOptions> options)
  5. {
  6. this.options = options.Value;
  7. }
  8. }
  • Konfiguracja opcji
  1. public class Startup
  2. {
  3. public IConfiguration Configuration { get; }
  4. public Startup(IHostingEnvironment env)
  5. {
  6. var builder = new ConfigurationBuilder()
  7. .SetBasePath(env.ContentRootPath)
  8. .AddJsonFile("appsettings.json", optional: false)
  9. .AddXmlFile("appsettings.xml", optional: true)
  10. .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
  11. Configuration = builder.Build();
  12. }
  13. public void ConfigureServices(IServiceCollection services)
  14. {
  15. services.Configure<CustomerOptions>(Configuration.GetSection("CustomersModule"));
  16. }
  17. }
  • Konfiguracja bez interfejsu IOptions
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. var customerOptions = new CustomerOptions();
  4. Configuration.GetSection("CustomersModule").Bind(customerOptions);
  5. services.AddSingleton(customerOptions);
  6. services.Configure<CustomerOptions>(Configuration.GetSection("CustomersModule"));
  7. }

Opcje serializacji json

Plik Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddMvc()
  4. .AddJsonOptions(options =>
  5. {
  6. options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; // Wyłączenie generowania wartości null w jsonie
  7. options.SerializerSettings.Converters.Add(new StringEnumConverter(camelCaseText: true)); // Serializacja enum jako tekst
  8. options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; // Zapobieganie cyklicznej serializacji
  9. })
  10. }

Włączenie obsługi XML

Plik Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services
  4. .AddMvc(options => options.RespectBrowserAcceptHeader = true)
  5. .AddXmlSerializerFormatters();
  6. }

Task

  1. t1 -----+=============+------------------->
  2. t1 -----+-------+------------------------>
  3. | | |
  4. t2 -----+=============|------------------>
  5. | |
  6. t3 -------------+=============|---------->
  7. |
  8. t4 ----------------------+=======|------->
  • Task - zadanie, które nie zwraca wyniku
  • Task - zadanie, które zwraca wynik o podanym typie

Middleware

  1. middleware (filter)
  2. request -> ----|---|-----|-----|-----|===Get(100)====|---response-------->

Autoryzacja

Basic

Headers
| Key | Value |
|—-|—-|
| Authorization | Basic {Base64(login:password)} |

Implementacja

  • Utworzenie interfejsu

    1. public interface ICustomerRepository : IEntityRepository<Customer>
    2. {
    3. bool TryAuthorize(string username, string hashPasword, out Customer customer);
    4. }
  • Implementacja repozytorium

  1. public class DbCustomerRepository : ICustomerRepository
  2. {
  3. private readonly MyContext context;
  4. public DbCustomerRepository(MyContext context)
  5. {
  6. this.context = context;
  7. }
  8. public bool TryAuthorize(string username, string hashPasword, out Customer customer)
  9. {
  10. customer = context.Customers.SingleOrDefault(e => e.UserName == username && e.HashPassword == hashPasword);
  11. return customer != null;
  12. }
  13. }
  • Utworzenie uchwytu autoryzacji
  1. public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
  2. {
  3. private readonly ICustomerRepository customerRepository;
  4. public BasicAuthenticationHandler(
  5. ICustomerRepository customerRepository,
  6. IOptionsMonitor<AuthenticationSchemeOptions> options,
  7. ILoggerFactory logger,
  8. UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
  9. {
  10. this.customerRepository = customerRepository;
  11. }
  12. protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
  13. {
  14. if (!Request.Headers.ContainsKey("Authorization"))
  15. return AuthenticateResult.Fail(string.Empty);
  16. var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
  17. if (authHeader.Scheme != "Basic")
  18. return AuthenticateResult.Fail(string.Empty);
  19. var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
  20. string[] credentials = Encoding.UTF8.GetString(credentialBytes).Split(':');
  21. if (!customerRepository.TryAuthorize(credentials[0], credentials[1], out Customer customer))
  22. {
  23. return AuthenticateResult.Fail("Invalid username or password");
  24. }
  25. ClaimsIdentity identity = new ClaimsIdentity("Basic");
  26. identity.AddClaim(new Claim(ClaimTypes.HomePhone, "555-444-333"));
  27. identity.AddClaim(new Claim(ClaimTypes.Role, "Developer"));
  28. ClaimsPrincipal principal = new ClaimsPrincipal(identity);
  29. var ticket = new AuthenticationTicket(principal, "Basic");
  30. return AuthenticateResult.Success(ticket);
  31. }
  32. }
  • Rejestracja
    Startup.cs
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddAuthentication("BasicAuthorization")
  4. .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthorization", null);
  5. }
  6. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  7. {
  8. app.UseAuthentication();
  9. app.UseMvc();
  10. }

Token

Headers
| Key | Value |
|—-|—-|
| Authorization | Bearer {token} |

  • OAuth 2.0 (google, facebook, github)
  • JWT

Generowanie dokumentacji

W formacie Swagger/OpenApi

Instalacja

  1. dotnet add package Swashbuckle.AspNetCore

Konfiguracja

Plik Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services
  4. .AddSwaggerGen(c => c.SwaggerDoc("v1", new Info { Title = "My Api", Version = "1.0" }));
  5. }
  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  2. {
  3. app.UseSwagger();
  4. app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"));
  5. }