Aracılığıyla paylaş


ASP.NET Web Forms'dan Blazor

İpucu

Bu içerik, Blazor .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan Azure için ASP NET Web Forms Geliştiricileri için e-Kitap'tan bir alıntıdır.

Blazor-for-ASP-NET-Web-Forms-Developers eBook kapak küçük resmi.

Kod tabanını ASP.NET Web Forms'a geçirmek Blazor , planlama gerektiren zaman alan bir görevdir. Bu bölümde sürecin ana hatları açıklanmış durumdadır. Geçişi kolaylaştırabilecek bir şey, uygulamanın N katmanlı bir mimariye uyduğunu ve burada uygulama modelinin (bu örnekte Web Forms) iş mantığından ayrı olduğundan emin olmaktır. Katmanların bu mantıksal ayrımı, .NET Core ve Blazor'ye nelerin taşınması gerektiğini netleştirir.

Bu örnekte GitHub'da bulunan eShop uygulaması kullanılır. eShop, form girişi ve doğrulama yoluyla CRUD özellikleri sağlayan bir katalog hizmetidir.

Çalışan bir uygulama neden uygulamasına Blazorgeçirilmelidir? Çoğu zaman buna gerek yoktur. ASP.NET Web Forms yıllar boyunca desteklenmeye devam edecektir. Ancak, sağlayan özelliklerin Blazor çoğu yalnızca geçirilen bir uygulamada desteklenir. Bu özellikler şunlardır:

  • Çerçevede performans geliştirmeleri, örneğin Span<T>
  • Farklı çalıştırabilme özelliği WebAssembly
  • Linux ve macOS için platformlar arası destek
  • Diğer uygulamaları etkilemeden uygulama yerel dağıtımı veya paylaşılan çerçeve dağıtımı

Bu veya diğer yeni özellikler yeterince ilgi çekiciyse, uygulamanın geçirilmesinde değer olabilir. Geçiş farklı şekiller alabilir; uygulamanın tamamı veya yalnızca değişiklik gerektiren belirli uç noktalar olabilir. Geçiş kararı sonuçta geliştirici tarafından çözülecek iş sorunlarına dayanır.

Sunucu tarafı ve istemci tarafı barındırma karşılaştırması

Barındırma modelleri bölümünde açıklandığı gibi, bir Blazor uygulama iki farklı şekilde barındırılabilir: sunucu tarafı ve istemci tarafı. Sunucu tarafı modeli, sunucuda gerçek kod çalıştırırken DOM güncelleştirmelerini yönetmek için ASP.NET Core SignalR bağlantılarını kullanır. İstemci tarafı modeli bir tarayıcı içinde çalışır WebAssembly ve sunucu bağlantısı gerektirmez. Belirli bir uygulama için en uygun olan, etkileyebilecek çeşitli farklılıklar vardır:

  • Farklı WebAssembly çalıştırılıyor, geçerli zamanda tüm özellikleri (iş parçacığı oluşturma gibi) desteklemez
  • İstemci ve sunucu arasındaki sohbet iletişimi, sunucu tarafı modunda gecikme sorunlarına neden olabilir
  • Veritabanlarına ve iç veya korumalı hizmetlere erişim için istemci tarafı barındırma ile ayrı bir hizmet gerekir

Yazma sırasında, sunucu tarafı modeli Web Forms'a daha yakından benzer. Bu bölümün çoğu, üretime hazır olduğundan sunucu tarafı barındırma modeline odaklanır.

Yeni proje oluşturma

Bu ilk geçiş adımı yeni bir proje oluşturmaktır. Bu proje türü.NET'in SDK stili projelerini temel alır ve önceki proje biçimlerinde kullanılan ortak değerin çoğunu basitleştirir. Daha fazla ayrıntı için lütfen Proje Yapısı bölümüne bakın.

