ASP.NET Core'da uygulama modeliyle çalışma

Tarafından Steve Smith

ASP.NET Core MVC, bir MVC uygulamasının bileşenlerini temsil eden bir uygulama modeli tanımlar. MVC öğelerinin davranışını değiştirmek için bu modeli okuyun ve değiştirin. Varsayılan olarak, MVC hangi sınıfların denetleyici olarak kabul edildiğini, bu sınıflardaki yöntemlerin eylemler olduğunu ve parametrelerin ve yönlendirmenin nasıl davrandığını belirlemek için belirli kuralları izler. Özel kurallar oluşturup bunları genel olarak veya öznitelik olarak uygulayarak bu davranışı bir uygulamanın gereksinimlerine uyacak şekilde özelleştirin.

Modeller ve Sağlayıcılar (IApplicationModelProvider)

ASP.NET Core MVC uygulama modeli, bir MVC uygulamasını açıklayan soyut arabirimleri ve somut uygulama sınıflarını içerir. Bu model, MVC'nin uygulamanın denetleyicilerini, eylem parametrelerini, yollarını ve filtrelerini varsayılan kurallar doğrultusunda bulmasının sonucudur. Uygulama modeliyle çalışarak, bir uygulamayı varsayılan MVC davranışından farklı kuralları izleyecek şekilde değiştirin. Parametreler, adlar, yollar ve filtrelerin tümü eylemler ve denetleyiciler için yapılandırma verileri olarak kullanılır.

ASP.NET Core MVC Uygulama Modeli aşağıdaki yapıya sahiptir:

  • ApplicationModel
    • Denetleyiciler (ControllerModel)
      • Eylemler (ActionModel)
        • Parametreler (ParameterModel)

Modelin her düzeyinin ortak Properties bir koleksiyona erişimi vardır ve alt düzeyler hiyerarşideki daha yüksek düzeyler tarafından ayarlanan özellik değerlerine erişebilir ve bunların üzerine yazabilir. Eylemler oluşturulduğunda özellikleri kalıcı ActionDescriptor.Properties hale eklenir. Ardından bir istek işlenirken, bir kuralın eklendiği veya değiştirildiği tüm özelliklere aracılığıyla ActionContext.ActionDescriptorerişilebilir. Özelliklerin kullanılması, filtreleri, model bağlayıcılarını ve diğer uygulama modeli yönlerini eylem temelinde yapılandırmanın harika bir yoludur.

Dekont

Koleksiyon ActionDescriptor.Properties , uygulama başlatıldıktan sonra iş parçacığı güvenli değildir (yazma işlemleri için). Kurallar, bu koleksiyona güvenli bir şekilde veri eklemenin en iyi yoludur.

ASP.NET Core MVC, arabirim tarafından IApplicationModelProvider tanımlanan bir sağlayıcı deseni kullanarak uygulama modelini yükler. Bu bölüm, bu sağlayıcının nasıl çalıştığını gösteren iç uygulama ayrıntılarından bazılarını kapsar. Sağlayıcı deseninin kullanımı, öncelikli olarak çerçeve kullanımı için gelişmiş bir konudur. Çoğu uygulama sağlayıcı desenini değil kuralları kullanmalıdır.

IApplicationModelProvider Her uygulamanın özelliğine göre artan düzende çağırdığı OnProvidersExecuting arabiriminin uygulamaları birbirini "sarmalarOrder". Yöntemi OnProvidersExecuted daha sonra ters sırada çağrılır. Çerçeve çeşitli sağlayıcılar tanımlar:

İlk (Order=-1000):

  • DefaultApplicationModelProvider

Ardından (Order=-990):

  • AuthorizationApplicationModelProvider
  • CorsApplicationModelProvider

Dekont

için aynı değere Order sahip iki sağlayıcının çağrılma sırası tanımlanmamıştır ve bunlara güvenilmemelidir.

Dekont

