ASP.NET Core'da Model Bağlama

Bu makalede model bağlamanın ne olduğu, nasıl çalıştığını ve davranışını özelleştirme açıklanmıştır.

Örnek kodu görüntüleme veya indirme (indirme).

Model bağlama nedir?

Denetleyiciler Razor ve sayfalar HTTP isteklerinden gelen verilerle çalışır. Örneğin, yol verileri bir kayıt anahtarı sağlarken, gönderilen form alanları modelin özellikleri için değerler sağlar. Bu değerlerin her biri için kod yazmak ve bunları dizelerden .NET türlerine dönüştürmek sıkıcı ve hataya açık olabilir. Model bağlaması bu işlemi otomatik hale gösterir. Model bağlama sistemi:

  • Rota verileri, form alanları ve sorgu dizeleri gibi çeşitli kaynaklardan veri alınır.
  • Yöntem parametrelerinde ve genel Razor özelliklerde denetleyicilere ve sayfalara verileri sağlar.
  • Dize verilerini .NET türlerine dönüştürür.
  • Karmaşık türlerin özelliklerini güncelleştirme.

Örnek

Aşağıdaki eylem yöntemine sahip olduğunu varsayalım:

[HttpGet("{id}")]
public ActionResult<Pet> GetById(int id, bool dogsOnly)

Uygulama da şu URL'yi kullanarak bir istek alır:

http://contoso.com/api/pets/2?DogsOnly=true

Model bağlaması, yönlendirme sistemi eylem yöntemini seçdikten sonra aşağıdaki adımlardan geçmektedir:

  • adlı tamsayının GetById ilk parametresini id bulur.
  • HTTP isteğinde kullanılabilir kaynakları bulur ve rota verisinde id = "2" bulur.
  • "2" dizesini tamsayı 2'ye dönüştürür.
  • adlı bir GetById boolean olan sonraki parametresini dogsOnly bulur.
  • Kaynaklara bakarak sorgu dizesinde "DogsOnly=true" ifadesini bulur. Ad eşleştirme büyük/büyük/büyük harfe duyarlı değildir.
  • "true" dizesini boole değerine true dönüştürür.

Ardından çerçeve yöntemini GetById çağırarak parametresi için 2 ve id true parametresini dogsOnly iletir.

Önceki örnekte model bağlama hedefleri, basit türler olan yöntem parametreleridir. Hedefler karmaşık bir türün özellikleri de olabilir. Her özellik başarıyla bağlandıktan sonra, bu özellik için model doğrulaması gerçekleşir. Modele bağlı verilerin kaydı ve bağlama veya doğrulama hataları ControllerBase.ModelState veya PageModel.ModelState içinde depolanır. Uygulama, bu işlemi başarıyla tamamlasa da ModelState.IsValid bayrağını denetler.

Targets

Model bağlaması aşağıdaki hedef türleri için değerleri bulmaya çalışır:

  • Bir isteğin yönlendirilen denetleyici eylem yönteminin parametreleri.
  • Bir isteğin Razor yönlendirilen Pages işleyicisi yönteminin parametreleri.
  • Öznitelikler tarafından PageModel belirtilirse, bir denetleyicinin veya sınıfın genel özellikleri.

[BindProperty] özniteliği

Model bağlamanın bu özelliği hedeflemesi için bir denetleyicinin PageModel veya sınıfın genel özelliğine uygulanabilir:

public class EditModel : InstructorsPageModel
{
    [BindProperty]
    public Instructor Instructor { get; set; }

[BindProperties] özniteliği

2.1 ve ASP.NET Core'da kullanılabilir. Model bağlamanın sınıfın tüm genel özelliklerini hedeflemesi için bir PageModel denetleyiciye veya sınıfa uygulanabilir:

[BindProperties(SupportsGet = true)]
public class CreateModel : InstructorsPageModel
{
    public Instructor Instructor { get; set; }

HTTP GET istekleri için model bağlama

Varsayılan olarak, özellikler HTTP GET isteklerine bağlı değildir. Genellikle GET isteği için tek ihtiyacınız olan kayıt kimliği parametresidir. Kayıt kimliği, veritabanındaki öğeyi aray için kullanılır. Bu nedenle, modelin bir örneğini tutan bir özelliği bağlamaya gerek yoktur. GET isteklerinden verilere bağlı özellikler istediğiniz senaryolarda özelliğini olarak SupportsGet true ayarlayın:

[BindProperty(Name = "ai_user", SupportsGet = true)]
public string ApplicationInsightsCookie { get; set; }

Kaynaklar

Varsayılan olarak, model bağlama verileri http isteğinde aşağıdaki kaynaklardan anahtar-değer çiftleri şeklinde alır:

  1. Form alanları
  2. İstek gövdesi ([ApiController] özniteliğine sahip denetleyiciler için.)
  3. Veri yönlendirme
  4. Sorgu dizesi parametreleri
  5. Karşıya yüklenen dosyalar

Her hedef parametre veya özellik için kaynaklar, önceki listede belirtilen sırada taranır. Birkaç özel durum vardır:

  • Rota verileri ve sorgu dizesi değerleri yalnızca basit türler için kullanılır.
  • Karşıya yüklenen dosyalar yalnızca veya uygulayan hedef türlere IFormFile IEnumerable<IFormFile> bağımlıdır.

Varsayılan kaynak doğru değilse, kaynağı belirtmek için aşağıdaki özniteliklerden birini kullanın:

  • [FromQuery] - Sorgu dizesinde yer alan değerleri alır.
  • [FromRoute] - Rota verilerinden değerleri alır.
  • [FromForm] - Gönderilen form alanlarından değerleri alır.
  • [FromBody] - İstek gövdesinden değerleri alır.
  • [FromHeader] - HTTP üst bilgilerinden değerleri alır.

Bu öznitelikler:

  • Aşağıdaki örnekte olduğu gibi model özelliklerine tek tek eklenir (model sınıfına eklenmez):

    public class Instructor
    {
        public int ID { get; set; }
    
        [FromQuery(Name = "Note")]
        public string NoteFromQueryString { get; set; }
    
  • İsteğe bağlı olarak oluşturucuda bir model adı değeri kabul eder. Özellik adının istekte yer alan değerle eşleşmesi durumunda bu seçenek sağlanır. Örneğin, istekte yer alan değer, aşağıdaki örnekte olduğu gibi adı kısa çizgi olan bir üst bilgi olabilir:

    public void OnGet([FromHeader(Name = "Accept-Language")] string language)
    

[FromBody] özniteliği

Http [FromBody] isteğinin gövdesinden özelliklerini doldurmak için özniteliğini bir parametreye uygulama. Çalışma ASP.NET Core, gövdeyi okuma sorumluluğunu bir giriş biçimlendirıcıya devreder. Giriş biçimlendirenler bu makalenin devamlarında açıklanmıştır.

Karmaşık [FromBody] bir tür parametresine uygulandığında, özelliklerine uygulanan tüm bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create eylem parametresinin pet gövdeden doldurulduğundan belirtir:

public ActionResult<Pet> Create([FromBody] Pet pet)

sınıfı, Pet özelliğinin bir Breed sorgu dizesi parametresinden doldurulduğundan belirtir:

public class Pet
{
    public string Name { get; set; }

    [FromQuery] // Attribute is ignored.
    public string Breed { get; set; }
}

Yukarıdaki örnekte:

  • özniteliği [FromQuery] yoksayılır.
  • özelliği Breed bir sorgu dizesi parametresinden doldurulmamaktadır.

Giriş biçimlendirenler yalnızca gövdeyi okur ve bağlama kaynağı özniteliklerini anlamaz. Gövdede uygun bir değer bulunursa, özelliği doldurmak için bu değer Breed kullanılır.

Eylem yöntemi başına [FromBody] birden fazla parametre için geçerli değildir. İstek akışı bir giriş biçimlendirıcısı tarafından okunduktan sonra, diğer parametrelerin bağlaması için artık yeniden [FromBody] okunamaz.

Ek kaynaklar

Kaynak veriler, değer sağlayıcıları tarafından model bağlama sistemine sağlanır. Diğer kaynaklardan model bağlama için veri alan özel değer sağlayıcıları yazıp kaydedebilirsiniz. Örneğin, s veya oturum durumu cookie verilerini almak istiyor olabilir. Yeni bir kaynaktan veri almak için:

  • uygulayan bir sınıf IValueProvider oluşturun.
  • uygulayan bir sınıf IValueProviderFactory oluşturun.
  • fabrika sınıfını içinde Startup.ConfigureServices kaydetme.

Örnek uygulama, değerlerini alan bir değer sağlayıcısı ve fabrika örneği cookie içerir. içinde kayıt kodu şu Startup.ConfigureServices şekildedir:

services.AddRazorPages()
    .AddMvcOptions(options =>
{
    options.ValueProviderFactories.Add(new CookieValueProviderFactory());
    options.ModelMetadataDetailsProviders.Add(
        new ExcludeBindingMetadataProvider(typeof(System.Version)));
    options.ModelMetadataDetailsProviders.Add(
        new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
})
.AddXmlSerializerFormatters();

Gösterilen kod, özel değer sağlayıcısını tüm yerleşik değer sağlayıcılarının ardından koyar. Bunu listede ilk yapmak için yerine Insert(0, new CookieValueProviderFactory()) çağrısında bulundurabilirsiniz. Add

Model özelliği için kaynak yok

Varsayılan olarak, model özelliği için değer bulunamasa model durumu hatası oluşturulmaz. özelliği null veya varsayılan değer olarak ayarlanır:

  • Null değere sahip basit türler olarak null ayarlanır.
  • Null değere sahip olmayan değer türleri olarak default(T) ayarlanır. Örneğin, bir parametre int id 0 olarak ayarlanır.
  • Karmaşık Türler için model bağlama özelliği ayarlamadan varsayılan oluşturucu kullanarak bir örnek oluşturur.
  • Diziler olarak Array.Empty<T>() ayarlanır, ancak byte[] diziler olarak null ayarlanır.

Model özelliğinin form alanlarında hiçbir şey bulunamadılarında model durumu geçersiz kılınacaksa özniteliğini [BindRequired] kullanın.

Bu [BindRequired] davranışın, istek gövdesinde JSON veya XML verilerine değil, gönderilen form verilerinden model bağlama için geçerli olduğunu unutmayın. İstek gövdesi verileri, giriş biçimlendirenler tarafından biçimlendirilmiş.

Tür dönüştürme hataları

Bir kaynak bulunursa ancak hedef türe dönüştürülenene model durumu geçersiz olarak işaretlenir. Önceki bölümde not edinilen hedef parametre veya özellik null veya varsayılan değere ayarlanır.

özniteliğine sahip bir API [ApiController] denetleyicisinde geçersiz model durumu otomatik HTTP 400 yanıtıyla sonuçlanmıştır.

Bir Razor sayfada, sayfayı bir hata iletisiyle yeniden oynatabilirsiniz:

public IActionResult OnPost()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _instructorsInMemoryStore.Add(Instructor);
    return RedirectToPage("./Index");
}

İstemci tarafı doğrulama, aksi takdirde bir Sayfalar formuna gönderilen en hatalı Razor verileri yakalar. Bu doğrulama, önceki vurgulanan kodu tetiklemeyi zorlar. Örnek uygulama, İşe Alma Tarihi alanına hatalı veriler koyan ve formu gönderen Geçersiz Tarih ile Gönder düğmesi içerir. Bu düğme, veri dönüştürme hataları oluştuğunda sayfayı yeniden oynatma kodunun nasıl çalıştığını gösterir.

Sayfa önceki kod tarafından yeniden oynatıldıklarında, geçersiz giriş form alanında gösterilmez. Bunun nedeni model özelliğinin null veya varsayılan değer olarak ayarlanmıştır. Geçersiz giriş bir hata iletisinde görünüyor. Ancak hatalı verileri form alanında yeniden oynatmak için model özelliğini bir dize yapmayı ve veri dönüştürmeyi el ile yapmayı göz önünde bulundurabilirsiniz.

Tür dönüştürme hatalarının model durumu hatalarına neden olması istemiyorsanız aynı strateji önerilir. Bu durumda model özelliğini bir dize olarak kullanın.

Basit türler

Model bağlayıcısı kaynak dizeleri içine dönüştüreb basit türler aşağıdakileri içerir:

Karmaşık türler

Karmaşık bir türün bağlamak için ortak varsayılan oluşturucusu ve ortak yazılabilir özellikleri olması gerekir. Model bağlaması oluştuğunda, sınıf genel varsayılan oluşturucu kullanılarak örneği yapılır.

Karmaşık türün her özelliği için model bağlaması, ad deseninin prefix.property_name. Hiçbir şey bulunamasa, ön ek olmadan property_name araması gerekir.

Bir parametreye bağlama için ön ek parametre adıdır. Bir ortak PageModel özele bağlama için, ön ek genel özellik adıdır. Bazı özniteliklerin varsayılan Prefix parametre veya özellik adı kullanımını geçersiz kılmaya olanak sağlayan bir özelliği vardır.

Örneğin, karmaşık türün aşağıdaki sınıf olduğunu Instructor varsayalım:

public class Instructor
{
    public int ID { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

Prefix = parametre adı

Bağlan olacak model adlı bir parametre instructorToUpdate ise:

public IActionResult OnPost(int? id, Instructor instructorToUpdate)

Model bağlaması, anahtarı için kaynaklara bakarak instructorToUpdate.ID başlar. Bu bulunamasa, ön ek ID olmadan araması gerekir.

Prefix = özellik adı

Bağlan olacak model denetleyicinin veya sınıfın adlı Instructor bir özelliği PageModel ise:

[BindProperty]
public Instructor Instructor { get; set; }

Model bağlaması, anahtarı için kaynaklara bakarak Instructor.ID başlar. Bu bulunamasa, ön ek ID olmadan araması gerekir.

Özel ön ek

Bağlan eklenecek model adlı bir parametre ise ve instructorToUpdate öznitelik ön ek olarak şunları Bind Instructor belirtir:

public IActionResult OnPost(
    int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)

Model bağlaması, anahtarı için kaynaklara bakarak Instructor.ID başlar. Bu bulunamasa, ön ek ID olmadan araması gerekir.

Karmaşık tür hedefleri için öznitelikler

Karmaşık türlerin model bağlamalarını denetlemek için çeşitli yerleşik öznitelikler kullanılabilir:

  • [Bind]
  • [BindRequired]
  • [BindNever]

Uyarı

Bu öznitelikler, gönderilen form verileri değerlerin kaynağı olduğunda model bağlamayı etkiler. Bunlar, gönderilen JSON ve XML istek gövdelerini işleyebilecek giriş biçimlendirenleri etkilemez. Giriş biçimlendirenler bu makalenin devamlarında açıklanmıştır.

[Bind] özniteliği

Bir sınıfa veya yöntem parametresine uygulanabilir. Modelin hangi özelliklerinin model bağlamaya dahil olması gerektiğini belirtir. [Bind] giriş biçimlendirenleri etkilemez.

Aşağıdaki örnekte, herhangi bir işleyici veya eylem yöntemi çağrıldı olduğunda yalnızca modelin belirtilen Instructor özellikleri bağlı olur:

[Bind("LastName,FirstMidName,HireDate")]
public class Instructor

Aşağıdaki örnekte, yöntem çağrıldı olduğunda Instructor yalnızca modelin belirtilen özellikleri OnPost bağlı olur:

[HttpPost]
public IActionResult OnPost([Bind("LastName,FirstMidName,HireDate")] Instructor instructor)

özniteliği, [Bind] oluşturma senaryolarında aşırı postaya karşı koruma için kullanılabilir. Dışlanan özellikler değiştirilmeden bırakılacak şekilde null veya varsayılan değer olarak ayarlanmış olduğundan, düzenleme senaryolarında iyi bir şekilde çalışmaz. Fazla postaya karşı savunma için öznitelik yerine görünüm modelleri [Bind] önerilir. Daha fazla bilgi için bkz. Fazla posta ile ilgili güvenlik notu.

[ModelBinder] özniteliği

ModelBinderAttribute türlere, özelliklere veya parametrelere uygulanabilir. Belirli bir örneği veya türü bağlamak için kullanılan model bağlayıcısı türünü belirtmeye olanak sağlar. Örnek:

[HttpPost]
public IActionResult OnPost([ModelBinder(typeof(MyInstructorModelBinder))] Instructor instructor)

özniteliği, [ModelBinder] modele bağlıyken bir özelliğin veya parametrenin adını değiştirmek için de kullanılabilir:

public class Instructor
{
    [ModelBinder(Name = "instructor_id")]
    public string Id { get; set; }

    public string Name { get; set; }
}

[BindRequired] özniteliği

Yöntem parametrelerine değil yalnızca model özelliklerine uygulanabilir. Modelin özelliği için bağlama başarısız olursa model bağlamanın model durumu hatası eklemeye neden olur. Aşağıda bir örnek verilmiştir:

public class InstructorWithCollection
{
    public int ID { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Hire Date")]
    [BindRequired]
    public DateTime HireDate { get; set; }

Ayrıca Model doğrulaması içinde [Required] özniteliğinin tartışmasını da görmek için bkz..

[BindNever] özniteliği

Yöntem parametrelerine değil yalnızca model özelliklerine uygulanabilir. Model bağlamanın modelin özelliğini ayarlamasını önler. Aşağıda bir örnek verilmiştir:

public class InstructorWithDictionary
{
    [BindNever]
    public int ID { get; set; }

Koleksiyonlar

Basit tür koleksiyonları olan hedefler için model bağlaması, ile veya ile parameter_name eşleşmeleri property_name. Eşleşme bulunamadan, ön ek olmadan desteklenen biçimlerden birini arayın. Örnek:

  • Bağlanarak parametrenin adlı bir dizi olduğunu selectedCourses varsayalım:

    public IActionResult OnPost(int? id, int[] selectedCourses)
    
  • Form veya sorgu dizesi verileri aşağıdaki biçimlerden biri olabilir:

    selectedCourses=1050&selectedCourses=2000 
    
    selectedCourses[0]=1050&selectedCourses[1]=2000
    
    [0]=1050&[1]=2000
    
    selectedCourses[a]=1050&selectedCourses[b]=2000&selectedCourses.index=a&selectedCourses.index=b
    
    [a]=1050&[b]=2000&index=a&index=b
    
  • Aşağıdaki biçim yalnızca form verisinde de desteklemektedir:

    selectedCourses[]=1050&selectedCourses[]=2000
    
  • Yukarıdaki örnek biçimlerin hepsi için model bağlaması iki öğeden bir diziyi parametresine selectedCourses iletir:

    • selectedCourses[0]=1050
    • selectedCourses[1]=2000

    Alt simge numaraları kullanan veri biçimleri (... [0] ... [1] ...) , sıfırdan başlayarak sıralı olarak numaralandıklarının doğru olduğundan emin olmalıdır. Alt simge numaralamada boşluk varsa, boşluk sonrasındaki tüm öğeler yoksayılır. Örneğin, alt simgeler 0 ve 1 yerine 0 ve 2 ise, ikinci öğe yoksayılır.

Sözlükler

Hedefler Dictionary için model bağlaması, ile veya ile parameter_name eşleşmeleri property_name. Eşleşme bulunamadan, ön ek olmadan desteklenen biçimlerden birini arayın. Örnek:

  • Hedef parametrenin adlandırılmış olduğunu Dictionary<int, string> selectedCourses varsayalım:

    public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
    
  • Gönderilen form veya sorgu dizesi verileri aşağıdaki örneklerden biri gibi olabilir:

    selectedCourses[1050]=Chemistry&selectedCourses[2000]=Economics
    
    [1050]=Chemistry&selectedCourses[2000]=Economics
    
    selectedCourses[0].Key=1050&selectedCourses[0].Value=Chemistry&
    selectedCourses[1].Key=2000&selectedCourses[1].Value=Economics
    
    [0].Key=1050&[0].Value=Chemistry&[1].Key=2000&[1].Value=Economics
    
  • Yukarıdaki örnek biçimlerin hepsi için model bağlaması iki öğeden bir sözlüğü parametresine selectedCourses iletir:

    • selectedCourses["1050"]="Chemistry"
    • selectedCourses["2000"]="Economics"

Oluşturucu bağlama ve kayıt türleri

Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olması gerekir. Hem hem de tabanlı giriş biçimlendirıcıları, parametresiz oluşturucusu System.Text.Json Newtonsoft.Json olmayan sınıflarınrialization destekler.

C# 9, ağ üzerinden verileri kısa ve öz bir şekilde temsil etmek için harika bir yol olan kayıt türlerini tanıtıyor. ASP.NET Core, tek bir oluşturucuyla model bağlama ve kayıt türlerini doğrulama desteği ekler:

public record Person([Required] string Name, [Range(0, 150)] int Age, [BindNever] int Id);

public class PersonController
{
   public IActionResult Index() => View();

   [HttpPost]
   public IActionResult Index(Person person)
   {
       ...
   }
}

Person/Index.cshtml:

@model Person

Name: <input asp-for="Name" />
...
Age: <input asp-for="Age" />

Çalışma zamanı, kayıt türlerini doğrularken bağlama ve doğrulama meta verilerini özellikler yerine parametreler üzerinde arar.

Çerçeve, kayıt türlerini bağlamaya ve doğrulamaya olanak sağlar:

public record Person([Required] string Name, [Range(0, 100)] int Age);

Yukarıdakinin çalışması için tür aşağıdakiler gerekir:

  • Kayıt türü olarak.
  • Tam olarak bir ortak oluşturucuya sahip.
  • Aynı ad ve türe sahip bir özelliği olan parametreleri içerir. Adlar büyük/büyük harfe göre farklılık gösterebilir.

Parametresiz oluşturucuları olmayan POCO'lar

Parametresiz oluşturucuları olmayan POCO'lar bağlanalamaz.

Aşağıdaki kod, türün parametresiz bir oluşturucuya sahip olması gerektiğini söyleyen bir özel durumla sonuç verir:

public class Person(string Name)

public record Person([Required] string Name, [Range(0, 100)] int Age)
{
   public Person(string Name) : this (Name, 0);
}

El ile yazmalı oluşturucularla kayıt türleri

Birincil oluşturucular çalışıyor gibi görünüyor, el ile yazmalı oluşturucularla kayıt türleri

public record Person
{
   public Person([Required] string Name, [Range(0, 100)] int Age) => (this.Name, this.Age) = (Name, Age);

   public string Name { get; set; }
   public int Age { get; set; }
}

Kayıt türleri, doğrulama ve bağlama meta verileri

Kayıt türleri için parametrelerde doğrulama ve bağlama meta verileri kullanılır. Özelliklerle ilgili tüm meta veriler yoksayılır

public record Person (string Name, int Age)
{
   [BindProperty(Name = "SomeName")] // This does not get used
   [Required] // This does not get used
   public string Name { get; init; }
}

Doğrulama ve meta veriler

Doğrulama parametresinde meta verileri kullanır, ancak değeri okumak için özelliğini kullanır. Birincil oluşturucular ile normal durumda, ikisi aynı olacaktır. Bununla birlikte, bunu yok etmenin yolları vardır:

public record Person([Required] string Name)
{
   private readonly string _name;
   public Name { get; init => _name = value ?? string.Empty; } // Now this property is never null. However this object could have been constructed as `new Person(null);`
}

TryUpdateModel bir kayıt türüne ait parametreleri güncelleştirmez

public record Person(string Name)
{
   public int Age { get; set; }
}

var person = new Person("initial-name");
TryUpdateModel(person, ...);

Bu durumda, MVC yeniden bağlamayı Name denemez. Ancak, Age güncelleştirilebilir

Model bağlama yol verileri ve sorgu dizelerinin genelleştirme davranışı

Yol ASP.NET Core sağlayıcısını ve sorgu dizesi değer sağlayıcısını kullanır:

  • Değerleri sabit kültür olarak işle.
  • URL'lerin kültüre göre değişken olmasını bekler.

Buna karşılık, form verilerinden gelen değerler kültüre duyarlı bir dönüştürmeden gelir. Bu, URL'lerin yerel olarak paylaşılabilir olması için tasarıma göredir.

Rota değeri ASP.NET Core sorgu dizesi değer sağlayıcısının kültüre duyarlı bir dönüştürmeden geçmesi için:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
    {
        var index = options.ValueProviderFactories.IndexOf(
            options.ValueProviderFactories.OfType<QueryStringValueProviderFactory>().Single());
        options.ValueProviderFactories[index] = new CulturedQueryStringValueProviderFactory();
    });
}
public class CulturedQueryStringValueProviderFactory : IValueProviderFactory
{
    public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var query = context.ActionContext.HttpContext.Request.Query;
        if (query != null && query.Count > 0)
        {
            var valueProvider = new QueryStringValueProvider(
                BindingSource.Query,
                query,
                CultureInfo.CurrentCulture);

            context.ValueProviders.Add(valueProvider);
        }

        return Task.CompletedTask;
    }
}

Özel veri türleri

Model bağlamanın işley yalnızca bazı özel veri türleri vardır.

IFormFile ve IFormFileCollection

HTTP isteğine dahil edilen karşıya yüklenen bir dosya. Ayrıca, birden çok IEnumerable<IFormFile> dosya için de kullanılabilir.

Cancellationtoken

Eylemler isteğe bağlı olarak bir parametresi CancellationToken olarak bağlanabilir. Bu, RequestAborted HTTP isteğinin temel alınan bağlantısının durdurulacağını işaret eder. Eylemler, denetleyici eylemlerinin bir parçası olarak yürütülen uzun süre çalışan zaman uyumsuz işlemleri iptal etmek için bu parametreyi kullanabilir.

Formcollection

Gönderilen form verilerinden tüm değerleri almak için kullanılır.

Giriş biçimlendirenler

İstek gövdesinde veriler JSON, XML veya başka bir biçimde olabilir. Bu verileri ayrıştırmak için model bağlaması, belirli bir içerik türünü işlemek üzere yapılandırılmış bir giriş biçimlendirci kullanır. Varsayılan olarak, ASP.NET Core verileri işlemeye için JSON tabanlı giriş biçimlendirenler içerir. Diğer içerik türleri için başka biçimlendirebilirsiniz.

ASP.NET Core, Consumes özniteliğine göre giriş biçimlendirenleri seçer. Bir öznitelik yoksa Content-Type üst bilgisi kullanır.

Yerleşik XML giriş biçimlendirenlerini kullanmak için:

  • NuGet Microsoft.AspNetCore.Mvc.Formatters.Xml yükleyin.

  • içinde Startup.ConfigureServices veya AddXmlSerializerFormatters çağrısı. AddXmlDataContractSerializerFormatters

    services.AddRazorPages()
        .AddMvcOptions(options =>
    {
        options.ValueProviderFactories.Add(new CookieValueProviderFactory());
        options.ModelMetadataDetailsProviders.Add(
            new ExcludeBindingMetadataProvider(typeof(System.Version)));
        options.ModelMetadataDetailsProviders.Add(
            new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
    })
    .AddXmlSerializerFormatters();
    
  • özniteliğini Consumes denetleyici sınıflara veya istek gövdesinde XML beklemesi gereken eylem yöntemlerine uygulama.

    [HttpPost]
    [Consumes("application/xml")]
    public ActionResult<Pet> Create(Pet pet)
    

    Daha fazla bilgi için, bkz. Introducing XML Serialization.

Giriş biçimlendirenlerle model bağlamayı özelleştirme

Giriş biçimlendiren, istek gövdesinden veri okumak için tam sorumluluğu üst alır. Bu işlemi özelleştirmek için giriş biçimlendirıcısı tarafından kullanılan API'leri yapılandırabilirsiniz. Bu bölümde adlı özel bir türü anlamak System.Text.Json için tabanlı giriş biçimlendirıcının nasıl özelleştirebileceğiniz ObjectId açıkmektedir.

adlı özel bir özellik içeren aşağıdaki modeli ObjectId Id düşünün:

public class ModelWithObjectId
{
    public ObjectId Id { get; set; }
}

kullanırken model bağlama işlemini özelleştirmek için, System.Text.Json sınıfından türetilen bir sınıf JsonConverter<T> oluşturun:

internal class ObjectIdConverter : JsonConverter<ObjectId>
{
    public override ObjectId Read(
        ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return new ObjectId(JsonSerializer.Deserialize<int>(ref reader, options));
    }

    public override void Write(
        Utf8JsonWriter writer, ObjectId value, JsonSerializerOptions options)
    {
        writer.WriteNumberValue(value.Id);
    }
}

Özel bir dönüştürücü kullanmak için JsonConverterAttribute özniteliğini türüne uygulama. Aşağıdaki örnekte, türü ObjectId ile özel dönüştürücü olarak ObjectIdConverter yapılandırılır:

[JsonConverter(typeof(ObjectIdConverter))]
public struct ObjectId
{
    public ObjectId(int id) =>
        Id = id;

    public int Id { get; }
}

Daha fazla bilgi için bkz. Özel dönüştürücüler yazma.

Belirtilen türleri model bağlamanın dışında tut

Model bağlama ve doğrulama sistemlerinin davranışı ModelMetadata tarafından yönlendirildi. ModelMetadata MvcOptions.ModelMetadataDetailsProviders'a bir ayrıntı sağlayıcısı ekleyerek özelleştirebilirsiniz. Yerleşik ayrıntılar sağlayıcıları, belirtilen türler için model bağlamayı veya doğrulamayı devre dışı bırakmak için kullanılabilir.

Belirtilen türe sahip tüm modellerde model bağlamayı devre dışı bırakmak için içinde bir ExcludeBindingMetadataProvider Startup.ConfigureServices ekleyin. Örneğin, türünde tüm modellerde model bağlamayı devre dışı bırakmak System.Version için:

services.AddRazorPages()
    .AddMvcOptions(options =>
{
    options.ValueProviderFactories.Add(new CookieValueProviderFactory());
    options.ModelMetadataDetailsProviders.Add(
        new ExcludeBindingMetadataProvider(typeof(System.Version)));
    options.ModelMetadataDetailsProviders.Add(
        new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
})
.AddXmlSerializerFormatters();

Belirtilen türün özelliklerinde doğrulamayı devre dışı bırakmak için içinde bir SuppressChildValidationMetadataProvider Startup.ConfigureServices ekleyin. Örneğin, türünde özelliklerde doğrulamayı devre dışı bırakmak System.Guid için:

services.AddRazorPages()
    .AddMvcOptions(options =>
{
    options.ValueProviderFactories.Add(new CookieValueProviderFactory());
    options.ModelMetadataDetailsProviders.Add(
        new ExcludeBindingMetadataProvider(typeof(System.Version)));
    options.ModelMetadataDetailsProviders.Add(
        new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
})
.AddXmlSerializerFormatters();

Özel model bağlayıcıları

Özel bir model bağlayıcısı yazarak ve belirli bir hedef için seçmek üzere özniteliğini kullanarak model [ModelBinder] bağlamayı genişletin. Özel model bağlama hakkında daha fazla bilgi.

El ile model bağlama

Model bağlaması yöntemi kullanılarak el ile TryUpdateModelAsync çağrılabilir. yöntemi hem hem de ControllerBase sınıflarında PageModel tanımlanır. Yöntem aşırı yüklemeleri, kullanmak üzere ön eki ve değer sağlayıcısını belirtmenize izin verir. Model bağlama başarısız false olursa yöntemi döndürür. Aşağıda bir örnek verilmiştir:

if (await TryUpdateModelAsync<InstructorWithCollection>(
    newInstructor,
    "Instructor",
    i => i.FirstMidName, i => i.LastName, i => i.HireDate))
{
    _instructorsInMemoryStore.Add(newInstructor);
    return RedirectToPage("./Index");
}
PopulateAssignedCourseData(newInstructor);
return Page();

TryUpdateModelAsync form gövdesinden, sorgu dizesinden ve yönlendirme verilerinden veri almak için değer sağlayıcılarını kullanır. TryUpdateModelAsync genellikle şu şekildedir:

  • Daha Razor fazla nakletmeyi engellemek için denetleyiciler ve görünümler kullanan sayfalarla ve MVC uygulamalarıyla kullanılır.
  • Form verilerinden, sorgu dizelerinden ve veri rotalarından tüketilmediği müddetçe bir Web API 'SI ile kullanılmaz. JSON kullanan Web API uç noktaları, istek gövdesini bir nesne olarak seri durumdan çıkarmak için giriş formatlarını kullanır.

Daha fazla bilgi için bkz. Tryupdatemodelasync.

[FromServices] özniteliği

Bu özniteliğin adı, bir veri kaynağı belirten model bağlama özniteliklerinin düzeniyle uyar. Ancak bir değer sağlayıcısından veri bağlama hakkında bilgi yoktur. Bağımlılık ekleme kapsayıcısından bir türün bir örneğini alır. Amacı, yalnızca belirli bir yöntem çağrılırsa bir hizmete ihtiyacınız olduğunda Oluşturucu ekleme için bir alternatif sağlamaktır.

Ek kaynaklar

Bu makalede, model bağlamanın ne olduğu, nasıl çalıştığı ve davranışını nasıl özelleştireceğiniz açıklanmaktadır.

Örnek kodu görüntüleyin veya indirin (nasıl indirilir).

Model bağlama nedir?

Denetleyiciler ve Razor Sayfalar, http isteklerinden gelen verilerle çalışır. Örneğin, rota verileri bir kayıt anahtarı sağlayabilir ve postalanan form alanları, modelin özelliklerine ilişkin değerler sağlayabilir. Bu değerlerin her birini almak ve bunları dizelerden .NET türlerine dönüştürmek için kod yazma sıkıcı ve hata durumunda olabilir. Model bağlama bu işlemi otomatikleştirir. Model bağlama sistemi:

  • Veri yolu, form alanları ve sorgu dizeleri gibi çeşitli kaynaklardan veri alır.
  • RazorYöntem parametreleri ve ortak özellikler içindeki denetleyicilere ve sayfalara verileri sağlar.
  • Dize verilerini .NET türlerine dönüştürür.
  • Karmaşık türlerin özelliklerini güncelleştirir.

Örnek

Aşağıdaki eylem yöntemine sahip olduğunuzu varsayalım:

[HttpGet("{id}")]
public ActionResult<Pet> GetById(int id, bool dogsOnly)

Ve uygulama şu URL ile bir istek alıyor:

http://contoso.com/api/pets/2?DogsOnly=true

Model bağlama, yönlendirme sistemi eylem yöntemini seçtikten sonra aşağıdaki adımlardan geçer:

  • Adlı bir tamsayı olan ilk parametresini bulur GetByID id .
  • HTTP isteğindeki kullanılabilir kaynakları arar ve id route verilerinde = "2" bulur.
  • "2" dizesini tamsayı 2 ' ye dönüştürür.
  • GetByIDAdlı bir Boole değeri olan bir sonraki parametresini bulur dogsOnly .
  • Kaynakları arar ve sorgu dizesinde "DogsOnly = true" bulur. Ad eşleştirme, büyük/küçük harfe duyarlı değildir.
  • "True" dizesini Boole değerine dönüştürür true .

Framework daha sonra yöntemi çağırır GetById , parametresi için 2 ' ye geçerek id ve true dogsOnly parametresi için.

Önceki örnekte, model bağlama hedefleri basit türler olan yöntem parametreleridir. Hedefler, karmaşık bir türün özellikleri de olabilir. Her bir özellik başarıyla bağlandıktan sonra, bu özellik için model doğrulaması oluşur. Hangi verilerin modele bağladığına ve tüm bağlama veya doğrulama hatalarıyla ilgili kayıt, ControllerBase. ModelState veya Pagemodel. ModelStateiçinde depolanır. Bu işlemin başarılı olup olmadığını öğrenmek için uygulama ModelState. IsValid bayrağını denetler.

Targets

Model bağlama, aşağıdaki tür hedeflerin değerlerini bulmayı dener:

  • Bir isteğin yönlendirildiği denetleyici eylemi yönteminin parametreleri.
  • RazorBir isteğin yönlendirildiği sayfa işleyicisi yönteminin parametreleri.
  • Bir denetleyicinin veya PageModel sınıfın öznitelikleri tarafından belirtilmişse ortak özellikleri.

[BindProperty] özniteliği

, PageModel Model bağlamasının bu özelliği hedeflemesini sağlamak için bir denetleyicinin veya sınıfın ortak özelliğine uygulanabilir:

public class EditModel : InstructorsPageModel
{
    [BindProperty]
    public Instructor Instructor { get; set; }

[BindProperties] özniteliği

ASP.NET Core 2,1 ve üzeri sürümlerde kullanılabilir. PageModelModel bağlamaya, sınıfın tüm ortak özelliklerini hedeflemesini bildirmek için bir denetleyiciye veya sınıfa uygulanabilir:

[BindProperties(SupportsGet = true)]
public class CreateModel : InstructorsPageModel
{
    public Instructor Instructor { get; set; }

HTTP GET istekleri için model bağlama

Varsayılan olarak, Özellikler HTTP GET istekleri için bağlantılı değildir. Genellikle, bir GET isteği için tüm ihtiyacınız olan bir kayıt KIMLIĞI parametresidir. Kayıt KIMLIĞI, veritabanındaki öğeyi aramak için kullanılır. Bu nedenle, modelin bir örneğini tutan bir özelliği bağlamaya gerek yoktur. GET isteklerinden alınan özelliklerin verilerine bağlanmasını istediğiniz senaryolarda SupportsGet özelliği şu şekilde ayarlayın true :

[BindProperty(Name = "ai_user", SupportsGet = true)]
public string ApplicationInsightsCookie { get; set; }

Kaynaklar

Varsayılan olarak, model bağlama, bir HTTP isteğindeki aşağıdaki kaynaklardan gelen anahtar-değer çiftleri biçimindeki verileri alır:

  1. Form alanları
  2. İstek gövdesi ( [ApiController] özniteliğine sahip denetleyicileriçin.)
  3. Veri yönlendirme
  4. Sorgu dizesi parametreleri
  5. Karşıya yüklenen dosyalar

Her hedef parametresi veya özelliği için kaynaklar, önceki listede belirtilen sırada taranır. Birkaç özel durum vardır:

  • Rota verileri ve sorgu dizesi değerleri yalnızca basit türler için kullanılır.
  • Karşıya yüklenen dosyalar yalnızca veya uygulayan hedef türlere bağlanır IFormFile IEnumerable<IFormFile> .

Varsayılan kaynak doğru değilse, kaynağı belirtmek için aşağıdaki özniteliklerden birini kullanın:

Bu öznitelikler:

  • Model özelliklerine tek tek eklenir (model sınıfına değil), aşağıdaki örnekte olduğu gibi:

    public class Instructor
    {
        public int ID { get; set; }
    
        [FromQuery(Name = "Note")]
        public string NoteFromQueryString { get; set; }
    
  • İsteğe bağlı olarak oluşturucuda bir model adı değeri kabul edin. Bu seçenek, özellik adının istekteki değerle eşleşmemesi durumunda sağlanır. Örneğin, istekteki değer aşağıdaki örnekte olduğu gibi adında bir tire olan bir üstbilgi olabilir:

    public void OnGet([FromHeader(Name = "Accept-Language")] string language)
    

[FromBody] özniteliği

[FromBody]Özniteliği BIR http isteği gövdesinden doldurmak için bir parametreye özniteliğini uygulayın. ASP.NET Core çalışma zamanı, gövdeyi bir giriş biçimlendirici 'ya okumaktan sorumlu olarak temsil eder. Giriş biçimleri Bu makalenin ilerleyen kısımlarındaaçıklanmıştır.

[FromBody]Karmaşık bir tür parametresine uygulandığında, özelliklerine uygulanan herhangi bir bağlama kaynak özniteliği yok sayılır. Örneğin, aşağıdaki eylem, Create pet parametresinin gövdeden doldurulduğunu belirtir:

public ActionResult<Pet> Create([FromBody] Pet pet)

PetSınıfı, Breed özelliğinin bir sorgu dizesi parametresinden doldurulduğunu belirtir:

public class Pet
{
    public string Name { get; set; }

    [FromQuery] // Attribute is ignored.
    public string Breed { get; set; }
}

Yukarıdaki örnekte:

  • [FromQuery]Öznitelik yoksayıldı.
  • BreedÖzellik bir sorgu dizesi parametresinden doldurulmamış.

Giriş biçimleri yalnızca gövdeyi okur ve bağlama kaynak özniteliklerini anlamayın. Gövdede uygun bir değer bulunursa, bu değer özelliği doldurmak için kullanılır Breed .

[FromBody]Action yöntemi başına birden fazla parametreye uygulanmaz. İstek akışı bir giriş biçimlendirici tarafından okunduktan sonra, diğer parametreleri bağlamak için artık bir daha okunamaz [FromBody] .

Ek kaynaklar

Kaynak verileri, model bağlama sistemine değer sağlayıcılara göre sağlanır. Diğer kaynaklardan model bağlamaya yönelik verileri alan özel değer sağlayıcıları yazabilir ve kaydedebilirsiniz. Örneğin, verilerin cookie veya oturum durumunun olmasını isteyebilirsiniz. Yeni bir kaynaktan veri almak için:

  • Uygulayan bir sınıf oluşturun IValueProvider .
  • Uygulayan bir sınıf oluşturun IValueProviderFactory .
  • Fabrika sınıfını içine kaydedin Startup.ConfigureServices .

Örnek uygulama, ' den değerler alan bir değer sağlayıcısı ve Factory örneği içerir cookie . içinde kayıt kodu şu Startup.ConfigureServices şekildedir:

services.AddMvc(options =>
{
    options.ValueProviderFactories.Add(new CookieValueProviderFactory());
    options.ModelMetadataDetailsProviders.Add(
        new ExcludeBindingMetadataProvider(typeof(System.Version)));
    options.ModelMetadataDetailsProviders.Add(
        new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
})
.AddXmlSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Gösterilen kod, özel değer sağlayıcısını tüm yerleşik değer sağlayıcılarının ardından koyar. Bunu listede ilk yapmak için yerine Insert(0, new CookieValueProviderFactory()) çağrısında bulundurabilirsiniz. Add

Model özelliği için kaynak yok

Varsayılan olarak, model özelliği için değer bulunamasa model durumu hatası oluşturulmaz. özelliği null veya varsayılan değer olarak ayarlanır:

  • Null değere sahip basit türler olarak null ayarlanır.
  • Null değere sahip olmayan değer türleri olarak default(T) ayarlanır. Örneğin, bir parametre int id 0 olarak ayarlanır.
  • Karmaşık Türler için model bağlama özelliği ayarlamadan varsayılan oluşturucu kullanarak bir örnek oluşturur.
  • Diziler olarak Array.Empty<T>() ayarlanır, ancak byte[] diziler olarak null ayarlanır.

Model özelliğinin form alanlarında hiçbir şey bulunamadılarında model durumu geçersiz kılınacaksa özniteliğini [BindRequired] kullanın.

Bu [BindRequired] davranışın, istek gövdesinde JSON veya XML verilerine değil, gönderilen form verilerinden model bağlama için geçerli olduğunu unutmayın. İstek gövdesi verileri, giriş biçimlendirenler tarafından biçimlendirilmiş.

Tür dönüştürme hataları

Bir kaynak bulunursa ancak hedef türe dönüştürülenene model durumu geçersiz olarak işaretlenir. Önceki bölümde not edinilen hedef parametre veya özellik null veya varsayılan değere ayarlanır.

özniteliğine sahip bir API [ApiController] denetleyicisinde geçersiz model durumu otomatik HTTP 400 yanıtıyla sonuçlanmıştır.

Bir Razor sayfada, sayfayı bir hata iletisiyle yeniden oynatabilirsiniz:

public IActionResult OnPost()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _instructorsInMemoryStore.Add(Instructor);
    return RedirectToPage("./Index");
}

İstemci tarafı doğrulama, aksi takdirde bir Sayfalar formuna gönderilen en hatalı Razor verileri yakalar. Bu doğrulama, önceki vurgulanan kodu tetiklemeyi zorlar. Örnek uygulama, İşe Alma Tarihi alanına hatalı veriler koyan ve formu gönderen Geçersiz Tarih ile Gönder düğmesi içerir. Bu düğme, veri dönüştürme hataları oluştuğunda sayfayı yeniden oynatma kodunun nasıl çalıştığını gösterir.

Sayfa önceki kod tarafından yeniden oynatıldıklarında, geçersiz giriş form alanında gösterilmez. Bunun nedeni model özelliğinin null veya varsayılan değer olarak ayarlanmıştır. Geçersiz giriş bir hata iletisinde görünüyor. Ancak hatalı verileri form alanında yeniden oynatmak için model özelliğini bir dize yapmayı ve veri dönüştürmeyi el ile yapmayı göz önünde bulundurabilirsiniz.

Tür dönüştürme hatalarının model durumu hatalarına neden olması istemiyorsanız aynı strateji önerilir. Bu durumda model özelliğini bir dize olarak kullanın.

Basit türler

Model bağlayıcısı kaynak dizeleri içine dönüştüreb basit türler aşağıdakileri içerir:

Karmaşık türler

Karmaşık bir türün bağlamak için ortak varsayılan oluşturucusu ve ortak yazılabilir özellikleri olması gerekir. Model bağlaması oluştuğunda, sınıf genel varsayılan oluşturucu kullanılarak örneği yapılır.

Karmaşık türün her özelliği için model bağlaması, ad deseninin prefix.property_name. Hiçbir şey bulunamasa, ön ek olmadan property_name aramaz.

Bir parametreye bağlama için ön ek parametre adıdır. Bir ortak PageModel özele bağlama için, ön ek genel özellik adıdır. Bazı özniteliklerin varsayılan Prefix parametre veya özellik adı kullanımını geçersiz kılmaya olanak sağlayan bir özelliği vardır.

Örneğin, karmaşık türün aşağıdaki sınıf olduğunu Instructor varsayalım:

public class Instructor
{
    public int ID { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

Prefix = parametre adı

Bağlan olacak model adlı bir parametre instructorToUpdate ise:

public IActionResult OnPost(int? id, Instructor instructorToUpdate)

Model bağlaması, anahtarı için kaynaklara bakarak instructorToUpdate.ID başlar. Bu bulunamasa, ön ek ID olmadan araması gerekir.

Prefix = özellik adı

Bağlan olacak model denetleyicinin veya sınıfın adlı Instructor bir özelliği PageModel ise:

[BindProperty]
public Instructor Instructor { get; set; }

Model bağlaması, anahtarı için kaynaklara bakarak Instructor.ID başlar. Bu bulunamasa, ön ek ID olmadan araması gerekir.

Özel ön ek

Bağlan eklenecek model adlı bir parametre ise ve instructorToUpdate öznitelik ön ek olarak şunları Bind Instructor belirtir:

public IActionResult OnPost(
    int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)

Model bağlaması, anahtarı için kaynaklara bakarak Instructor.ID başlar. Bu bulunamasa, ön ek ID olmadan araması gerekir.

Karmaşık tür hedefleri için öznitelikler

Karmaşık türlerin model bağlamalarını denetlemek için çeşitli yerleşik öznitelikler kullanılabilir:

  • [BindRequired]
  • [BindNever]
  • [Bind]

Not

Bu öznitelikler, gönderilen form verileri değerlerin kaynağı olduğunda model bağlamayı etkiler. Bunlar, gönderilen JSON ve XML istek gövdelerini işleyebilecek giriş biçimlendirenleri etkilemez. Giriş biçimlendirenler bu makalenin devamlarında açıklanmıştır.

Ayrıca Model doğrulaması içinde [Required] özniteliğinin tartışmasını da görmek için bkz..

[BindRequired] özniteliği

Yöntem parametrelerine değil yalnızca model özelliklerine uygulanabilir. Modelin özelliği için bağlama başarısız olursa model bağlamanın model durumu hatası eklemeye neden olur. Aşağıda bir örnek verilmiştir:

public class InstructorWithCollection
{
    public int ID { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Hire Date")]
    [BindRequired]
    public DateTime HireDate { get; set; }

[BindNever] özniteliği

Yöntem parametrelerine değil yalnızca model özelliklerine uygulanabilir. Model bağlamanın modelin özelliğini ayarlamasını önler. Aşağıda bir örnek verilmiştir:

public class InstructorWithDictionary
{
    [BindNever]
    public int ID { get; set; }

[Bind] özniteliği

Bir sınıfa veya yöntem parametresine uygulanabilir. Modelin hangi özelliklerinin model bağlamaya dahil olması gerektiğini belirtir.

Aşağıdaki örnekte, herhangi bir işleyici veya eylem yöntemi çağrıldı olduğunda yalnızca modelin belirtilen Instructor özellikleri bağlı olur:

[Bind("LastName,FirstMidName,HireDate")]
public class Instructor

Aşağıdaki örnekte, yöntem çağrıldı olduğunda Instructor yalnızca modelin belirtilen özellikleri OnPost bağlı olur:

[HttpPost]
public IActionResult OnPost([Bind("LastName,FirstMidName,HireDate")] Instructor instructor)

özniteliği, [Bind] oluşturma senaryolarında aşırı postaya karşı koruma için kullanılabilir. Dışlanan özellikler değiştirilmeden bırakılacak şekilde null veya varsayılan değer olarak ayarlanmış olduğundan, düzenleme senaryolarında iyi bir şekilde çalışmaz. Fazla postaya karşı savunma için öznitelik yerine görünüm modelleri [Bind] önerilir. Daha fazla bilgi için bkz. Fazla posta ile ilgili güvenlik notu.

Koleksiyonlar

Basit tür koleksiyonları olan hedefler için model bağlaması, ile veya ile parameter_name eşleşmeleri property_name. Eşleşme bulunamadan, ön ek olmadan desteklenen biçimlerden birini arayın. Örnek:

  • Bağlanarak parametrenin adlı bir dizi olduğunu selectedCourses varsayalım:

    public IActionResult OnPost(int? id, int[] selectedCourses)
    
  • Form veya sorgu dizesi verileri aşağıdaki biçimlerden biri olabilir:

    selectedCourses=1050&selectedCourses=2000 
    
    selectedCourses[0]=1050&selectedCourses[1]=2000
    
    [0]=1050&[1]=2000
    
    selectedCourses[a]=1050&selectedCourses[b]=2000&selectedCourses.index=a&selectedCourses.index=b
    
    [a]=1050&[b]=2000&index=a&index=b
    
  • Aşağıdaki biçim yalnızca form verisinde de desteklemektedir:

    selectedCourses[]=1050&selectedCourses[]=2000
    
  • Yukarıdaki örnek biçimlerin hepsi için model bağlaması iki öğeden bir diziyi parametresine selectedCourses iletir:

    • selectedCourses[0]=1050
    • selectedCourses[1]=2000

    Alt simge numaralarını kullanan veri biçimleri (... [0]... [1]...) sıfırdan başlayarak sıralı olarak numaralandırıldıklarından emin olmalıdır. Alt simge numaralandırmasında boşluk varsa, boşluklardan sonraki tüm öğeler yoksayılır. Örneğin, alt simgeler 0 ve 1 yerine 0 ve 2 ise ikinci öğe yok sayılır.

Sözlükler

DictionaryHedefler için, model bağlama parameter_name veya property_name eşleşme arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örnek:

  • Hedef parametrenin bir adlandırılmış olduğunu varsayalım Dictionary<int, string> selectedCourses :

    public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
    
  • Postalanan form veya sorgu dizesi verileri aşağıdaki örneklerden birine benzeyebilir:

    selectedCourses[1050]=Chemistry&selectedCourses[2000]=Economics
    
    [1050]=Chemistry&selectedCourses[2000]=Economics
    
    selectedCourses[0].Key=1050&selectedCourses[0].Value=Chemistry&
    selectedCourses[1].Key=2000&selectedCourses[1].Value=Economics
    
    [0].Key=1050&[0].Value=Chemistry&[1].Key=2000&[1].Value=Economics
    
  • Önceki örnek biçimlerinin hepsi için model bağlama iki öğenin bir sözlüğünü selectedCourses parametreye geçirir:

    • Selectedkurslar ["1050"] = "Chemistry"
    • Selectedkurslar ["2000"] = "Ekonomiks"

Model bağlama yolu verileri ve sorgu dizeleri için Genelleştirme davranışı

ASP.NET Core yol değeri sağlayıcısı ve sorgu dizesi değer sağlayıcısı:

  • Değerleri sabit kültür olarak değerlendirin.
  • URL 'Lerin kültür sabiti olmasını bekler.

Buna karşılık, form verilerinden gelen değerler kültüre duyarlı bir dönüştürmeye gider. Bu, URL 'Lerin yerel ayarlarda paylaşılabilir olması için tasarımdır.

ASP.NET Core yol değeri sağlayıcısını ve sorgu dizesi değeri sağlayıcısını, kültüre duyarlı bir dönüşüme dönüştürmek için:

services.AddMvc(options =>
{
    var index = options.ValueProviderFactories.IndexOf(
        options.ValueProviderFactories.OfType<QueryStringValueProviderFactory>().Single());
    options.ValueProviderFactories[index] = new CulturedQueryStringValueProviderFactory();
});
public class CulturedQueryStringValueProviderFactory : IValueProviderFactory
{
    public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var query = context.ActionContext.HttpContext.Request.Query;
        if (query != null && query.Count > 0)
        {
            var valueProvider = new QueryStringValueProvider(
                BindingSource.Query,
                query,
                CultureInfo.CurrentCulture);

            context.ValueProviders.Add(valueProvider);
        }

        return Task.CompletedTask;
    }
}

Özel veri türleri

Model bağlamanın işleyebileceği bazı özel veri türleri vardır.

Iformfile ve ıformfilecollection

HTTP isteğine eklenen karşıya yüklenen dosya. Ayrıca, IEnumerable<IFormFile> birden çok dosya için de desteklenir.

CancellationToken

Zaman uyumsuz denetleyicilerde etkinliği iptal etmek için kullanılır.

Form koleksiyonu

Postalanan form verilerinden tüm değerleri almak için kullanılır.

Giriş biçimleri

İstek gövdesindeki veriler JSON, XML veya başka bir biçimde olabilir. Model bağlama, bu verileri ayrıştırmak için belirli bir içerik türünü işlemek üzere yapılandırılmış bir giriş biçimlendiricisi kullanır. varsayılan olarak, ASP.NET Core json verilerini işlemek için json tabanlı giriş formatlayıcıları içerir. Diğer içerik türleri için başka biçim ekleyebilirsiniz.

ASP.NET Core, tüketen özniteliğine bağlı olarak giriş formatlayıcıları seçer. Hiçbir öznitelik yoksa, Content-Type üst bilgisinikullanır.

Yerleşik XML girişi formatlayıcıları 'nı kullanmak için:

  • Microsoft.AspNetCore.Mvc.Formatters.XmlNuGet paketini yükler.

  • İçinde Startup.ConfigureServices , veya öğesini çağırın AddXmlSerializerFormatters AddXmlDataContractSerializerFormatters .

    services.AddMvc(options =>
    {
        options.ValueProviderFactories.Add(new CookieValueProviderFactory());
        options.ModelMetadataDetailsProviders.Add(
            new ExcludeBindingMetadataProvider(typeof(System.Version)));
        options.ModelMetadataDetailsProviders.Add(
            new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
    })
    .AddXmlSerializerFormatters()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
  • Özniteliği, Consumes istek GÖVDESINDE XML beklemeniz gereken denetleyici sınıflarına veya eylem yöntemlerine uygulayın.

    [HttpPost]
    [Consumes("application/xml")]
    public ActionResult<Pet> Create(Pet pet)
    

    Daha fazla bilgi için bkz. XML serileştirme tanıtımı.

Belirtilen türleri model bağlamalarından Dışla

Model bağlama ve doğrulama sistemlerinin davranışı ModelMetadatatarafından yönlendiriliyor. ModelMetadata Mvcoptions. modelmetadatadetails sağlayıcılarınabir ayrıntı sağlayıcısı ekleyerek özelleştirebilirsiniz. Yerleşik Ayrıntılar sağlayıcıları, belirtilen türler için model bağlamayı veya doğrulamayı devre dışı bırakmak üzere kullanılabilir.

Belirtilen türdeki tüm modellerdeki model bağlamayı devre dışı bırakmak için içine bir ekleyin ExcludeBindingMetadataProvider Startup.ConfigureServices . Örneğin, türü tüm modeller üzerinde model bağlamayı devre dışı bırakmak için System.Version :

services.AddMvc(options =>
{
    options.ValueProviderFactories.Add(new CookieValueProviderFactory());
    options.ModelMetadataDetailsProviders.Add(
        new ExcludeBindingMetadataProvider(typeof(System.Version)));
    options.ModelMetadataDetailsProviders.Add(
        new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
})
.AddXmlSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Belirtilen türdeki özelliklerde doğrulamayı devre dışı bırakmak için içine bir ekleyin SuppressChildValidationMetadataProvider Startup.ConfigureServices . Örneğin, türündeki özelliklerde doğrulamayı devre dışı bırakmak için System.Guid :

services.AddMvc(options =>
{
    options.ValueProviderFactories.Add(new CookieValueProviderFactory());
    options.ModelMetadataDetailsProviders.Add(
        new ExcludeBindingMetadataProvider(typeof(System.Version)));
    options.ModelMetadataDetailsProviders.Add(
        new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
})
.AddXmlSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Özel model ciltleri

Özel bir model cildi yazarak ve [ModelBinder] belirli bir hedef için seçmek üzere özniteliğini kullanarak model bağlamayı genişletebilirsiniz. Özel model bağlamahakkında daha fazla bilgi edinin.

El ile model bağlama

Model bağlama yöntemi kullanılarak el ile çağrılabilir TryUpdateModelAsync . Yöntemi hem hem de sınıflarında tanımlanmıştır ControllerBase PageModel . Yöntem aşırı yüklemeleri, kullanılacak öneki ve değer sağlayıcısını belirtmenizi sağlar. Yöntemi false model bağlamanın başarısız olup olmadığını döndürür. Aşağıda bir örnek verilmiştir:

if (await TryUpdateModelAsync<InstructorWithCollection>(
    newInstructor,
    "Instructor",
    i => i.FirstMidName, i => i.LastName, i => i.HireDate))
{
    _instructorsInMemoryStore.Add(newInstructor);
    return RedirectToPage("./Index");
}
PopulateAssignedCourseData(newInstructor);
return Page();

[FromServices] özniteliği

Bu özniteliğin adı, bir veri kaynağı belirten model bağlama özniteliklerinin düzeniyle uyar. Ancak bir değer sağlayıcısından veri bağlama hakkında bilgi yoktur. Bağımlılık ekleme kapsayıcısından bir türün bir örneğini alır. Amacı, yalnızca belirli bir yöntem çağrılırsa bir hizmete ihtiyacınız olduğunda Oluşturucu ekleme için bir alternatif sağlamaktır.

Ek kaynaklar