Proje oluşturulduktan sonra, önceki projede kullanılan kitaplıkları yükleyin. Eski Web Forms projelerinde, gerekli NuGet paketlerini listelemek için packages.config dosyasını kullanmış olabilirsiniz. Yeni SDK stilindeki projede packages.config dosyasının yerini <PackageReference> proje dosyasındaki öğeler almıştır. Bu yaklaşımın bir avantajı, tüm bağımlılıkların geçişli olarak yüklenmesidir. Yalnızca önemsediğiniz en üst düzey bağımlılıkları listelersiniz.

Kullandığınız bağımlılıkların birçoğu Entity Framework 6 ve log4net dahil olmak üzere .NET için kullanılabilir. Kullanılabilir .NET veya .NET Standard sürümü yoksa, .NET Framework sürümü genellikle kullanılabilir. Mesafeniz farklılık gösterebilir. .NET'te bulunmayan herhangi bir API çalışma zamanı hatasına neden olur. Visual Studio bu tür paketleri size bildirir. Çözüm Gezgini'da projenin Başvurular düğümünde sarı bir simge görüntülenir.

BlazorTabanlı eShop projesinde yüklü paketleri görebilirsiniz. Daha önce packages.config dosyası projede kullanılan her paketi listelemişti ve dosya neredeyse 50 satır uzunluğunda oluyordu. packages.config kod parçacığı:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  ...
  <package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.4.0" targetFramework="net472" />
  <package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.9.1" targetFramework="net472" />
  <package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.9.1" targetFramework="net472" />
  <package id="Microsoft.ApplicationInsights.Web" version="2.9.1" targetFramework="net472" />
  <package id="Microsoft.ApplicationInsights.WindowsServer" version="2.9.1" targetFramework="net472" />
  <package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.9.1" targetFramework="net472" />
  <package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net472" />
  <package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net472" />
  <package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net472" />
  <package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net472" />
  ...
  <package id="System.Memory" version="4.5.1" targetFramework="net472" />
  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0" targetFramework="net472" />
  <package id="System.Threading.Channels" version="4.5.0" targetFramework="net472" />
  <package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
  <package id="WebGrease" version="1.6.0" targetFramework="net472" />
</packages>

<packages> öğesi tüm gerekli bağımlılıkları içerir. Gerekli olduğundan bu paketlerden hangilerinin dahil olduğunu belirlemek zordur. Bazı <package> öğeler yalnızca ihtiyacınız olan bağımlılıkların gereksinimlerini karşılamak için listelenir.

Proje, Blazor proje dosyasındaki bir <ItemGroup> öğe içinde ihtiyacınız olan bağımlılıkları listeler:

<ItemGroup>
    <PackageReference Include="Autofac" Version="4.9.3" />
    <PackageReference Include="EntityFramework" Version="6.4.4" />
    <PackageReference Include="log4net" Version="2.0.12" />
    <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="2.2.12" />
</ItemGroup>

Web Forms geliştiricilerinin ömrünü basitleştiren bir NuGet paketi, Windows Uyumluluk Paketi'dir. .NET platformlar arası olsa da bazı özellikler yalnızca Windows'da kullanılabilir. Windows'a özgü özellikler, uyumluluk paketi yüklenerek kullanıma sunulur. Bu tür özelliklere örnek olarak Kayıt Defteri, WMI ve Dizin Hizmetleri verilebilir. Paket yaklaşık 20.000 API ekler ve zaten aşina olabileceğiniz birçok hizmeti etkinleştirir. eShop projesi uyumluluk paketini gerektirmez; ancak projeleriniz Windows'a özgü özellikler kullanıyorsa, paket geçiş çalışmalarını kolaylaştırır.

Başlangıç işlemini etkinleştirme