IApplicationModelProvider , çerçeve yazarlarının genişletecekleri gelişmiş bir kavramdır. Genel olarak, uygulamalar kuralları, çerçeveler ise sağlayıcılar kullanmalıdır. Önemli fark, sağlayıcıların her zaman kurallardan önce çalışmasıdır.

, DefaultApplicationModelProvider ASP.NET Core MVC tarafından kullanılan varsayılan davranışların çoğunu oluşturur. Sorumlulukları şunlardır:

  • Bağlama genel filtreler ekleme
  • Bağlama denetleyici ekleme
  • Genel denetleyici yöntemlerini eylem olarak ekleme
  • Bağlama eylem yöntemi parametreleri ekleme
  • Yol ve diğer öznitelikleri uygulama

Bazı yerleşik davranışlar tarafından DefaultApplicationModelProvideruygulanır. Bu sağlayıcı, , ve ParameterModel örneklerine başvuran PropertyModelActionModelöğesini oluşturmakla ControllerModelsorumludur. sınıfı DefaultApplicationModelProvider , gelecekte değişebilecek bir iç çerçeve uygulama ayrıntısıdır.

AuthorizationApplicationModelProvider ve AllowAnonymousFilter öznitelikleriyle ilişkili davranışın uygulanmasından AuthorizeFilter sorumludur. Daha fazla bilgi için bkz . ASP.NET Core'da basit yetkilendirme.

ve CorsApplicationModelProviderIDisableCorsAttributeile IEnableCorsAttribute ilişkili davranışı uygular. Daha fazla bilgi için bkz . ASP.NET Core'da Çıkış Noktaları Arası İstekleri (CORS) Etkinleştirme.

Bu bölümde açıklanan çerçevenin iç sağlayıcılarıyla ilgili bilgiler .NET API tarayıcısı aracılığıyla kullanılamaz. Ancak sağlayıcılar ASP.NET Core başvuru kaynağında (dotnet/aspnetcore GitHub deposu) incelenebilir. Sağlayıcıları ada göre bulmak için GitHub aramasını kullanın ve Dalları/etiketleri değiştir açılan listesiyle kaynağın sürümünü seçin.

Kurallar

Uygulama modeli, modellerin davranışını özelleştirmek için modelin veya sağlayıcının tamamını geçersiz kılmaya kıyasla daha basit bir yol sağlayan kural soyutlamalarını tanımlar. Bu soyutlamalar, bir uygulamanın davranışını değiştirmenin önerilen yoludur. Kurallar, özelleştirmeleri dinamik olarak uygulayan bir kod yazma yolu sağlar. Filtreler çerçevenin davranışını değiştirmenin bir aracı olsa da, özelleştirmeler tüm uygulamanın birlikte nasıl çalıştığı üzerinde denetime izin verir.

Aşağıdaki kurallar kullanılabilir:

Kurallar, MVC seçeneklerine eklenerek veya öznitelikler uygulanarak ve denetleyicilere, eylemlere veya eylem parametrelerine (filtrelere benzer) uygulanarak uygulanır. Filtrelerden farklı olarak, kurallar yalnızca uygulama başlatıldığında yürütülür, her isteğin parçası olarak yürütülemez.

Dekont

Sayfalar rotası ve uygulama modeli sağlayıcısı kuralları hakkında Razor bilgi için bkz Razor . ASP.NET Core'da Sayfalar yolu ve uygulama kuralları.

ApplicationModel

Uygulama modeline özellik eklemek için aşağıdaki kural kullanılır:

using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace AppModelSample.Conventions
{
    public class ApplicationDescription : IApplicationModelConvention
    {
        private readonly string _description;

        public ApplicationDescription(string description)
        {
            _description = description;
        }

        public void Apply(ApplicationModel application)
        {
            application.Properties["description"] = _description;
        }
    }
}