için Blazor başlangıç işlemi Web Forms'dan değişmiştir ve diğer ASP.NET Core hizmetleri için benzer bir kurulumu izler. Sunucu tarafında barındırıldığında Razor bileşenleri normal bir ASP.NET Core uygulamasının parçası olarak çalıştırılır. Ile tarayıcıda WebAssemblybarındırıldığında Razor bileşenleri benzer bir barındırma modeli kullanır. Aradaki fark, bileşenlerin arka uç işlemlerinden herhangi birinden ayrı bir hizmet olarak çalıştırılmasıdır. Her iki durumda da başlangıç benzerdir.

Global.asax.cs dosyası, Web Forms projeleri için varsayılan başlangıç sayfasıdır. eShop projesinde, bu dosya Denetimin Ters Çevrilmesi (IoC) kapsayıcısını yapılandırır ve uygulamanın veya isteğin çeşitli yaşam döngüsü olaylarını işler. Bu olaylardan bazıları ara yazılım (gibi Application_BeginRequest) ile işlenir. Diğer olaylar, bağımlılık ekleme (DI) yoluyla belirli hizmetlerin geçersiz kılınmalarını gerektirir.

Örneğin, eShop için Global.asax.cs dosyası aşağıdaki kodu içerir:

public class Global : HttpApplication, IContainerProviderAccessor
{
    private static readonly ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    static IContainerProvider _containerProvider;
    IContainer container;

    public IContainerProvider ContainerProvider
    {
        get { return _containerProvider; }
    }

    protected void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on app startup
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        ConfigureContainer();
        ConfigDataBase();
    }

    /// <summary>
    /// Track the machine name and the start time for the session inside the current session
    /// </summary>
    protected void Session_Start(Object sender, EventArgs e)
    {
        HttpContext.Current.Session["MachineName"] = Environment.MachineName;
        HttpContext.Current.Session["SessionStartTime"] = DateTime.Now;
    }

    /// <summary>
    /// https://autofaccn.readthedocs.io/en/latest/integration/webforms.html
    /// </summary>
    private void ConfigureContainer()
    {
        var builder = new ContainerBuilder();
        var mockData = bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);
        builder.RegisterModule(new ApplicationModule(mockData));
        container = builder.Build();
        _containerProvider = new ContainerProvider(container);
    }

    private void ConfigDataBase()
    {
        var mockData = bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);

        if (!mockData)
        {
            Database.SetInitializer<CatalogDBContext>(container.Resolve<CatalogDBInitializer>());
        }
    }

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        //set the property to our new object
        LogicalThreadContext.Properties["activityid"] = new ActivityIdHelper();

        LogicalThreadContext.Properties["requestinfo"] = new WebRequestInfo();

        _log.Debug("Application_BeginRequest");
    }
}

Yukarıdaki dosya, sunucu tarafında Program.csBlazor:

using eShopOnBlazor.Models;
using eShopOnBlazor.Models.Infrastructure;
using eShopOnBlazor.Services;
using log4net;
using System.Data.Entity;
using eShopOnBlazor;

var builder = WebApplication.CreateBuilder(args);

// add services

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

if (builder.Configuration.GetValue<bool>("UseMockData"))
{
    builder.Services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
    builder.Services.AddScoped<ICatalogService, CatalogService>();
    builder.Services.AddScoped<IDatabaseInitializer<CatalogDBContext>, CatalogDBInitializer>();
    builder.Services.AddSingleton<CatalogItemHiLoGenerator>();
    builder.Services.AddScoped(_ => new CatalogDBContext(builder.Configuration.GetConnectionString("CatalogDBContext")));
}

var app = builder.Build();

new LoggerFactory().AddLog4Net("log4Net.xml");

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}

// Middleware for Application_BeginRequest
app.Use((ctx, next) =>
{
    LogicalThreadContext.Properties["activityid"] = new ActivityIdHelper(ctx);
    LogicalThreadContext.Properties["requestinfo"] = new WebRequestInfo(ctx);
    return next();
});

app.UseStaticFiles();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});

ConfigDataBase(app);

void ConfigDataBase(IApplicationBuilder app)
{
    using (var scope = app.ApplicationServices.CreateScope())
    {
        var initializer = scope.ServiceProvider.GetService<IDatabaseInitializer<CatalogDBContext>>();

        if (initializer != null)
        {
            Database.SetInitializer(initializer);
        }
    }
}

app.Run();

Web Forms'da fark ettiğiniz önemli bir değişiklik, bağımlılık ekleme (DI) yaygınlığıdır. DI, ASP.NET Core tasarımında yol gösterici bir ilke olmuştur. ASP.NET Core çerçevesinin neredeyse tüm yönlerini özelleştirmeyi destekler. Birçok senaryo için kullanılabilecek yerleşik bir hizmet sağlayıcısı bile vardır. Daha fazla özelleştirme gerekiyorsa, birçok topluluk projesi tarafından desteklenebilir. Örneğin, üçüncü taraf DI kitaplık yatırımınızı ileriye taşıyabilirsiniz.

Özgün eShop uygulamasında oturum yönetimi için bazı yapılandırmalar vardır. Sunucu tarafı Blazor iletişim için ASP.NET Core SignalR kullandığından, bağlantılar HTTP bağlamından bağımsız olarak gerçekleşebileceğinden oturum durumu desteklenmez. Oturum durumunu kullanan bir Blazor uygulama, uygulama olarak çalıştırmadan önce yeniden oluşturmayı gerektirir.

Uygulama başlatma hakkında daha fazla bilgi için bkz . Uygulama başlatma.

HTTP modüllerini ve işleyicilerini ara yazılıma geçirme

HTTP modülleri ve işleyicileri, HTTP isteği işlem hattını denetlemek için Web Forms'daki yaygın desenlerdir. IHttpModule Kaydedilen veya uygulanabilen ve IHttpHandler gelen istekleri işleyen sınıflar. Web Forms, web.config dosyasında modülleri ve işleyicileri yapılandırıyor. Web Forms ayrıca uygulama yaşam döngüsü olay işlemeyi de temel alır. ASP.NET Core bunun yerine ara yazılımı kullanır. Ara yazılım sınıfının yöntemine Configure kaydedilirStartup. Ara yazılım yürütme sırası kayıt sırasına göre belirlenir.

Başlatma işlemini etkinleştir bölümünde, yöntem olarak Application_BeginRequest Web Forms tarafından bir yaşam döngüsü olayı oluşturuldu. Bu olay ASP.NET Core'da kullanılamaz. Bu davranışı elde etmenin bir yolu, Startup.cs dosya örneğinde görüldüğü gibi ara yazılımı uygulamaktır. Bu ara yazılım aynı mantığı yapar ve ardından denetimi ara yazılım işlem hattındaki bir sonraki işleyiciye aktarır.

Modülleri ve işleyicileri geçirme hakkında daha fazla bilgi için bkz . HTTP işleyicilerini ve modüllerini ASP.NET Core ara yazılımına geçirme.

Statik dosyaları geçirme

Statik dosyalara (html, CSS, görüntüler ve JavaScript gibi) hizmet vermek için dosyaların ara yazılım tarafından kullanıma sunulmaları gerekir. yöntemini çağırmak UseStaticFiles , statik dosyaların web kök yolundan sunulmasını sağlar. Varsayılan web kök dizini wwwroot'tur, ancak özelleştirilebilir. Program.cs dosyasına dahil edilen:

...

app.UseStaticFiles();

...

eShop projesi temel statik dosya erişimini etkinleştirir. Statik dosya erişimi için kullanılabilecek birçok özelleştirme vardır. Varsayılan dosyaları veya dosya tarayıcısını etkinleştirme hakkında bilgi için bkz . ASP.NET Core'da statik dosyalar.

Çalışma zamanı paketleme ve küçültme kurulumunu geçirme