Uygulama modeli kuralları, içinde MVC eklendiğinde Startup.ConfigureServicesseçenek olarak uygulanır:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Conventions.Add(new ApplicationDescription("My Application Description"));
        options.Conventions.Add(new NamespaceRoutingConvention());
    });
}

Özelliklere denetleyici eylemleri içinde ActionDescriptor.Properties koleksiyondan erişilebilir:

public class AppModelController : Controller
{
    public string Description()
    {
        return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
    }
}

Açıklamayı ControllerModel değiştirme

Denetleyici modeli özel özellikler de içerebilir. Özel özellikler, uygulama modelinde belirtilen aynı ada sahip mevcut özellikleri geçersiz kılar. Aşağıdaki kural özniteliği denetleyici düzeyinde bir açıklama ekler:

using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace AppModelSample.Conventions
{
    public class ControllerDescriptionAttribute : Attribute, IControllerModelConvention
    {
        private readonly string _description;

        public ControllerDescriptionAttribute(string description)
        {
            _description = description;
        }

        public void Apply(ControllerModel controllerModel)
        {
            controllerModel.Properties["description"] = _description;
        }
    }
}

Bu kural bir denetleyiciye öznitelik olarak uygulanır:

[ControllerDescription("Controller Description")]
public class DescriptionAttributesController : Controller
{
    public string Index()
    {
        return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
    }

Açıklamayı ActionModel değiştirme

Ayrı bir öznitelik kuralı, uygulama veya denetleyici düzeyinde zaten uygulanmış olan davranışı geçersiz kılarak tek tek eylemlere uygulanabilir:

using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace AppModelSample.Conventions
{
    public class ActionDescriptionAttribute : Attribute, IActionModelConvention
    {
        private readonly string _description;

        public ActionDescriptionAttribute(string description)
        {
            _description = description;
        }

        public void Apply(ActionModel actionModel)
        {
            actionModel.Properties["description"] = _description;
        }
    }
}

Bunu denetleyici içindeki bir eyleme uygulamak, denetleyici düzeyi kuralını nasıl geçersiz kıldığını gösterir:

[ControllerDescription("Controller Description")]
public class DescriptionAttributesController : Controller
{
    public string Index()
    {
        return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
    }