Paketleme ve küçültme, belirli dosya türlerini almak için sunucu isteklerinin sayısını ve boyutunu azaltmaya yönelik performans iyileştirme teknikleridir. JavaScript ve CSS genellikle istemciye gönderilmeden önce bir tür paketleme veya küçültmeden geçer. ASP.NET Web Forms'da bu iyileştirmeler çalışma zamanında işlenir. İyileştirme kuralları bir App_Start/BundleConfig.cs dosyası tanımlanır. ASP.NET Core'da daha bildirim temelli bir yaklaşım benimsenir. Dosya, küçültülecek dosyaları ve belirli küçültme ayarlarını listeler.

Paketleme ve küçültme hakkında daha fazla bilgi için bkz . ASP.NET Core'da statik varlıkları paketleme ve küçültme.

ASPX sayfalarını geçirme

Web Forms uygulamasındaki bir sayfa, .aspx uzantısına sahip bir dosyadır. Web Forms sayfası genellikle içindeki Blazorbir bileşene eşlenebilir. Razor bileşeni .razor uzantısına sahip bir dosyaya yazılır. eShop projesi için beş sayfa Razor sayfasına dönüştürülür.

Örneğin, ayrıntılar görünümü Web Forms projesinde üç dosyadan oluşur: Details.aspx, Details.aspx.cs ve Details.aspx.designer.cs. öğesine dönüştürülürkenBlazor, arka planda kod ve işaretleme Details.razor olarak birleştirilir. Razor derlemesi (.designer.cs dosyalarındakiyle eşdeğerdir) obj dizininde depolanır ve varsayılan olarak Çözüm Gezgini'de görüntülenemez. Web Forms sayfası aşağıdaki işaretlemelerden oluşur:

<%@ Page Title="Details" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Details.aspx.cs" Inherits="eShopLegacyWebForms.Catalog.Details" %>

<asp:Content ID="Details" ContentPlaceHolderID="MainContent" runat="server">
    <h2 class="esh-body-title">Details</h2>

    <div class="container">
        <div class="row">
            <asp:Image runat="server" CssClass="col-md-6 esh-picture" ImageUrl='<%#"/Pics/" + product.PictureFileName%>' />
            <dl class="col-md-6 dl-horizontal">
                <dt>Name
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.Name%>' />
                </dd>

                <dt>Description
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.Description%>' />
                </dd>

                <dt>Brand
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.CatalogBrand.Brand%>' />
                </dd>

                <dt>Type
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.CatalogType.Type%>' />
                </dd>
                <dt>Price
                </dt>

                <dd>
                    <asp:Label CssClass="esh-price" runat="server" Text='<%#product.Price%>' />
                </dd>

                <dt>Picture name
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.PictureFileName%>' />
                </dd>

                <dt>Stock
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.AvailableStock%>' />
                </dd>

                <dt>Restock
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.RestockThreshold%>' />
                </dd>

                <dt>Max stock
                </dt>

                <dd>
                    <asp:Label runat="server" Text='<%#product.MaxStockThreshold%>' />
                </dd>

            </dl>
        </div>

        <div class="form-actions no-color esh-link-list">
            <a runat="server" href='<%# GetRouteUrl("EditProductRoute", new {id =product.Id}) %>' class="esh-link-item">Edit
            </a>
            |
            <a runat="server" href="~" class="esh-link-item">Back to list
            </a>
        </div>

    </div>
</asp:Content>

Yukarıdaki işaretlemenin arka planında aşağıdaki kod bulunur:

using eShopLegacyWebForms.Models;
using eShopLegacyWebForms.Services;
using log4net;
using System;
using System.Web.UI;

namespace eShopLegacyWebForms.Catalog
{
    public partial class Details : System.Web.UI.Page
    {
        private static readonly ILog _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        protected CatalogItem product;

        public ICatalogService CatalogService { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            var productId = Convert.ToInt32(Page.RouteData.Values["id"]);
            _log.Info($"Now loading... /Catalog/Details.aspx?id={productId}");
            product = CatalogService.FindCatalogItem(productId);

            this.DataBind();
        }
    }
}

uygulamasına Blazordönüştürüldüğünde, Web Forms sayfası aşağıdaki koda çevrilir:

@page "/Catalog/Details/{id:int}"
@inject ICatalogService CatalogService
@inject ILogger<Details> Logger

<h2 class="esh-body-title">Details</h2>

<div class="container">
    <div class="row">
        <img class="col-md-6 esh-picture" src="@($"/Pics/{_item.PictureFileName}")">

        <dl class="col-md-6 dl-horizontal">
            <dt>
                Name
            </dt>

            <dd>
                @_item.Name
            </dd>

            <dt>
                Description
            </dt>

            <dd>
                @_item.Description
            </dd>

            <dt>
                Brand
            </dt>

            <dd>
                @_item.CatalogBrand.Brand
            </dd>

            <dt>
                Type
            </dt>

            <dd>
                @_item.CatalogType.Type
            </dd>
            <dt>
                Price
            </dt>

            <dd>
                @_item.Price
            </dd>

            <dt>
                Picture name
            </dt>

            <dd>
                @_item.PictureFileName
            </dd>

            <dt>
                Stock
            </dt>

            <dd>
                @_item.AvailableStock
            </dd>

            <dt>
                Restock
            </dt>

            <dd>
                @_item.RestockThreshold
            </dd>

            <dt>
                Max stock
            </dt>

            <dd>
                @_item.MaxStockThreshold
            </dd>

        </dl>
    </div>

    <div class="form-actions no-color esh-link-list">
        <a href="@($"/Catalog/Edit/{_item.Id}")" class="esh-link-item">
            Edit
        </a>
        |
        <a href="/" class="esh-link-item">
            Back to list
        </a>
    </div>

</div>

@code {
    private CatalogItem _item;

    [Parameter]
    public int Id { get; set; }

    protected override void OnInitialized()
    {
        Logger.LogInformation("Now loading... /Catalog/Details/{Id}", Id);

        _item = CatalogService.FindCatalogItem(Id);
    }
}

Kod ve işaretlemenin aynı dosyada olduğuna dikkat edin. Gerekli hizmetler özniteliğiyle @inject erişilebilir hale getirilir. Yönergeye @page göre bu sayfaya rotadan Catalog/Details/{id} erişilebilir. Yolun {id} yer tutucusunun değeri bir tamsayıyla kısıtlandı. Yönlendirme bölümünde açıklandığı gibi, Web Forms'un aksine, razor bileşeni rotasını ve dahil edilen parametreleri açıkça belirtir. Birçok Web Forms denetiminin içinde Blazortam karşılıkları olmayabilir. Genellikle aynı amaca hizmet edecek eşdeğer bir HTML kod parçacığı vardır. Örneğin, <asp:Label /> denetim bir HTML <label> öğesiyle değiştirilebilir.

'da model doğrulama Blazor

Web Forms kodunuz doğrulama içeriyorsa, çok az veya hiç değişiklik olmadan sahip olduğunuz verilerin çoğunu aktarabilirsiniz. içinde Blazor çalıştırmanın bir avantajı, aynı doğrulama mantığının özel JavaScript'e gerek kalmadan çalıştırılabilmesidir. Veri ek açıklamaları, model doğrulamayı kolaylaştırır.

Örneğin, Create.aspx sayfasında doğrulama içeren bir veri giriş formu vardır. Örnek bir kod parçacığı şöyle görünür:

<div class="form-group">
    <label class="control-label col-md-2">Name</label>
    <div class="col-md-3">
        <asp:TextBox ID="Name" runat="server" CssClass="form-control"></asp:TextBox>
        <asp:RequiredFieldValidator runat="server" ControlToValidate="Name" Display="Dynamic"
            CssClass="field-validation-valid text-danger" ErrorMessage="The Name field is required." />
    </div>