    [ActionDescription("Action Description")]
    public string UseActionDescriptionAttribute()
    {
        return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
    }
}

ParameterModel

Aşağıdaki kural eylem parametrelerine uygulanarak bunları BindingInfodeğiştirebilir. Aşağıdaki kural parametresinin bir yol parametresi olmasını gerektirir. Sorgu dizesi değerleri gibi diğer olası bağlama kaynakları yoksayılır:

using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace AppModelSample.Conventions
{
    public class MustBeInRouteParameterModelConvention : Attribute, IParameterModelConvention
    {
        public void Apply(ParameterModel model)
        {
            if (model.BindingInfo == null)
            {
                model.BindingInfo = new BindingInfo();
            }
            model.BindingInfo.BindingSource = BindingSource.Path;
        }
    }
}

Özniteliği herhangi bir eylem parametresine uygulanabilir:

public class ParameterModelController : Controller
{
    // Will bind:  /ParameterModel/GetById/123
    // WON'T bind: /ParameterModel/GetById?id=123
    public string GetById([MustBeInRouteParameterModelConvention]int id)
    {
        return $"Bound to id: {id}";
    }
}

Kuralı tüm eylem parametrelerine uygulamak için öğesine ekleyin MustBeInRouteParameterModelConventionMvcOptionsStartup.ConfigureServices:

options.Conventions.Add(new MustBeInRouteParameterModelConvention());

ActionModel Adı değiştirme

Aşağıdaki kural, ActionModel uygulandığı eylemin adını güncelleştirmek için öğesini değiştirir. Yeni ad, özniteliğine bir parametre olarak sağlanır. Bu yeni ad yönlendirme tarafından kullanıldığından, bu eylem yöntemine ulaşmak için kullanılan yolu etkiler:

using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace AppModelSample.Conventions
{
    public class CustomActionNameAttribute : Attribute, IActionModelConvention
    {
        private readonly string _actionName;

        public CustomActionNameAttribute(string actionName)
        {
            _actionName = actionName;
        }

        public void Apply(ActionModel actionModel)
        {
            // this name will be used by routing
            actionModel.ActionName = _actionName;
        }
    }
}

Bu öznitelik içindeki bir eylem yöntemine HomeControlleruygulanır:

// Route: /Home/MyCoolAction
[CustomActionName("MyCoolAction")]
public string SomeName()
{
    return ControllerContext.ActionDescriptor.ActionName;
}

Yöntem adı olsa SomeNameda, özniteliği yöntem adını kullanarak MVC kuralını geçersiz kılar ve eylem adını ile MyCoolActiondeğiştirir. Bu nedenle, bu eyleme ulaşmak için kullanılan yol şeklindedir /Home/MyCoolAction.

Dekont

Bu bölümdeki bu örnek temelde yerleşik ActionNameAttribute'in kullanımıyla aynıdır.

Özel yönlendirme kuralı

Yönlendirmenin nasıl çalıştığını özelleştirmek için bir IApplicationModelConvention kullanın. Örneğin, aşağıdaki kural denetleyicilerin ad alanlarını kendi yollarına dahil eder . ve ad alanında öğesini yolunda ile / değiştirir:

using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System.Linq;

namespace AppModelSample.Conventions
{
    public class NamespaceRoutingConvention : IApplicationModelConvention
    {
        public void Apply(ApplicationModel application)
        {
            foreach (var controller in application.Controllers)
            {
                var hasAttributeRouteModels = controller.Selectors
                    .Any(selector => selector.AttributeRouteModel != null);

                if (!hasAttributeRouteModels
                    && controller.ControllerName.Contains("Namespace")) // affect one controller in this sample
                {
                    // Replace the . in the namespace with a / to create the attribute route
                    // Ex: MySite.Admin namespace will correspond to MySite/Admin attribute route
                    // Then attach [controller], [action] and optional {id?} token.
                    // [Controller] and [action] is replaced with the controller and action
                    // name to generate the final template
                    controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
                    {
                        Template = controller.ControllerType.Namespace.Replace('.', '/') + "/[controller]/[action]/{id?}"
                    };
                }
            }

            // You can continue to put attribute route templates for the controller actions depending on the way you want them to behave
        }
    }
}

Kural, içinde Startup.ConfigureServicesbir seçenek olarak eklenir:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Conventions.Add(new ApplicationDescription("My Application Description"));
        options.Conventions.Add(new NamespaceRoutingConvention());
    });
}

Bahşiş

Aşağıdaki yaklaşımı kullanarak ara yazılımaMvcOptions kurallar ekleyin. Yer {CONVENTION} tutucu, eklenecek kuraldır:

services.Configure<MvcOptions>(c => c.Conventions.Add({CONVENTION}));

Aşağıdaki örnek, denetleyicinin Namespace adında bulunduğu öznitelik yönlendirmesini kullanmayan yollara bir kural uygular:

using Microsoft.AspNetCore.Mvc;

namespace AppModelSample.Controllers
{
    public class NamespaceRoutingController : Controller
    {
        // using NamespaceRoutingConvention
        // route: /AppModelSample/Controllers/NamespaceRouting/Index
        public string Index()
        {
            return "This demonstrates namespace routing.";
        }
    }
}

uygulamasında uygulama modeli kullanımı WebApiCompatShim

ASP.NET Core MVC, ASP.NET Web API 2'den farklı bir kural kümesi kullanır. Özel kuralları kullanarak, ASP.NET Core MVC uygulamasının davranışını web API'sinin davranışıyla tutarlı olacak şekilde değiştirebilirsiniz. Microsoft, NuGet paketini bu amaçla özel olarak sunar.WebApiCompatShim