</div>

içindeBlazor, eşdeğer işaretleme create.razor dosyasında sağlanır:

<EditForm Model="_item" OnValidSubmit="@...">
    <DataAnnotationsValidator />

    <div class="form-group">
        <label class="control-label col-md-2">Name</label>
        <div class="col-md-3">
            <InputText class="form-control" @bind-Value="_item.Name" />
            <ValidationMessage For="(() => _item.Name)" />
        </div>
    </div>

    ...
</EditForm>

Bağlam EditForm , doğrulama desteğini içerir ve bir girişin çevresinde sarmalanabilir. Veri ek açıklamaları doğrulama eklemenin yaygın bir yoludur. Bu tür doğrulama desteği bileşen aracılığıyla DataAnnotationsValidator eklenebilir. Bu mekanizma hakkında daha fazla bilgi için bkz . ASP.NET Temel Blazor formlar ve doğrulama.

Yapılandırmayı geçirme

Web Forms projesinde yapılandırma verileri en yaygın olarak web.config dosyasında depolanır. Yapılandırma verilerine ile ConfigurationManagererişilir. Nesneleri ayrıştırmak için genellikle hizmetler gerekiyordu. .NET Framework 4.7.2 ile, oluşturma özelliği aracılığıyla ConfigurationBuildersyapılandırmaya eklendi. Bu oluşturucular, geliştiricilerin gerekli değerleri almak için çalışma zamanında oluşturulan yapılandırma için çeşitli kaynaklar eklemesine izin verdi.

ASP.NET Core, uygulamanız ve dağıtımınız tarafından kullanılan yapılandırma kaynağını veya kaynaklarını tanımlamanızı sağlayan esnek bir yapılandırma sistemi kullanıma sunulmuştur. ConfigurationBuilder Web Forms uygulamanızda kullanıyor olabileceğiniz altyapı, ASP.NET Core yapılandırma sisteminde kullanılan kavramlar sonrasında modellenmiştir.

Aşağıdaki kod parçacığı, Web Forms eShop projesinin yapılandırma değerlerini depolamak için web.config'i nasıl kullandığını gösterir:

<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="CatalogDBContext" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated Security=True; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="UseMockData" value="true" />
    <add key="UseCustomizationData" value="false" />
  </appSettings>
</configuration>

Veritabanı bağlantı dizesi gibi gizli dizilerin web.config içinde depolanması yaygın bir durumdur. Gizli diziler, kaynak denetimi gibi güvenli olmayan konumlarda kaçınılmaz olarak kalıcı hale gelir. Blazor ASP.NET Core'da, önceki XML tabanlı yapılandırma aşağıdaki JSON ile değiştirilir:

{
  "ConnectionStrings": {
    "CatalogDBContext": "Data Source=(localdb)\\MSSQLLocalDB; Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated Security=True; MultipleActiveResultSets=True;"
  },
  "UseMockData": true,
  "UseCustomizationData": false
}

JSON varsayılan yapılandırma biçimidir; ancak ASP.NET Core, XML dahil olmak üzere diğer birçok biçimi destekler. Topluluk tarafından desteklenen çeşitli biçimler de vardır.

Yapılandırma değerlerine oluşturucudan Program.cs erişebilirsiniz:

if (builder.Configuration.GetValue<bool>("UseMockData"))
{
    builder.Services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
    builder.Services.AddScoped<ICatalogService, CatalogService>();
    builder.Services.AddScoped<IDatabaseInitializer<CatalogDBContext>, CatalogDBInitializer>();
    builder.Services.AddSingleton<CatalogItemHiLoGenerator>();
    builder.Services.AddScoped(_ => new CatalogDBContext(builder.Configuration.GetConnectionString("CatalogDBContext")));
}