Dekont

ASP.NET Web API'sinden geçiş hakkında daha fazla bilgi için bkz . ASP.NET Web API'sinden ASP.NET Core'a geçiş.

Web API Uyumluluğu Dolgusunu kullanmak için:

  • Microsoft.AspNetCore.Mvc.WebApiCompatShim Paketi projeye ekleyin.
  • içinde arayarak AddWebApiConventions kuralları MVC'ye Startup.ConfigureServicesekleyin:
services.AddMvc().AddWebApiConventions();

Dolgu tarafından sağlanan kurallar yalnızca uygulamanın belirli öznitelikleri uygulanmış olan bölümlerine uygulanır. Aşağıdaki dört öznitelik, hangi denetleyicilerin kurallarını dolgu kurallarına göre değiştirmesi gerektiğini denetlemek için kullanılır:

Eylem kuralları

UseWebApiActionConventionsAttribute , HTTP yöntemini adlarına göre eylemlerle eşlemek için kullanılır (örneğin, Get ile HttpGeteşler). Yalnızca öznitelik yönlendirme kullanmayan eylemler için geçerlidir.

Aşırı Yükleme

UseWebApiOverloadingAttribute kuralı uygulamak WebApiOverloadingApplicationModelConvention için kullanılır. Bu kural, isteğe bağlı olmayan tüm parametreleri karşılayan aday eylemlerini sınırlayan eylem seçimi işlemine bir OverloadActionConstraint ekler.

Parametre kuralları

UseWebApiParameterConventionsAttribute eylem kuralını uygulamak WebApiParameterConventionsApplicationModelConvention için kullanılır. Bu kural, eylem parametresi olarak kullanılan basit türlerin varsayılan olarak URI'den, karmaşık türlerin ise istek gövdesinden bağlandığını belirtir.

Rotalar

UseWebApiRoutesAttribute denetleyici kuralının WebApiApplicationModelConvention uygulanıp uygulanmadığını denetler. Etkinleştirildiğinde, bu kural rotaya alanlar için destek eklemek için kullanılır ve denetleyicinin alanda api olduğunu gösterir.

Uyumluluk paketi, bir dizi kurala ek olarak, web API'sinin sağladığının yerini alan bir System.Web.Http.ApiController temel sınıf içerir. Bu, web API'sine yazılan ve öğesinden ApiController devralan web API denetleyicilerinizin ASP.NET Core MVC üzerinde çalışırken çalışmasını sağlar. UseWebApi* Daha önce listelenen tüm öznitelikler temel denetleyici sınıfına uygulanır. , web API'sinde ApiController bulunanlarla uyumlu özellikleri, yöntemleri ve sonuç türlerini kullanıma sunar.

Bir uygulamayı belgeleyemek için kullanma ApiExplorer

Uygulama modeli, uygulamanın yapısından geçiş yapmak için kullanılabilecek her düzeyde bir ApiExplorerModel özellik kullanıma sunar. Bu, Swagger gibi araçları kullanarak web API'leri için yardım sayfaları oluşturmak için kullanılabilir. özelliği, ApiExplorer uygulama modelinin hangi bölümlerinin kullanıma sunulacak olduğunu belirtmek için ayarlanabilen bir IsVisible özelliği kullanıma sunar. Bu ayarı bir kural kullanarak yapılandırın:

using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace AppModelSample.Conventions
{
    public class EnableApiExplorerApplicationConvention : IApplicationModelConvention
    {
        public void Apply(ApplicationModel application)
        {
            application.ApiExplorer.IsVisible = true;
        }
    }
}

Bu yaklaşımı (ve gerekirse ek kuralları) kullanarak API görünürlüğü bir uygulama içindeki herhangi bir düzeyde etkinleştirilir veya devre dışı bırakılır.