Varsayılan olarak, ortam değişkenleri, JSON dosyaları (appsettings.json ve uygulama ayarları.{ Environment}.json) ve komut satırı seçenekleri yapılandırma nesnesine geçerli yapılandırma kaynakları olarak kaydedilir. Yapılandırma kaynaklarına aracılığıyla Configuration[key]erişilebilir. Daha gelişmiş bir teknik, yapılandırma verilerini seçenekler desenini kullanarak nesnelere bağlamaktır. Yapılandırma ve seçenekler deseni hakkında daha fazla bilgi için bkz . ASP.NET Core'da yapılandırma ve ASP.NET Core'da Seçenekler düzeni.

Veri erişimini geçirme

Veri erişimi, herhangi bir uygulamanın önemli bir yönüdür. eShop projesi katalog bilgilerini bir veritabanında depolar ve Entity Framework (EF) 6 ile verileri alır. EF 6 .NET 5'te desteklendiğinden, proje bunu kullanmaya devam edebilir.

eShop'ta EF ile ilgili aşağıdaki değişiklikler gerekliydi:

  • .NET Framework'te nesnesi nameDbContext=ConnectionString form dizesini kabul eder ve bağlanmak için öğesinden ConfigurationManager.AppSettings[ConnectionString] bağlantı dizesi kullanır. .NET Core'da bu desteklenmez. bağlantı dizesi sağlanmalıdır.
  • Veritabanına zaman uyumlu bir şekilde erişildi. Bu işe yarasa da ölçeklenebilirlik olumsuz etkilenebilir. Bu mantık zaman uyumsuz bir desene taşınmalıdır.

Veri kümesi bağlama için aynı yerel destek olmasa da Razor Blazor sayfasında C# desteğiyle esneklik ve güç sağlar. Örneğin, hesaplamalar yapabilir ve sonucu görüntüleyebilirsiniz. içindeki Blazorveri desenleri hakkında daha fazla bilgi için Veri erişimi bölümüne bakın.

Mimari değişiklikler

Son olarak, 'a Blazorgeçiş yaparken dikkate alınması gereken bazı önemli mimari farklılıklar vardır. Bu değişikliklerin çoğu .NET Core veya ASP.NET Core tabanlı her şey için geçerlidir.

Blazor.NET Core üzerinde oluşturulduğundan, .NET Core'da destek sağlanmasında dikkat edilmesi gereken noktalar vardır. Önemli değişikliklerden bazıları aşağıdaki özelliklerin kaldırılmasını içerir:

  • Birden Çok AppDomains
  • uzaktan iletişim
  • Kod Erişimi Güvenliği (CAS)
  • Güvenlik Saydamlığı

.NET Core üzerinde çalıştırmayı desteklemek için gerekli değişiklikleri belirleme teknikleri hakkında daha fazla bilgi için bkz . Kodunuzu .NET Framework'ten .NET Core'a taşıma.

ASP.NET Core, ASP.NET'nin yeniden tasarlanan bir sürümüdür ve başlangıçta belirgin görünmeyecek bazı değişikliklere sahiptir. Ana değişiklikler şunlardır:

  • Eşitleme bağlamı yok; başka bir deyişle , HttpContext.Currentveya başka statik erişimciler yok Thread.CurrentPrincipal
  • Gölge kopyalama yok
  • İstek kuyruğu yok

ASP.NET Core'daki birçok işlem zaman uyumsuz olup G/Ç'ye bağlı görevlerin daha kolay yüklenmesini sağlar. İş parçacığı havuzu kaynaklarını hızla tüketebilen veya Task.Wait()kullanarak Task.GetResult() hiçbir zaman engellememek önemlidir.

Geçiş sonucu

Bu noktada, bir Web Forms projesini uygulamasına taşımak için gerekenlerin birçok örneğini Blazorgördünüz. Tam bir örnek için bkz . eShopOnBlazor projesi.