Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.
Bu makalede model bağlamanın ne olduğu, nasıl çalıştığı ve davranışının nasıl özelleştirileceği açıklanmaktadır.
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 gönderilen form alanları modelin özellikleri için değerler sağlayabilir. Bu değerlerin her birini almak ve bunları dizelerden .NET türlerine dönüştürmek için kod yazmak yorucu ve hataya açık olabilir. Model bağlama bu işlemi otomatikleştirir. Model bağlama sistemi:
- Rota verileri, form alanları ve sorgu dizeleri gibi çeşitli kaynaklardan veri alır.
- Yöntem parametrelerinde ve Razor genel özelliklerdeki verileri denetleyiciler ve sayfalara 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)
Uygulama şu URL'ye sahip bir istek alır:
https://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ı
GetById
bir tamsayınınid
ilk parametresini bulur. - HTTP isteğindeki kullanılabilir kaynakları arar ve yol verilerinde = "2" değerini bulur
id
. - "2" dizesini 2 tamsayısına dönüştürür.
- adlı
GetById
bir boole değerinindogsOnly
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. İsim karşılaştırma büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve, GetById
yöntemini çağırarak id
parametresi için 2 ve true
parametresi için dogsOnly
değerini geçirir.
Yukarıdaki ö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. Bu işlemin başarılı olup olmadığını öğrenmek için uygulama ModelState.IsValid bayrağını denetler.
Hedefler
Model bağlama, aşağıdaki hedef türleri için değerleri bulmaya çalışır:
- bir isteğin yönlendirıldığı denetleyici eylem yönteminin parametreleri.
- Bir isteğin yönlendirildiği Pages işleyici yönteminin parametreleri.
- Öznitelikler tarafından belirtilirse, bir denetleyicinin veya
PageModel
sınıfın genel özellikleri.
[BindProperty] özniteliği
Model bağlamanın bu özelliği hedeflemesine neden olmak için bir denetleyicinin veya PageModel
sınıfın ortak özelliğine uygulanabilir:
public class EditModel : PageModel
{
[BindProperty]
public Instructor? Instructor { get; set; }
// ...
}
[BindProperties] özniteliği
Model bağlamasının sınıfın tüm genel özelliklerini hedeflemesini bildirmek için bir denetleyiciye veya PageModel
sınıfa uygulanabilir:
[BindProperties]
public class CreateModel : PageModel
{
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 ihtiyacınız olan tek şey 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 isteklerindeki verilere bağlı özelliklerin olmasını istediğiniz senaryolarda SupportsGet
özelliğini true
olarak ayarlayın.
[BindProperty(Name = "ai_user", SupportsGet = true)]
public string? ApplicationInsightsCookie { get; set; }
Model bağlama basit ve karmaşık türler
Model bağlama, üzerinde çalıştığı türler için belirli tanımları kullanır.
Basit bir tür, TypeConverter veya TryParse
yöntemi kullanılarak tek bir dizeden dönüştürülür. Karmaşık bir tür birden çok giriş değerinden dönüştürülür. Çerçeve, TypeConverter
veya TryParse
varlığının olup olmadığına göre farkı belirler. Bir tür dönüştürücüsü oluşturmanızı veya harici kaynaklar ya da birden fazla giriş gerektirmeyen bir TryParse
'den string
'a dönüşüm için SomeType
kullanmanızı öneririz.
Kaynaklar
Varsayılan olarak, model bağlama bir HTTP isteğinde aşağıdaki kaynaklardan anahtar-değer çiftleri biçiminde veri alır:
- Form alanları
- İstek gövdesi ([ApiController] özniteliğine sahip denetleyiciler için.)
- Yol verisi
- Sorgu dizesi parametreleri
- Yüklenen dosyalar
Her hedef parametre veya özellik için kaynaklar, önceki listede belirtilen sırayla taranır. Birkaç özel durum vardır:
- Yönlendirme verileri ve sorgu dizesi değerleri yalnızca basit türler için kullanılır.
- Karşıya yüklenen dosyalar yalnızca
IFormFile
veyaIEnumerable<IFormFile>
uygulayan hedef türlerine bağlıdır.
Varsayılan kaynak doğru değilse, kaynağı belirtmek için aşağıdaki özniteliklerden birini kullanın:
-
[FromQuery]
- Sorgu dizesinden 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 sınıfına değil model özelliklerine ayrı ayrı eklenir:
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. Özellik adının istekteki değerle eşleşmemesi durumunda bu seçenek sağlanır. Örneğin, istekteki değer, adında kısa çizgi bulunan bir başlık olabilir, aşağıdaki örnekte olduğu gibi.
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Bir parametrenin özelliklerini HTTP isteğinin gövdesinden doldurmak için [FromBody]
özniteliğini uygulayın. ASP.NET Core çalışma zamanı, içeriği okuma sorumluluğunu bir giriş biçimlendiricisine devreder. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[FromBody]
, karmaşık bir tür parametresine uygulandığında, bunun özelliklerine ait bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylemi, pet
parametresinin gövdeden doldurulduğunu belirtir:
public ActionResult<Pet> Create([FromBody] Pet pet)
sınıfı, Pet
özelliğinin Breed
bir sorgu dizesi parametresinden doldurulduğunu belirtir:
public class Pet
{
public string Name { get; set; } = null!;
[FromQuery] // Attribute is ignored.
public string Breed { get; set; } = null!;
}
Yukarıdaki örnekte:
-
[FromQuery]
Özniteliği yoksayılır. -
Breed
özelliği bir sorgu dizesi parametresinden doldurulmuyor.
Giriş biçimlendiricileri yalnızca gövdeyi okur ve bağlama kaynak özniteliklerini anlamaz. Gövde içinde uygun bir değer bulunursa, bu değer Breed
özelliğini doldurmak için kullanılır.
Eylem yöntemi başına birden fazla parametreye uygulamayın [FromBody]
. İstek akışı bir giriş biçimlendiricisi tarafından okunduktan sonra, diğer [FromBody]
parametreleri bağlamak için yeniden okunamayacaktır.
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ı yazabilir ve kaydedebilirsiniz. Örneğin, tanımlama bilgilerinden veya oturum durumundan veri isteyebilirsiniz. Yeni bir kaynaktan veri almak için:
-
IValueProvider
uygulayan bir sınıf oluşturun. -
IValueProviderFactory
uygulayan bir sınıf oluşturun. - Fabrika sınıfını
Program.cs
kaydedin.
Örnek, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve üretici örneği içerir.
Program.cs
içinde özel değer sağlayıcı fabrikalarını kaydedin.
builder.Services.AddControllers(options =>
{
options.ValueProviderFactories.Add(new CookieValueProviderFactory());
});
Yukarıdaki kod, özel değer sağlayıcısını tüm yerleşik değer sağlayıcılarının arkasına yerleştirir. Listedeki ilk öğe yapmak için Insert(0, new CookieValueProviderFactory())
yerine Add
öğesini çağırın.
Model özelliği için kaynak yok
Varsayılan olarak, bir model özelliği için değer bulunamazsa model durumu hatası oluşturulmaz. özelliği null veya varsayılan değer olarak ayarlanır:
- Null atanabilir basit türler
null
olarak ayarlanır. - Null olmayan değer türleri
default(T)
olarak ayarlanır. Örneğin, bir parametreint id
0 olarak ayarlanır. - Karmaşık Türler için model bağlama, özellikleri ayarlamadan varsayılan oluşturucuyu kullanarak bir örnek oluşturur.
- Diziler
Array.Empty<T>()
olarak ayarlanır, ancakbyte[]
dizilerinull
olarak ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamadığında model durumunu geçersiz kılmak için [BindRequired]
özniteliğini kullanın.
Bu [BindRequired]
davranışının, bir istek gövdesindeki JSON veya XML verilerinden değil, gönderilen form verilerinden model bağlama için geçerli olduğunu unutmayın. İstek gövdesi verileri giriş biçimlendiricileri tarafından işlenir.
Tür dönüştürme hataları
Bir kaynak bulunur ancak hedef türe dönüştürülemezse, model durumu geçersiz olarak işaretlenir. Hedef parametre veya özellik, önceki bölümde belirtildiği gibi null veya varsayılan değer olarak ayarlanır.
[ApiController]
özniteliğine sahip bir API denetleyicisinde, geçersiz model durumu otomatik olarak HTTP 400 yanıtı verir.
Razor Sayfada bir hata mesajıyla sayfayı yeniden görüntüleyin:
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
// ...
return RedirectToPage("./Index");
}
Sayfa önceki kod tarafından yeniden görüntülendiğinde, form alanında geçersiz giriş gösterilmez. Bunun nedeni model özelliğinin null veya varsayılan değer olarak ayarlanmış olmasıdır. Geçersiz giriş bir hata iletisinde görünüyor. Form alanındaki hatalı verileri yeniden görüntülemek istiyorsanız model özelliğini bir dize haline getirme ve veri dönüştürme işlemini el ile gerçekleştirmeyi göz önünde bulundurun.
Tür dönüştürme hatalarının model durumu hatalarına neden olmasını istemiyorsanız aynı strateji önerilir. Bu durumda, model özelliğini bir dize yapın.
Basit türler
Açıklaması için Model bağlama basit ve karmaşık türler bölümüne bakın.
Model bağlayıcısının kaynak dizeleri dönüştürebileceği basit türler şunlardır:
- Boolean
- Bayt, SByte
- Char
- DateOnly
- Tarih Saat
- DateTimeOffset
- Ondalık
- Çift
- Sabit Listesi
- GUID
- Int16, Int32, Int64
- Tek
- TimeOnly
- Zaman Aralığı
- UInt16, UInt32, UInt64
- Urı
- Sürüm
IParsable<T>.TryParse
ile bağla
API, IParsable<TSelf>.TryParse
bağlama denetleyicisi eylem parametresi değerlerini destekler:
public static bool TryParse (string? s, IFormatProvider? provider, out TSelf result);
Aşağıdaki DateRange
sınıf, tarih aralığı bağlamayı desteklemek için IParsable<TSelf>
'i uygular:
public class DateRange : IParsable<DateRange>
{
public DateOnly? From { get; init; }
public DateOnly? To { get; init; }
public static DateRange Parse(string value, IFormatProvider? provider)
{
if (!TryParse(value, provider, out var result))
{
throw new ArgumentException("Could not parse supplied value.", nameof(value));
}
return result;
}
public static bool TryParse(string? value,
IFormatProvider? provider, out DateRange dateRange)
{
var segments = value?.Split(',', StringSplitOptions.RemoveEmptyEntries
| StringSplitOptions.TrimEntries);
if (segments?.Length == 2
&& DateOnly.TryParse(segments[0], provider, out var fromDate)
&& DateOnly.TryParse(segments[1], provider, out var toDate))
{
dateRange = new DateRange { From = fromDate, To = toDate };
return true;
}
dateRange = new DateRange { From = default, To = default };
return false;
}
}
Yukarıdaki kod:
- İki tarihi temsil eden bir dizeyi nesneye
DateRange
dönüştürür - Model bağlayıcısı
IParsable<TSelf>.TryParse
yöntemini bağlamak içinDateRange
kullanır.
Aşağıdaki denetleyici eylemi, bir tarih aralığını bağlamak için sınıfını DateRange
kullanır:
// GET /WeatherForecast/ByRange?range=7/24/2022,07/26/2022
public IActionResult ByRange([FromQuery] DateRange range)
{
if (!ModelState.IsValid)
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Where(wf => DateOnly.FromDateTime(wf.Date) >= range.From
&& DateOnly.FromDateTime(wf.Date) <= range.To)
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d"),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int)(wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View("Index", weatherForecasts);
}
Aşağıdaki Locale
sınıf, IParsable<TSelf>
uygular ve CultureInfo
'a bağlanmayı destekler.
public class Locale : CultureInfo, IParsable<Locale>
{
public Locale(string culture) : base(culture)
{
}
public static Locale Parse(string value, IFormatProvider? provider)
{
if (!TryParse(value, provider, out var result))
{
throw new ArgumentException("Could not parse supplied value.", nameof(value));
}
return result;
}
public static bool TryParse([NotNullWhen(true)] string? value,
IFormatProvider? provider, out Locale locale)
{
if (value is null)
{
locale = new Locale(CurrentCulture.Name);
return false;
}
try
{
locale = new Locale(value);
return true;
}
catch (CultureNotFoundException)
{
locale = new Locale(CurrentCulture.Name);
return false;
}
}
}
Aşağıdaki denetleyici eylemi, bir Locale
dizisini bağlamak için CultureInfo
sınıfını kullanır.
// GET /en-GB/WeatherForecast
public IActionResult Index([FromRoute] Locale locale)
{
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d", locale),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int)(wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View(weatherForecasts);
}
Aşağıdaki denetleyici eylemi, bir tarih aralığını DateRange
ile bağlamak için Locale
ve CultureInfo
sınıflarını kullanır:
// GET /af-ZA/WeatherForecast/RangeByLocale?range=2022-07-24,2022-07-29
public IActionResult RangeByLocale([FromRoute] Locale locale, [FromQuery] string range)
{
if (!ModelState.IsValid)
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
if (!DateRange.TryParse(range, locale, out DateRange rangeResult))
{
ModelState.TryAddModelError(nameof(range),
$"Invalid date range: {range} for locale {locale.DisplayName}");
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
}
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Where(wf => DateOnly.FromDateTime(wf.Date) >= rangeResult.From
&& DateOnly.FromDateTime(wf.Date) <= rangeResult.To)
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d", locale),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int) (wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View("Index", weatherForecasts);
}
GitHub'da API örnek uygulaması, bir API denetleyicisi için önceki örneği gösterir.
TryParse
ile bağla
API, TryParse
bağlama denetleyicisi eylem parametresi değerlerini destekler:
public static bool TryParse(string value, T out result);
public static bool TryParse(string value, IFormatProvider provider, T out result);
IParsable<T>.TryParse
parametre bağlaması için önerilen yaklaşımdır çünkü aksine TryParse
, yansımaya bağımlı değildir.
Aşağıdaki DateRangeTP
sınıf şunu uygular TryParse
:
public class DateRangeTP
{
public DateOnly? From { get; }
public DateOnly? To { get; }
public DateRangeTP(string from, string to)
{
if (string.IsNullOrEmpty(from))
throw new ArgumentNullException(nameof(from));
if (string.IsNullOrEmpty(to))
throw new ArgumentNullException(nameof(to));
From = DateOnly.Parse(from);
To = DateOnly.Parse(to);
}
public static bool TryParse(string? value, out DateRangeTP? result)
{
var range = value?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (range?.Length != 2)
{
result = default;
return false;
}
result = new DateRangeTP(range[0], range[1]);
return true;
}
}
Aşağıdaki denetleyici eylemi, bir tarih aralığını bağlamak için sınıfını DateRangeTP
kullanır:
// GET /WeatherForecast/ByRangeTP?range=7/24/2022,07/26/2022
public IActionResult ByRangeTP([FromQuery] DateRangeTP range)
{
if (!ModelState.IsValid)
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Where(wf => DateOnly.FromDateTime(wf.Date) >= range.From
&& DateOnly.FromDateTime(wf.Date) <= range.To)
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d"),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int)(wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View("Index", weatherForecasts);
}
Karmaşık türler
Karmaşık bir türün, bağlanacak genel bir varsayılan oluşturucuya ve genel yazılabilir özelliklerine sahip olması gerekir. Model bağlama gerçekleştiğinde, sınıfın örneği, public varsayılan oluşturucu kullanılarak oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad desenininkaynaklarına bakar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar. Ön ek kullanma kararı, her özellik için ayrı ayrı alınmaz. Örneğin, ?Instructor.Id=100&Name=foo
içeren bir sorgu, OnGet(Instructor instructor)
yöntemine bağlı olarak, türü Instructor
olan elde edilen nesne şunları içerir:
-
Id
olarak100
ayarlayın. -
Name
olaraknull
ayarlayın. Model bağlamasıInstructor.Name
'ün önceki sorgu parametresinde kullanılması nedeniyleInstructor.Id
'ü bekliyor.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak bir özelliğe PageModel
bağlanırken, ön ek ortak özelliğin adıdır. Bazı öznitelikler, parametre veya özellik adının varsayılan kullanımını geçersiz kılmanıza olanak tanıyan bir Prefix
özelliğe sahiptir.
Örneğin, karmaşık türün aşağıdaki Instructor
sınıf olduğunu varsayalım:
public class Instructor
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
Ön ek = parametre adı
Bağlanacak model adlı instructorToUpdate
bir parametreyse:
public IActionResult OnPost(int? id, Instructor instructorToUpdate)
Model bağlama, instructorToUpdate.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Eğer bağlanacak model, denetleyici veya Instructor
sınıfının PageModel
adlı bir özelliğiyse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model, instructorToUpdate
adlı bir parametre olduğunda ve Bind
özniteliği, ön ek olarak Instructor
'yi belirtiyorsa:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Karmaşık tür hedefleri için öznitelikler
Karmaşık türlerin model bağlamasını denetlemek için çeşitli yerleşik öznitelikler kullanılabilir:
Uyarı
Bu öznitelikler, form verileri gönderildiğinde değerlerin kaynağı olarak model bağlamasını etkiler. Bunlar, gönderilen JSON ve XML istek gövdelerini işleyen giriş biçimlendiricilerini etkilemez. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[Bind] özelliği
Bir sınıfa veya yöntem parametresine uygulanabilir. Modelin hangi özelliklerinin model bağlamaya dahil edilmesi gerektiğini belirtir.
[Bind]
giriş biçimlendiricilerini etkilemez.
Aşağıdaki örnekte, herhangi bir işleyici veya eylem yöntemi çağrıldığında yalnızca modelin Instructor
belirtilen özellikleri bağlıdır:
[Bind("LastName,FirstMidName,HireDate")]
public class Instructor
Aşağıdaki örnekte, Instructor
yöntemi çağrıldığında yalnızca OnPost
modelinin belirtilen özellikleri bağlanır.
[HttpPost]
public IActionResult OnPost(
[Bind("LastName,FirstMidName,HireDate")] Instructor instructor)
[Bind]
özniteliği, oluşturma senaryolarında aşırı paylaşıma karşı koruma sağlamak için kullanılabilir. Dışlanan özellikler değiştirilmeden bırakılmak yerine null veya varsayılan değer olarak ayarlandığından, düzenleme senaryolarında düzgün çalışmaz. Aşırı paylaşıma karşı korunma için, [Bind]
özniteliği yerine görünüm modelleri önerilir. Daha fazla bilgi için bkz . Fazla paylaşımla 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ının türünü belirtmeye olanak tanır. Örneğin:
[HttpPost]
public IActionResult OnPost(
[ModelBinder<MyInstructorModelBinder>] Instructor instructor)
Özniteliği, [ModelBinder]
modele bağlı olduğunda 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; }
// ...
}
[BindRequired] özniteliği
Bir modelin özelliği için bağlantı kurulamıyorsa, model durumuna bir hata eklenmesine neden olur. Bir örnek aşağıda verilmiştir:
public class InstructorBindRequired
{
// ...
[BindRequired]
public DateTime HireDate { get; set; }
}
Ayrıca Bkz. Model doğrulamasında [Required]
özniteliğin tartışması.
[BindNever] özniteliği
Bir özelliğe veya türe uygulanabilir. Model bağlamasının bir modelin özelliğini ayarlamasını engeller. Bir türe uygulandığında, model bağlama sistemi türün tanımladığı tüm özellikleri dışlar. Bir örnek aşağıda verilmiştir:
public class InstructorBindNever
{
[BindNever]
public int Id { get; set; }
// ...
}
Koleksiyonlar
Basit tür koleksiyonları olan hedefler için model bağlama, parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Bağlanacak parametrenin adlı
selectedCourses
bir dizi olduğunu varsayalım:public IActionResult OnPost(int? id, int[] selectedCourses)
Form veya sorgu dizesi verileri aşağıdaki biçimlerden birinde 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
Adı
index
veyaIndex
olan bir parametreyi ya da özelliği bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlama,index
öğesini koleksiyon için bir dizin olarak kullanmaya çalışır ve bu da yanlış bağlamaya yol açabilir. Örneğin, aşağıdaki eylemi göz önünde bulundurun:public IActionResult Post(string index, List<Product> products)
Yukarıdaki kodda
index
sorgu dizesi parametresi yöntem parametresineindex
bağlanır ve ayrıca ürün koleksiyonunu bağlamak için kullanılır. Parametrenin yeniden adlandırılması veya bağlamayıindex
yapılandırmak için bir model bağlama özniteliği kullanılması bu sorunu önler:public IActionResult Post(string productIndex, List<Product> products)
Aşağıdaki biçim yalnızca form verilerinde desteklenir:
selectedCourses[]=1050&selectedCourses[]=2000
Önceki tüm örnek biçimler için, model bağlama parametresine
selectedCourses
iki öğeden oluşan bir dizi geçirir:- selectedCourses[0]=1050
- selectedCourses[1]=2000
Alt simge numaraları kullanan veri biçimleri (... [0] ... [1] ...) sıfırdan başlayarak sıralı olarak numaralandırıldığından emin olmalıdır. Alt simge numaralandırmasında boşluk varsa, boşluktan sonraki 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
Dictionary
hedefleri için, model bağlama parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adı
Dictionary<int, string>
olan birselectedCourses
olduğunu varsayalım.public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
Gönderilen form veya sorgu dizesi verileri aşağıdaki örneklerden biri gibi görünebilir:
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 tüm örnek biçimler için model bağlama parametresine
selectedCourses
iki öğeden oluşan bir sözlük geçirir:- selectedCourses["1050"]="Kimya"
- selectedCourses["2000"]="Ekonomi"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir.
System.Text.Json
ve Newtonsoft.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarılmasını destekler.
Kayıt türleri, ağ üzerinden verileri kısa bir şekilde temsil etmenin harika bir yoludur. ASP.NET Core, tek bir oluşturucuyla model bağlamayı ve kayıt türlerini doğrulamayı destekler:
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
<label>Name: <input asp-for="Name" /></label>
<br />
<label>Age: <input asp-for="Age" /></label>
Kayıt türleri doğrulanırken çalışma zamanı, özellikle özellikler yerine parametrelerde bağlama ve doğrulama meta verilerini arar.
Çerçeve, kayıt türlerini bağlamaya ve doğrulamaya olanak tanır:
public record Person([Required] string Name, [Range(0, 100)] int Age);
Öncekinin çalışması için türün şunları yapması gerekir:
- Bir kayıt türü oluşturun.
- Tam olarak bir genel oluşturucuya sahip olun.
- Aynı isim ve türde bir özelliği olan parametreleri içerir. Adların büyük/küçük harfe göre farklılık göstermemesi gerekir.
Parametresiz oluşturucuları olmayan POCO'lar
Parametresiz oluşturucuları olmayan POCO'lar bağlanamaz.
Aşağıdaki kod, türün parametresiz bir oluşturucuya sahip olması gerektiğini belirten bir özel durumla sonuçlanır.
public class Person {
public Person(string Name) { }
}
public record Person([Required] string Name, [Range(0, 100)] int Age)
{
public Person(string Name) : this (Name, 0)
{
}
}
El ile yazılmış oluşturucularla kayıt türleri
Manuel olarak yazılmış ve birincil oluşturuculara benzeyen oluşturucuların çalıştığı 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 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ğerini okumak için özelliğini kullanır. Birincil yapıcılarla normal koşullarda, ikisi aynı olacaktır. Ancak, bunu yenmenin yolları vardır:
public record Person([Required] string Name)
{
private readonly string _name;
// The following property is never null.
// However this object could have been constructed as "new Person(null)".
public string Name { get; init => _name = value ?? string.Empty; }
}
TryUpdateModel bir kayıt türündeki 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ştirilmeye izin verilir
Model bağlama yönlendirme verilerinin ve sorgu dizelerinin 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ı beklenir.
Buna karşılık, form verilerinden gelen değerler kültüre duyarlı bir dönüştürmeden geçer. Bu, URL'lerin yerel ayarlar arasında paylaşılabilir olması için tasarım gereğidir.
ASP.NET Core yol değeri sağlayıcısının ve sorgu dizesi değer sağlayıcısının kültüre duyarlı bir dönüştürmeden geçirilmesini sağlamak için:
- IValueProviderFactory'den Devral
- QueryStringValueProviderFactory veya RouteValueValueProviderFactory'den kodu kopyalayın
- Değer sağlayıcısı oluşturucusna geçirilen kültür değerini CultureInfo.CurrentCulture ile değiştirin
- MVC seçeneklerindeki varsayılan değer sağlayıcısı fabrikasını yenisiyle değiştirin:
public class CultureQueryStringValueProviderFactory : IValueProviderFactory
{
public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
{
_ = context ?? throw new ArgumentNullException(nameof(context));
var query = context.ActionContext.HttpContext.Request.Query;
if (query?.Count > 0)
{
context.ValueProviders.Add(
new QueryStringValueProvider(
BindingSource.Query,
query,
CultureInfo.CurrentCulture));
}
return Task.CompletedTask;
}
}
builder.Services.AddControllers(options =>
{
var index = options.ValueProviderFactories.IndexOf(
options.ValueProviderFactories.OfType<QueryStringValueProviderFactory>()
.Single());
options.ValueProviderFactories[index] =
new CultureQueryStringValueProviderFactory();
});
Özel veri türleri
Model bağlamanın işleyebileceği bazı özel veri türleri vardır.
IFormFile ve IFormFileCollection
HTTP isteğine eklenen yüklenmiş bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
İptal Belirteci
Eylemler isteğe bağlı olarak bir CancellationToken
’yi parametre olarak bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyal veren RequestAborted öğesine bağlanır. 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.
Form Koleksiyonu
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biçimlendiricileri
İ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çimlendirici kullanır. varsayılan olarak ASP.NET Core, JSON verilerini işlemek için JSON tabanlı giriş biçimlendiricileri içerir. Diğer içerik türleri için başka biçimlendiriciler ekleyebilirsiniz.
ASP.NET Core, Consumes özniteliğine göre giriş biçimlendiricilerini seçer. Öznitelik yoksa İçerik Türü üst bilgisini kullanır.
Yerleşik XML giriş biçimlendiricilerini kullanmak için:
Program.cs
içinde, AddXmlSerializerFormatters veya AddXmlDataContractSerializerFormatters öğesini arayın.builder.Services.AddControllers() .AddXmlSerializerFormatters();
Denetleyici sınıflarına veya istek gövdesinde
Consumes
XML bekleyen eylem yöntemlerine özniteliğini uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileştirmeye Giriş.
Giriş biçimlendiricileri ile model bağlamayı özelleştirme
Giriş biçimlendiricisi, istek gövdesinden veri okumanın tüm sorumluluğunu alır. Bu işlemi özelleştirmek için giriş biçimlendiricisi tarafından kullanılan API'leri yapılandırın. Bu bölüm, System.Text.Json
tabanlı giriş biçimlendiricisinin, ObjectId
adlı özel bir türü anlaması için nasıl özelleştirileceğini açıklar.
Özel ObjectId
bir özellik içeren aşağıdaki modeli göz önünde bulundurun:
public class InstructorObjectId
{
[Required]
public ObjectId ObjectId { get; set; } = null!;
}
System.Text.Json
kullanırken model bağlama işlemini özelleştirmek için JsonConverter<T> öğesinden türetilmiş bir sınıf oluşturun.
internal class ObjectIdConverter : JsonConverter<ObjectId>
{
public override ObjectId Read(
ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> new(JsonSerializer.Deserialize<int>(ref reader, options));
public override void Write(
Utf8JsonWriter writer, ObjectId value, JsonSerializerOptions options)
=> writer.WriteNumberValue(value.Id);
}
Özel dönüştürücü kullanmak için özniteliğini JsonConverterAttribute türüne uygulayın. Aşağıdaki örnekte, ObjectId
türü, özel dönüştürücüsü olarak ObjectIdConverter
ile yapılandırılır.
[JsonConverter(typeof(ObjectIdConverter))]
public record ObjectId(int Id);
Daha fazla bilgi için Özel dönüştürücüler nasıl yazılır? kısmına bakın.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a ModelMetadata
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ğlamasını veya doğrulamayı devre dışı bırakmak için kullanılabilir.
Belirtilen türdeki tüm modellerde model bağlamayı devre dışı bırakmak için, ExcludeBindingMetadataProvider'e bir Program.cs
ekleyin. Örneğin, türündeki tüm System.Version
modellerde model bağlamayı devre dışı bırakmak için:
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new ExcludeBindingMetadataProvider(typeof(Version)));
options.ModelMetadataDetailsProviders.Add(
new SuppressChildValidationMetadataProvider(typeof(Guid)));
});
Belirtilen türdeki özelliklerde doğrulamayı devre dışı bırakmak için SuppressChildValidationMetadataProvider öğesini Program.cs
içinde ekleyin. Örneğin, türündeki System.Guid
özelliklerde doğrulamayı devre dışı bırakmak için:
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new ExcludeBindingMetadataProvider(typeof(Version)));
options.ModelMetadataDetailsProviders.Add(
new SuppressChildValidationMetadataProvider(typeof(Guid)));
});
Özel model bağlayıcıları
Özel bir model bağlayıcı yazarak ve [ModelBinder]
özniteliğini kullanarak, model bağlamayı belirli bir hedef için seçebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
TryUpdateModelAsync yöntemi kullanılarak model bağlama işlemi manuel olarak başlatılabilir. Yöntem hem ControllerBase
hem de PageModel
sınıflarında tanımlanır. Yöntem aşırı yüklemeleri, kullanılacak ön ek ve değer sağlayıcısını belirtmenize olanak sağlar. Yöntem, model bağlama başarısız olursa döndürür false
. Bir örnek aşağıda verilmiştir:
if (await TryUpdateModelAsync(
newInstructor,
"Instructor",
x => x.Name, x => x.HireDate!))
{
_instructorStore.Add(newInstructor);
return RedirectToPage("./Index");
}
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:
- Fazla gönderimi önlemek için denetleyiciler ve görünümler kullanılarak Sayfalar ve MVC uygulamalarıyla birlikte Razor kullanılır.
- Form verilerinden, sorgu dizelerinden ve yönlendirme verilerinden alınmadıkça bir web API'si ile kullanılmaz. JSON kullanan Web API uç noktaları, istek gövdesini bir nesneye seri durumdan çıkarmak için Giriş biçimlendiricilerini kullanır.
Daha fazla bilgi için bkz . TryUpdateModelAsync.
[FromServices] özniteliği
Bu özniteliğin adı, bir veri kaynağı belirten model bağlama özniteliklerinin desenini izler. Ancak bu, bir değer sağlayıcısından verileri bağlamayla ilgili değildir. Bağımlılık enjeksiyonu kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir metot çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu enjeksiyonuna alternatif sağlamaktır.
Türün bir örneği bağımlılık ekleme kapsayıcısında kayıtlı değilse, uygulama parametresini bağlamaya çalışırken bir özel durum oluşturur. parametresini isteğe bağlı hale getirmek için aşağıdaki yaklaşımlardan birini kullanın:
- Parametreyi null değeri alabilir hale getirin.
- parametresi için varsayılan bir değer ayarlayın.
Null atanabilir parametreler için, parametreye erişmeden önce bu parametrenin olmadığından null
emin olun.
Ek kaynaklar
Bu makalede model bağlamanın ne olduğu, nasıl çalıştığı ve davranışının nasıl özelleştirileceği açıklanmaktadır.
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 gönderilen form alanları modelin özellikleri için değerler sağlayabilir. Bu değerlerin her birini almak ve bunları dizelerden .NET türlerine dönüştürmek için kod yazmak yorucu ve hataya açık olabilir. Model bağlama bu işlemi otomatikleştirir. Model bağlama sistemi:
- Rota verileri, form alanları ve sorgu dizeleri gibi çeşitli kaynaklardan veri alır.
- Yöntem parametrelerinde ve Razor genel özelliklerdeki verileri denetleyiciler ve sayfalara 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)
Uygulama şu URL'ye sahip bir istek alır:
https://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ı
GetById
bir tamsayınınid
ilk parametresini bulur. - HTTP isteğindeki kullanılabilir kaynakları arar ve yol verilerinde = "2" değerini bulur
id
. - "2" dizesini 2 tamsayısına dönüştürür.
- adlı
GetById
bir boole değerinindogsOnly
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. İsim karşılaştırma büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve, GetById
yöntemini çağırarak id
parametresi için 2 ve true
parametresi için dogsOnly
değerini geçirir.
Yukarıdaki ö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. Bu işlemin başarılı olup olmadığını öğrenmek için uygulama ModelState.IsValid bayrağını denetler.
Hedefler
Model bağlama, aşağıdaki hedef türleri için değerleri bulmaya çalışır:
- bir isteğin yönlendirıldığı denetleyici eylem yönteminin parametreleri.
- Bir isteğin yönlendirildiği Pages işleyici yönteminin parametreleri.
- Öznitelikler tarafından belirtilirse, bir denetleyicinin veya
PageModel
sınıfın genel özellikleri.
[BindProperty] özniteliği
Model bağlamanın bu özelliği hedeflemesine neden olmak için bir denetleyicinin veya PageModel
sınıfın ortak özelliğine uygulanabilir:
public class EditModel : PageModel
{
[BindProperty]
public Instructor? Instructor { get; set; }
// ...
}
[BindProperties] özniteliği
Model bağlamasının sınıfın tüm genel özelliklerini hedeflemesini bildirmek için bir denetleyiciye veya PageModel
sınıfa uygulanabilir:
[BindProperties]
public class CreateModel : PageModel
{
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 ihtiyacınız olan tek şey 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 isteklerindeki verilere bağlı özelliklerin olmasını istediğiniz senaryolarda SupportsGet
özelliğini true
olarak ayarlayın.
[BindProperty(Name = "ai_user", SupportsGet = true)]
public string? ApplicationInsightsCookie { get; set; }
Model bağlama basit ve karmaşık türler
Model bağlama, üzerinde çalıştığı türler için belirli tanımları kullanır.
Basit bir tür, TypeConverter veya TryParse
yöntemi kullanılarak tek bir dizeden dönüştürülür. Karmaşık bir tür birden çok giriş değerinden dönüştürülür. Çerçeve, TypeConverter
veya TryParse
varlığının olup olmadığına göre farkı belirler. Bir tür dönüştürücüsü oluşturmanızı veya harici kaynaklar ya da birden fazla giriş gerektirmeyen bir TryParse
'den string
'a dönüşüm için SomeType
kullanmanızı öneririz.
Kaynaklar
Varsayılan olarak, model bağlama bir HTTP isteğinde aşağıdaki kaynaklardan anahtar-değer çiftleri biçiminde veri alır:
- Form alanları
- İstek gövdesi ([ApiController] özniteliğine sahip denetleyiciler için.)
- Yol verisi
- Sorgu dizesi parametreleri
- Yüklenen dosyalar
Her hedef parametre veya özellik için kaynaklar, önceki listede belirtilen sırayla taranır. Birkaç özel durum vardır:
- Yönlendirme verileri ve sorgu dizesi değerleri yalnızca basit türler için kullanılır.
- Karşıya yüklenen dosyalar yalnızca
IFormFile
veyaIEnumerable<IFormFile>
uygulayan hedef türlerine bağlıdır.
Varsayılan kaynak doğru değilse, kaynağı belirtmek için aşağıdaki özniteliklerden birini kullanın:
-
[FromQuery]
- Sorgu dizesinden 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 sınıfına değil model özelliklerine ayrı ayrı eklenir:
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. Özellik adının istekteki değerle eşleşmemesi durumunda bu seçenek sağlanır. Örneğin, istekteki değer, adında kısa çizgi bulunan bir başlık olabilir, aşağıdaki örnekte olduğu gibi.
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Bir parametrenin özelliklerini HTTP isteğinin gövdesinden doldurmak için [FromBody]
özniteliğini uygulayın. ASP.NET Core çalışma zamanı, içeriği okuma sorumluluğunu bir giriş biçimlendiricisine devreder. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[FromBody]
, karmaşık bir tür parametresine uygulandığında, bunun özelliklerine ait bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylemi, pet
parametresinin gövdeden doldurulduğunu belirtir:
public ActionResult<Pet> Create([FromBody] Pet pet)
sınıfı, Pet
özelliğinin Breed
bir sorgu dizesi parametresinden doldurulduğunu belirtir:
public class Pet
{
public string Name { get; set; } = null!;
[FromQuery] // Attribute is ignored.
public string Breed { get; set; } = null!;
}
Yukarıdaki örnekte:
-
[FromQuery]
Özniteliği yoksayılır. -
Breed
özelliği bir sorgu dizesi parametresinden doldurulmuyor.
Giriş biçimlendiricileri yalnızca gövdeyi okur ve bağlama kaynak özniteliklerini anlamaz. Gövde içinde uygun bir değer bulunursa, bu değer Breed
özelliğini doldurmak için kullanılır.
Eylem yöntemi başına birden fazla parametreye uygulamayın [FromBody]
. İstek akışı bir giriş biçimlendiricisi tarafından okunduktan sonra, diğer [FromBody]
parametreleri bağlamak için yeniden okunamayacaktır.
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ı yazabilir ve kaydedebilirsiniz. Örneğin, tanımlama bilgilerinden veya oturum durumundan veri isteyebilirsiniz. Yeni bir kaynaktan veri almak için:
-
IValueProvider
uygulayan bir sınıf oluşturun. -
IValueProviderFactory
uygulayan bir sınıf oluşturun. - Fabrika sınıfını
Program.cs
kaydedin.
Örnek, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve üretici örneği içerir.
Program.cs
içinde özel değer sağlayıcı fabrikalarını kaydedin.
builder.Services.AddControllers(options =>
{
options.ValueProviderFactories.Add(new CookieValueProviderFactory());
});
Yukarıdaki kod, özel değer sağlayıcısını tüm yerleşik değer sağlayıcılarının arkasına yerleştirir. Listedeki ilk öğe yapmak için Insert(0, new CookieValueProviderFactory())
yerine Add
öğesini çağırın.
Model özelliği için kaynak yok
Varsayılan olarak, bir model özelliği için değer bulunamazsa model durumu hatası oluşturulmaz. özelliği null veya varsayılan değer olarak ayarlanır:
- Null atanabilir basit türler
null
olarak ayarlanır. - Null olmayan değer türleri
default(T)
olarak ayarlanır. Örneğin, bir parametreint id
0 olarak ayarlanır. - Karmaşık Türler için model bağlama, özellikleri ayarlamadan varsayılan oluşturucuyu kullanarak bir örnek oluşturur.
- Diziler
Array.Empty<T>()
olarak ayarlanır, ancakbyte[]
dizilerinull
olarak ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamadığında model durumunu geçersiz kılmak için [BindRequired]
özniteliğini kullanın.
Bu [BindRequired]
davranışın, bir istek gövdesindeki 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çimlendiricileri tarafından işlenir.
Tür dönüştürme hataları
Bir kaynak bulunur ancak hedef türe dönüştürülemezse, model durumu geçersiz olarak işaretlenir. Hedef parametre veya özellik, önceki bölümde belirtildiği gibi null veya varsayılan değer olarak ayarlanır.
[ApiController]
özniteliğine sahip bir API denetleyicisinde, geçersiz model durumu otomatik olarak HTTP 400 yanıtı verir.
Razor Sayfada bir hata mesajıyla sayfayı yeniden görüntüleyin:
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
// ...
return RedirectToPage("./Index");
}
Sayfa önceki kod tarafından yeniden görüntülendiğinde, form alanında geçersiz giriş gösterilmez. Bunun nedeni model özelliğinin null veya varsayılan değer olarak ayarlanmış olmasıdır. Geçersiz giriş bir hata iletisinde görünüyor. Form alanındaki hatalı verileri yeniden görüntülemek istiyorsanız model özelliğini bir dize haline getirme ve veri dönüştürme işlemini el ile gerçekleştirmeyi göz önünde bulundurun.
Tür dönüştürme hatalarının model durumu hatalarına neden olmasını istemiyorsanız aynı strateji önerilir. Bu durumda, model özelliğini bir dize yapın.
Basit türler
Açıklaması için Model bağlama basit ve karmaşık türler bölümüne bakın.
Model bağlayıcısının kaynak dizeleri dönüştürebileceği basit türler şunlardır:
- Boolean
- Bayt, SByte
- Char
- DateOnly
- Tarih Saat
- DateTimeOffset
- Ondalık
- Çift
- Sabit Listesi
- GUID
- Int16, Int32, Int64
- Tek
- TimeOnly
- Zaman Aralığı
- UInt16, UInt32, UInt64
- Urı
- Sürüm
IParsable<T>.TryParse
ile bağla
API, IParsable<TSelf>.TryParse
bağlama denetleyicisi eylem parametresi değerlerini destekler:
public static bool TryParse (string? s, IFormatProvider? provider, out TSelf result);
Aşağıdaki DateRange
sınıf, tarih aralığı bağlamayı desteklemek için IParsable<TSelf>
'i uygular:
public class DateRange : IParsable<DateRange>
{
public DateOnly? From { get; init; }
public DateOnly? To { get; init; }
public static DateRange Parse(string value, IFormatProvider? provider)
{
if (!TryParse(value, provider, out var result))
{
throw new ArgumentException("Could not parse supplied value.", nameof(value));
}
return result;
}
public static bool TryParse(string? value,
IFormatProvider? provider, out DateRange dateRange)
{
var segments = value?.Split(',', StringSplitOptions.RemoveEmptyEntries
| StringSplitOptions.TrimEntries);
if (segments?.Length == 2
&& DateOnly.TryParse(segments[0], provider, out var fromDate)
&& DateOnly.TryParse(segments[1], provider, out var toDate))
{
dateRange = new DateRange { From = fromDate, To = toDate };
return true;
}
dateRange = new DateRange { From = default, To = default };
return false;
}
}
Yukarıdaki kod:
- İki tarihi temsil eden bir dizeyi nesneye
DateRange
dönüştürür - Model bağlayıcısı
IParsable<TSelf>.TryParse
yöntemini bağlamak içinDateRange
kullanır.
Aşağıdaki denetleyici eylemi, bir tarih aralığını bağlamak için sınıfını DateRange
kullanır:
// GET /WeatherForecast/ByRange?range=7/24/2022,07/26/2022
public IActionResult ByRange([FromQuery] DateRange range)
{
if (!ModelState.IsValid)
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Where(wf => DateOnly.FromDateTime(wf.Date) >= range.From
&& DateOnly.FromDateTime(wf.Date) <= range.To)
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d"),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int)(wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View("Index", weatherForecasts);
}
Aşağıdaki Locale
sınıf, IParsable<TSelf>
uygular ve CultureInfo
'a bağlanmayı destekler.
public class Locale : CultureInfo, IParsable<Locale>
{
public Locale(string culture) : base(culture)
{
}
public static Locale Parse(string value, IFormatProvider? provider)
{
if (!TryParse(value, provider, out var result))
{
throw new ArgumentException("Could not parse supplied value.", nameof(value));
}
return result;
}
public static bool TryParse([NotNullWhen(true)] string? value,
IFormatProvider? provider, out Locale locale)
{
if (value is null)
{
locale = new Locale(CurrentCulture.Name);
return false;
}
try
{
locale = new Locale(value);
return true;
}
catch (CultureNotFoundException)
{
locale = new Locale(CurrentCulture.Name);
return false;
}
}
}
Aşağıdaki denetleyici eylemi, bir Locale
dizisini bağlamak için CultureInfo
sınıfını kullanır.
// GET /en-GB/WeatherForecast
public IActionResult Index([FromRoute] Locale locale)
{
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d", locale),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int)(wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View(weatherForecasts);
}
Aşağıdaki denetleyici eylemi, bir tarih aralığını DateRange
ile bağlamak için Locale
ve CultureInfo
sınıflarını kullanır:
// GET /af-ZA/WeatherForecast/RangeByLocale?range=2022-07-24,2022-07-29
public IActionResult RangeByLocale([FromRoute] Locale locale, [FromQuery] string range)
{
if (!ModelState.IsValid)
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
if (!DateRange.TryParse(range, locale, out DateRange rangeResult))
{
ModelState.TryAddModelError(nameof(range),
$"Invalid date range: {range} for locale {locale.DisplayName}");
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
}
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Where(wf => DateOnly.FromDateTime(wf.Date) >= rangeResult.From
&& DateOnly.FromDateTime(wf.Date) <= rangeResult.To)
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d", locale),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int) (wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View("Index", weatherForecasts);
}
GitHub'da API örnek uygulaması, bir API denetleyicisi için önceki örneği gösterir.
TryParse
ile bağla
API, TryParse
bağlama denetleyicisi eylem parametresi değerlerini destekler:
public static bool TryParse(string value, T out result);
public static bool TryParse(string value, IFormatProvider provider, T out result);
IParsable<T>.TryParse
parametre bağlaması için önerilen yaklaşımdır çünkü aksine TryParse
, yansımaya bağımlı değildir.
Aşağıdaki DateRangeTP
sınıf şunu uygular TryParse
:
public class DateRangeTP
{
public DateOnly? From { get; }
public DateOnly? To { get; }
public DateRangeTP(string from, string to)
{
if (string.IsNullOrEmpty(from))
throw new ArgumentNullException(nameof(from));
if (string.IsNullOrEmpty(to))
throw new ArgumentNullException(nameof(to));
From = DateOnly.Parse(from);
To = DateOnly.Parse(to);
}
public static bool TryParse(string? value, out DateRangeTP? result)
{
var range = value?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (range?.Length != 2)
{
result = default;
return false;
}
result = new DateRangeTP(range[0], range[1]);
return true;
}
}
Aşağıdaki denetleyici eylemi, bir tarih aralığını bağlamak için sınıfını DateRangeTP
kullanır:
// GET /WeatherForecast/ByRangeTP?range=7/24/2022,07/26/2022
public IActionResult ByRangeTP([FromQuery] DateRangeTP range)
{
if (!ModelState.IsValid)
return View("Error", ModelState.Values.SelectMany(v => v.Errors));
var weatherForecasts = Enumerable
.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.Where(wf => DateOnly.FromDateTime(wf.Date) >= range.From
&& DateOnly.FromDateTime(wf.Date) <= range.To)
.Select(wf => new WeatherForecastViewModel
{
Date = wf.Date.ToString("d"),
TemperatureC = wf.TemperatureC,
TemperatureF = 32 + (int)(wf.TemperatureC / 0.5556),
Summary = wf.Summary
});
return View("Index", weatherForecasts);
}
Karmaşık türler
Karmaşık bir türün, bağlanacak genel bir varsayılan oluşturucuya ve genel yazılabilir özelliklerine sahip olması gerekir. Model bağlama gerçekleştiğinde, sınıfın örneği, public varsayılan oluşturucu kullanılarak oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad desenininkaynaklarına bakar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar. Ön ek kullanma kararı, her özellik için ayrı ayrı alınmaz. Örneğin, ?Instructor.Id=100&Name=foo
içeren bir sorgu, OnGet(Instructor instructor)
yöntemine bağlı olarak, türü Instructor
olan elde edilen nesne şunları içerir:
-
Id
olarak100
ayarlayın. -
Name
olaraknull
ayarlayın. Model bağlamasıInstructor.Name
'ün önceki sorgu parametresinde kullanılması nedeniyleInstructor.Id
'ü bekliyor.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak bir özelliğe PageModel
bağlanırken, ön ek ortak özelliğin adıdır. Bazı öznitelikler, parametre veya özellik adının varsayılan kullanımını geçersiz kılmanıza olanak tanıyan bir Prefix
özelliğe sahiptir.
Örneğin, karmaşık türün aşağıdaki Instructor
sınıf olduğunu varsayalım:
public class Instructor
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
Ön ek = parametre adı
Bağlanacak model adlı instructorToUpdate
bir parametreyse:
public IActionResult OnPost(int? id, Instructor instructorToUpdate)
Model bağlama, instructorToUpdate.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Eğer bağlanacak model, denetleyici veya Instructor
sınıfının PageModel
adlı bir özelliğiyse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model, instructorToUpdate
adlı bir parametre olduğunda ve Bind
özniteliği, ön ek olarak Instructor
'yi belirtiyorsa:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Karmaşık tür hedefleri için öznitelikler
Karmaşık türlerin model bağlamasını denetlemek için çeşitli yerleşik öznitelikler kullanılabilir:
Uyarı
Bu öznitelikler, form verileri gönderildiğinde değerlerin kaynağı olarak model bağlamasını etkiler. Bunlar, gönderilen JSON ve XML istek gövdelerini işleyen giriş biçimlendiricilerini etkilemez. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[Bind] özelliği
Bir sınıfa veya yöntem parametresine uygulanabilir. Modelin hangi özelliklerinin model bağlamaya dahil edilmesi gerektiğini belirtir.
[Bind]
giriş biçimlendiricilerini etkilemez.
Aşağıdaki örnekte, herhangi bir işleyici veya eylem yöntemi çağrıldığında yalnızca modelin Instructor
belirtilen özellikleri bağlıdır:
[Bind("LastName,FirstMidName,HireDate")]
public class Instructor
Aşağıdaki örnekte, Instructor
yöntemi çağrıldığında yalnızca OnPost
modelinin belirtilen özellikleri bağlanır.
[HttpPost]
public IActionResult OnPost(
[Bind("LastName,FirstMidName,HireDate")] Instructor instructor)
[Bind]
özniteliği, oluşturma senaryolarında aşırı paylaşıma karşı koruma sağlamak için kullanılabilir. Dışlanan özellikler değiştirilmeden bırakılmak yerine null veya varsayılan değer olarak ayarlandığından, düzenleme senaryolarında düzgün çalışmaz. Aşırı paylaşıma karşı korunma için, [Bind]
özniteliği yerine görünüm modelleri önerilir. Daha fazla bilgi için bkz . Fazla paylaşımla 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ının türünü belirtmeye olanak tanır. Örneğin:
[HttpPost]
public IActionResult OnPost(
[ModelBinder(typeof(MyInstructorModelBinder))] Instructor instructor)
Özniteliği, [ModelBinder]
modele bağlı olduğunda 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; }
// ...
}
[BindRequired] özniteliği
Bir modelin özelliği için bağlantı kurulamıyorsa, model durumuna bir hata eklenmesine neden olur. Bir örnek aşağıda verilmiştir:
public class InstructorBindRequired
{
// ...
[BindRequired]
public DateTime HireDate { get; set; }
}
Ayrıca Bkz. Model doğrulamasında [Required]
özniteliğin tartışması.
[BindNever] özniteliği
Bir özelliğe veya türe uygulanabilir. Model bağlamasının bir modelin özelliğini ayarlamasını engeller. Bir türe uygulandığında, model bağlama sistemi türün tanımladığı tüm özellikleri dışlar. Bir örnek aşağıda verilmiştir:
public class InstructorBindNever
{
[BindNever]
public int Id { get; set; }
// ...
}
Koleksiyonlar
Basit tür koleksiyonları olan hedefler için model bağlama, parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Bağlanacak parametrenin adlı
selectedCourses
bir dizi olduğunu varsayalım:public IActionResult OnPost(int? id, int[] selectedCourses)
Form veya sorgu dizesi verileri aşağıdaki biçimlerden birinde 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
Adı
index
veyaIndex
olan bir parametreyi ya da özelliği bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlama,index
öğesini koleksiyon için bir dizin olarak kullanmaya çalışır ve bu da yanlış bağlamaya yol açabilir. Örneğin, aşağıdaki eylemi göz önünde bulundurun:public IActionResult Post(string index, List<Product> products)
Yukarıdaki kodda
index
sorgu dizesi parametresi yöntem parametresineindex
bağlanır ve ayrıca ürün koleksiyonunu bağlamak için kullanılır. Parametrenin yeniden adlandırılması veya bağlamayıindex
yapılandırmak için bir model bağlama özniteliği kullanılması bu sorunu önler:public IActionResult Post(string productIndex, List<Product> products)
Aşağıdaki biçim yalnızca form verilerinde desteklenir:
selectedCourses[]=1050&selectedCourses[]=2000
Önceki tüm örnek biçimler için, model bağlama parametresine
selectedCourses
iki öğeden oluşan bir dizi geçirir:- selectedCourses[0]=1050
- selectedCourses[1]=2000
Alt simge numaraları kullanan veri biçimleri (... [0] ... [1] ...) sıfırdan başlayarak sıralı olarak numaralandırıldığından emin olmalıdır. Alt simge numaralandırmasında boşluk varsa, boşluktan sonraki 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
Dictionary
hedefleri için, model bağlama parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adı
Dictionary<int, string>
olan birselectedCourses
olduğunu varsayalım.public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
Gönderilen form veya sorgu dizesi verileri aşağıdaki örneklerden biri gibi görünebilir:
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 tüm örnek biçimler için model bağlama parametresine
selectedCourses
iki öğeden oluşan bir sözlük geçirir:- selectedCourses["1050"]="Kimya"
- selectedCourses["2000"]="Ekonomi"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir.
System.Text.Json
ve Newtonsoft.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarılmasını destekler.
Kayıt türleri, ağ üzerinden verileri kısa bir şekilde temsil etmenin harika bir yoludur. ASP.NET Core, tek bir oluşturucuyla model bağlamayı ve kayıt türlerini doğrulamayı destekler:
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
<label>Name: <input asp-for="Name" /></label>
<br />
<label>Age: <input asp-for="Age" /></label>
Kayıt türleri doğrulanırken çalışma zamanı, özellikle özellikler yerine parametrelerde bağlama ve doğrulama meta verilerini arar.
Çerçeve, kayıt türlerini bağlamaya ve doğrulamaya olanak tanır:
public record Person([Required] string Name, [Range(0, 100)] int Age);
Öncekinin çalışması için türün şunları yapması gerekir:
- Bir kayıt türü oluşturun.
- Tam olarak bir genel oluşturucuya sahip olun.
- Aynı isim ve türde bir özelliği olan parametreleri içerir. Adların büyük/küçük harfe göre farklılık göstermemesi gerekir.
Parametresiz oluşturucuları olmayan POCO'lar
Parametresiz oluşturucuları olmayan POCO'lar bağlanamaz.
Aşağıdaki kod, türün parametresiz bir oluşturucuya sahip olması gerektiğini belirten bir özel durumla sonuçlanır.
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 yazılmış oluşturucularla kayıt türleri
Manuel olarak yazılmış ve birincil oluşturuculara benzeyen oluşturucuların çalıştığı 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 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ğerini okumak için özelliğini kullanır. Birincil yapıcılarla normal koşullarda, ikisi aynı olacaktır. Ancak, bunu yenmenin yolları vardır:
public record Person([Required] string Name)
{
private readonly string _name;
// The following property is never null.
// However this object could have been constructed as "new Person(null)".
public string Name { get; init => _name = value ?? string.Empty; }
}
TryUpdateModel bir kayıt türündeki 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ştirilmeye izin verilir
Model bağlama yönlendirme verilerinin ve sorgu dizelerinin 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ı beklenir.
Buna karşılık, form verilerinden gelen değerler kültüre duyarlı bir dönüştürmeden geçer. Bu, URL'lerin yerel ayarlar arasında paylaşılabilir olması için tasarım gereğidir.
ASP.NET Core yol değeri sağlayıcısının ve sorgu dizesi değer sağlayıcısının kültüre duyarlı bir dönüştürmeden geçirilmesini sağlamak için:
- IValueProviderFactory'den Devral
- QueryStringValueProviderFactory veya RouteValueValueProviderFactory'den kodu kopyalayın
- Değer sağlayıcısı oluşturucusna geçirilen kültür değerini CultureInfo.CurrentCulture ile değiştirin
- MVC seçeneklerindeki varsayılan değer sağlayıcısı fabrikasını yenisiyle değiştirin:
public class CultureQueryStringValueProviderFactory : IValueProviderFactory
{
public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
{
_ = context ?? throw new ArgumentNullException(nameof(context));
var query = context.ActionContext.HttpContext.Request.Query;
if (query?.Count > 0)
{
context.ValueProviders.Add(
new QueryStringValueProvider(
BindingSource.Query,
query,
CultureInfo.CurrentCulture));
}
return Task.CompletedTask;
}
}
builder.Services.AddControllers(options =>
{
var index = options.ValueProviderFactories.IndexOf(
options.ValueProviderFactories.OfType<QueryStringValueProviderFactory>()
.Single());
options.ValueProviderFactories[index] =
new CultureQueryStringValueProviderFactory();
});
Özel veri türleri
Model bağlamanın işleyebileceği bazı özel veri türleri vardır.
IFormFile ve IFormFileCollection
HTTP isteğine eklenen yüklenmiş bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
İptal Belirteci
Eylemler isteğe bağlı olarak bir CancellationToken
’yi parametre olarak bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyal veren RequestAborted öğesine bağlanır. 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.
Form Koleksiyonu
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biçimlendiricileri
İ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çimlendirici kullanır. varsayılan olarak ASP.NET Core, JSON verilerini işlemek için JSON tabanlı giriş biçimlendiricileri içerir. Diğer içerik türleri için başka biçimlendiriciler ekleyebilirsiniz.
ASP.NET Core, Consumes özniteliğine göre giriş biçimlendiricilerini seçer. Öznitelik yoksa İçerik Türü üst bilgisini kullanır.
Yerleşik XML giriş biçimlendiricilerini kullanmak için:
Program.cs
içinde, AddXmlSerializerFormatters veya AddXmlDataContractSerializerFormatters öğesini arayın.builder.Services.AddControllers() .AddXmlSerializerFormatters();
Denetleyici sınıflarına veya istek gövdesinde
Consumes
XML bekleyen eylem yöntemlerine özniteliğini uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileştirmeye Giriş.
Giriş biçimlendiricileri ile model bağlamayı özelleştirme
Giriş biçimlendiricisi, istek gövdesinden veri okumanın tüm sorumluluğunu alır. Bu işlemi özelleştirmek için giriş biçimlendiricisi tarafından kullanılan API'leri yapılandırın. Bu bölüm, System.Text.Json
tabanlı giriş biçimlendiricisinin, ObjectId
adlı özel bir türü anlaması için nasıl özelleştirileceğini açıklar.
Özel ObjectId
bir özellik içeren aşağıdaki modeli göz önünde bulundurun:
public class InstructorObjectId
{
[Required]
public ObjectId ObjectId { get; set; } = null!;
}
System.Text.Json
kullanırken model bağlama işlemini özelleştirmek için JsonConverter<T> öğesinden türetilmiş bir sınıf oluşturun.
internal class ObjectIdConverter : JsonConverter<ObjectId>
{
public override ObjectId Read(
ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> new(JsonSerializer.Deserialize<int>(ref reader, options));
public override void Write(
Utf8JsonWriter writer, ObjectId value, JsonSerializerOptions options)
=> writer.WriteNumberValue(value.Id);
}
Özel dönüştürücü kullanmak için özniteliğini JsonConverterAttribute türüne uygulayın. Aşağıdaki örnekte, ObjectId
türü, özel dönüştürücüsü olarak ObjectIdConverter
ile yapılandırılır.
[JsonConverter(typeof(ObjectIdConverter))]
public record ObjectId(int Id);
Daha fazla bilgi için Özel dönüştürücüler nasıl yazılır? kısmına bakın.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a ModelMetadata
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ğlamasını veya doğrulamayı devre dışı bırakmak için kullanılabilir.
Belirtilen türdeki tüm modellerde model bağlamayı devre dışı bırakmak için, ExcludeBindingMetadataProvider'e bir Program.cs
ekleyin. Örneğin, türündeki tüm System.Version
modellerde model bağlamayı devre dışı bırakmak için:
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new ExcludeBindingMetadataProvider(typeof(Version)));
options.ModelMetadataDetailsProviders.Add(
new SuppressChildValidationMetadataProvider(typeof(Guid)));
});
Belirtilen türdeki özelliklerde doğrulamayı devre dışı bırakmak için SuppressChildValidationMetadataProvider öğesini Program.cs
içinde ekleyin. Örneğin, türündeki System.Guid
özelliklerde doğrulamayı devre dışı bırakmak için:
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new ExcludeBindingMetadataProvider(typeof(Version)));
options.ModelMetadataDetailsProviders.Add(
new SuppressChildValidationMetadataProvider(typeof(Guid)));
});
Özel model bağlayıcıları
Özel bir model bağlayıcı yazarak ve [ModelBinder]
özniteliğini kullanarak, model bağlamayı belirli bir hedef için seçebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
TryUpdateModelAsync yöntemi kullanılarak model bağlama işlemi manuel olarak başlatılabilir. Yöntem hem ControllerBase
hem de PageModel
sınıflarında tanımlanır. Yöntem aşırı yüklemeleri, kullanılacak ön ek ve değer sağlayıcısını belirtmenize olanak sağlar. Yöntem, model bağlama başarısız olursa döndürür false
. Bir örnek aşağıda verilmiştir:
if (await TryUpdateModelAsync(
newInstructor,
"Instructor",
x => x.Name, x => x.HireDate!))
{
_instructorStore.Add(newInstructor);
return RedirectToPage("./Index");
}
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:
- Fazla gönderimi önlemek için denetleyiciler ve görünümler kullanılarak Sayfalar ve MVC uygulamalarıyla birlikte Razor kullanılır.
- Form verilerinden, sorgu dizelerinden ve yönlendirme verilerinden alınmadıkça bir web API'si ile kullanılmaz. JSON kullanan Web API uç noktaları, istek gövdesini bir nesneye seri durumdan çıkarmak için Giriş biçimlendiricilerini kullanır.
Daha fazla bilgi için bkz . TryUpdateModelAsync.
[FromServices] özniteliği
Bu özniteliğin adı, bir veri kaynağı belirten model bağlama özniteliklerinin desenini izler. Ancak bu, bir değer sağlayıcısından verileri bağlamayla ilgili değildir. Bağımlılık enjeksiyonu kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir metot çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu enjeksiyonuna alternatif sağlamaktır.
Türün bir örneği bağımlılık ekleme kapsayıcısında kayıtlı değilse, uygulama parametresini bağlamaya çalışırken bir özel durum oluşturur. parametresini isteğe bağlı hale getirmek için aşağıdaki yaklaşımlardan birini kullanın:
- Parametreyi null değeri alabilir hale getirin.
- parametresi için varsayılan bir değer ayarlayın.
Null atanabilir parametreler için, parametreye erişmeden önce bu parametrenin olmadığından null
emin olun.
Ek kaynaklar
Bu makalede model bağlamanın ne olduğu, nasıl çalıştığı ve davranışının nasıl özelleştirileceği açıklanmaktadır.
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 gönderilen form alanları modelin özellikleri için değerler sağlayabilir. Bu değerlerin her birini almak ve bunları dizelerden .NET türlerine dönüştürmek için kod yazmak yorucu ve hataya açık olabilir. Model bağlama bu işlemi otomatikleştirir. Model bağlama sistemi:
- Rota verileri, form alanları ve sorgu dizeleri gibi çeşitli kaynaklardan veri alır.
- Yöntem parametrelerinde ve Razor genel özelliklerdeki verileri denetleyiciler ve sayfalara 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)
Uygulama şu URL'ye sahip bir istek alır:
https://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ı
GetById
bir tamsayınınid
ilk parametresini bulur. - HTTP isteğindeki kullanılabilir kaynakları arar ve yol verilerinde = "2" değerini bulur
id
. - "2" dizesini 2 tamsayısına dönüştürür.
- adlı
GetById
bir boole değerinindogsOnly
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. İsim karşılaştırma büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve, GetById
yöntemini çağırarak id
parametresi için 2 ve true
parametresi için dogsOnly
değerini geçirir.
Yukarıdaki ö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. Bu işlemin başarılı olup olmadığını öğrenmek için uygulama ModelState.IsValid bayrağını denetler.
Hedefler
Model bağlama, aşağıdaki hedef türleri için değerleri bulmaya çalışır:
- bir isteğin yönlendirıldığı denetleyici eylem yönteminin parametreleri.
- Bir isteğin yönlendirildiği Pages işleyici yönteminin parametreleri.
- Öznitelikler tarafından belirtilirse, bir denetleyicinin veya
PageModel
sınıfın genel özellikleri.
[BindProperty] özniteliği
Model bağlamanın bu özelliği hedeflemesine neden olmak için bir denetleyicinin veya PageModel
sınıfın ortak özelliğine uygulanabilir:
public class EditModel : PageModel
{
[BindProperty]
public Instructor? Instructor { get; set; }
// ...
}
[BindProperties] özniteliği
Model bağlamasının sınıfın tüm genel özelliklerini hedeflemesini bildirmek için bir denetleyiciye veya PageModel
sınıfa uygulanabilir:
[BindProperties]
public class CreateModel : PageModel
{
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 ihtiyacınız olan tek şey 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 isteklerindeki verilere bağlı özelliklerin olmasını istediğiniz senaryolarda SupportsGet
özelliğini true
olarak ayarlayın.
[BindProperty(Name = "ai_user", SupportsGet = true)]
public string? ApplicationInsightsCookie { get; set; }
Kaynaklar
Varsayılan olarak, model bağlama bir HTTP isteğinde aşağıdaki kaynaklardan anahtar-değer çiftleri biçiminde veri alır:
- Form alanları
- İstek gövdesi ([ApiController] özniteliğine sahip denetleyiciler için.)
- Yol verisi
- Sorgu dizesi parametreleri
- Yüklenen dosyalar
Her hedef parametre veya özellik için kaynaklar, önceki listede belirtilen sırayla taranır. Birkaç özel durum vardır:
- Yönlendirme verileri ve sorgu dizesi değerleri yalnızca basit türler için kullanılır.
- Karşıya yüklenen dosyalar yalnızca
IFormFile
veyaIEnumerable<IFormFile>
uygulayan hedef türlerine bağlıdır.
Varsayılan kaynak doğru değilse, kaynağı belirtmek için aşağıdaki özniteliklerden birini kullanın:
-
[FromQuery]
- Sorgu dizesinden 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 sınıfına değil model özelliklerine ayrı ayrı eklenir:
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. Özellik adının istekteki değerle eşleşmemesi durumunda bu seçenek sağlanır. Örneğin, istekteki değer, adında kısa çizgi bulunan bir başlık olabilir, aşağıdaki örnekte olduğu gibi.
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Bir parametrenin özelliklerini HTTP isteğinin gövdesinden doldurmak için [FromBody]
özniteliğini uygulayın. ASP.NET Core çalışma zamanı, içeriği okuma sorumluluğunu bir giriş biçimlendiricisine devreder. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[FromBody]
, karmaşık bir tür parametresine uygulandığında, bunun özelliklerine ait bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylemi, pet
parametresinin gövdeden doldurulduğunu belirtir:
public ActionResult<Pet> Create([FromBody] Pet pet)
sınıfı, Pet
özelliğinin Breed
bir sorgu dizesi parametresinden doldurulduğunu belirtir:
public class Pet
{
public string Name { get; set; } = null!;
[FromQuery] // Attribute is ignored.
public string Breed { get; set; } = null!;
}
Yukarıdaki örnekte:
-
[FromQuery]
Özniteliği yoksayılır. -
Breed
özelliği bir sorgu dizesi parametresinden doldurulmuyor.
Giriş biçimlendiricileri yalnızca gövdeyi okur ve bağlama kaynak özniteliklerini anlamaz. Gövde içinde uygun bir değer bulunursa, bu değer Breed
özelliğini doldurmak için kullanılır.
Eylem yöntemi başına birden fazla parametreye uygulamayın [FromBody]
. İstek akışı bir giriş biçimlendiricisi tarafından okunduktan sonra, diğer [FromBody]
parametreleri bağlamak için yeniden okunamayacaktır.
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ı yazabilir ve kaydedebilirsiniz. Örneğin, tanımlama bilgilerinden veya oturum durumundan veri isteyebilirsiniz. Yeni bir kaynaktan veri almak için:
-
IValueProvider
uygulayan bir sınıf oluşturun. -
IValueProviderFactory
uygulayan bir sınıf oluşturun. - Fabrika sınıfını
Program.cs
kaydedin.
Örnek, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve üretici örneği içerir.
Program.cs
içinde özel değer sağlayıcı fabrikalarını kaydedin.
builder.Services.AddControllers(options =>
{
options.ValueProviderFactories.Add(new CookieValueProviderFactory());
});
Yukarıdaki kod, özel değer sağlayıcısını tüm yerleşik değer sağlayıcılarının arkasına yerleştirir. Listedeki ilk öğe yapmak için Insert(0, new CookieValueProviderFactory())
yerine Add
öğesini çağırın.
Model özelliği için kaynak yok
Varsayılan olarak, bir model özelliği için değer bulunamazsa model durumu hatası oluşturulmaz. özelliği null veya varsayılan değer olarak ayarlanır:
- Boş değer atanabilir basit türler
null
olarak ayarlanır. - Null olmayan değer türleri
default(T)
olarak ayarlanır. Örneğin, bir parametreint id
0 olarak ayarlanır. - Karmaşık Türler için model bağlama, özellikleri ayarlamadan varsayılan oluşturucuyu kullanarak bir örnek oluşturur.
- Diziler
Array.Empty<T>()
olarak ayarlanır, ancakbyte[]
dizilerinull
olarak ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamadığında model durumunu geçersiz kılmak için [BindRequired]
özniteliğini kullanın.
Bu [BindRequired]
davranışın, bir istek gövdesindeki 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çimlendiricileri tarafından işlenir.
Tür dönüştürme hataları
Bir kaynak bulunur ancak hedef türe dönüştürülemezse, model durumu geçersiz olarak işaretlenir. Hedef parametre veya özellik, önceki bölümde belirtildiği gibi null veya varsayılan değer olarak ayarlanır.
[ApiController]
özniteliğine sahip bir API denetleyicisinde, geçersiz model durumu otomatik olarak HTTP 400 yanıtı verir.
Razor Sayfada bir hata mesajıyla sayfayı yeniden görüntüleyin:
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
// ...
return RedirectToPage("./Index");
}
Sayfa önceki kod tarafından yeniden görüntülendiğinde, form alanında geçersiz giriş gösterilmez. Bunun nedeni model özelliğinin null veya varsayılan değer olarak ayarlanmış olmasıdır. Geçersiz giriş bir hata iletisinde görünüyor. Form alanındaki hatalı verileri yeniden görüntülemek istiyorsanız model özelliğini bir dize haline getirme ve veri dönüştürme işlemini el ile gerçekleştirmeyi göz önünde bulundurun.
Tür dönüştürme hatalarının model durumu hatalarına neden olmasını istemiyorsanız aynı strateji önerilir. Bu durumda, model özelliğini bir dize yapın.
Basit türler
Model bağlayıcısının kaynak dizeleri dönüştürebileceği basit türler şunlardır:
- Boolean
- Bayt, SByte
- Char
- Tarih Saat
- DateTimeOffset
- Ondalık
- Çift
- Sabit Listesi
- GUID
- Int16, Int32, Int64
- Tek
- Zaman Aralığı
- UInt16, UInt32, UInt64
- Urı
- Sürüm
Karmaşık türler
Karmaşık bir türün, bağlanacak genel bir varsayılan oluşturucuya ve genel yazılabilir özelliklerine sahip olması gerekir. Model bağlama gerçekleştiğinde, sınıfın örneği, public varsayılan oluşturucu kullanılarak oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad desenininkaynaklarına bakar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar. Ön ek kullanma kararı, her özellik için ayrı ayrı alınmaz. Örneğin, ?Instructor.Id=100&Name=foo
içeren bir sorgu, OnGet(Instructor instructor)
yöntemine bağlı olarak, türü Instructor
olan elde edilen nesne şunları içerir:
-
Id
olarak100
ayarlayın. -
Name
olaraknull
ayarlayın. Model bağlamasıInstructor.Name
'ün önceki sorgu parametresinde kullanılması nedeniyleInstructor.Id
'ü bekliyor.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak bir özelliğe PageModel
bağlanırken, ön ek ortak özelliğin adıdır. Bazı öznitelikler, parametre veya özellik adının varsayılan kullanımını geçersiz kılmanıza olanak tanıyan bir Prefix
özelliğe sahiptir.
Örneğin, karmaşık türün aşağıdaki Instructor
sınıf olduğunu varsayalım:
public class Instructor
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
Ön ek = parametre adı
Bağlanacak model adlı instructorToUpdate
bir parametreyse:
public IActionResult OnPost(int? id, Instructor instructorToUpdate)
Model bağlama, instructorToUpdate.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Eğer bağlanacak model, denetleyici veya Instructor
sınıfının PageModel
adlı bir özelliğiyse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model, instructorToUpdate
adlı bir parametre olduğunda ve Bind
özniteliği, ön ek olarak Instructor
'yi belirtiyorsa:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Karmaşık tür hedefleri için öznitelikler
Karmaşık türlerin model bağlamasını denetlemek için çeşitli yerleşik öznitelikler kullanılabilir:
Uyarı
Bu öznitelikler, form verileri gönderildiğinde değerlerin kaynağı olarak model bağlamasını etkiler. Bunlar, gönderilen JSON ve XML istek gövdelerini işleyen giriş biçimlendiricilerini etkilemez. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[Bind] özelliği
Bir sınıfa veya yöntem parametresine uygulanabilir. Modelin hangi özelliklerinin model bağlamaya dahil edilmesi gerektiğini belirtir.
[Bind]
giriş biçimlendiricilerini etkilemez.
Aşağıdaki örnekte, herhangi bir işleyici veya eylem yöntemi çağrıldığında yalnızca modelin Instructor
belirtilen özellikleri bağlıdır:
[Bind("LastName,FirstMidName,HireDate")]
public class Instructor
Aşağıdaki örnekte, Instructor
yöntemi çağrıldığında yalnızca OnPost
modelinin belirtilen özellikleri bağlanır.
[HttpPost]
public IActionResult OnPost(
[Bind("LastName,FirstMidName,HireDate")] Instructor instructor)
[Bind]
özniteliği, oluşturma senaryolarında aşırı paylaşıma karşı koruma sağlamak için kullanılabilir. Dışlanan özellikler değiştirilmeden bırakılmak yerine null veya varsayılan değer olarak ayarlandığından, düzenleme senaryolarında düzgün çalışmaz. Aşırı paylaşıma karşı korunma için, [Bind]
özniteliği yerine görünüm modelleri önerilir. Daha fazla bilgi için bkz . Fazla paylaşımla 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ının türünü belirtmeye olanak tanır. Örneğin:
[HttpPost]
public IActionResult OnPost(
[ModelBinder(typeof(MyInstructorModelBinder))] Instructor instructor)
Özniteliği, [ModelBinder]
modele bağlı olduğunda 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; }
// ...
}
[BindRequired] özniteliği
Bir modelin özelliği için bağlantı kurulamıyorsa, model durumuna bir hata eklenmesine neden olur. Bir örnek aşağıda verilmiştir:
public class InstructorBindRequired
{
// ...
[BindRequired]
public DateTime HireDate { get; set; }
}
Ayrıca Bkz. Model doğrulamasında [Required]
özniteliğin tartışması.
[BindNever] özniteliği
Bir özelliğe veya türe uygulanabilir. Model bağlamasının bir modelin özelliğini ayarlamasını engeller. Bir türe uygulandığında, model bağlama sistemi türün tanımladığı tüm özellikleri dışlar. Bir örnek aşağıda verilmiştir:
public class InstructorBindNever
{
[BindNever]
public int Id { get; set; }
// ...
}
Koleksiyonlar
Basit tür koleksiyonları olan hedefler için model bağlama, parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Bağlanacak parametrenin adlı
selectedCourses
bir dizi olduğunu varsayalım:public IActionResult OnPost(int? id, int[] selectedCourses)
Form veya sorgu dizesi verileri aşağıdaki biçimlerden birinde 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
Adı
index
veyaIndex
olan bir parametreyi ya da özelliği bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlama,index
öğesini koleksiyon için bir dizin olarak kullanmaya çalışır ve bu da yanlış bağlamaya yol açabilir. Örneğin, aşağıdaki eylemi göz önünde bulundurun:public IActionResult Post(string index, List<Product> products)
Yukarıdaki kodda
index
sorgu dizesi parametresi yöntem parametresineindex
bağlanır ve ayrıca ürün koleksiyonunu bağlamak için kullanılır. Parametrenin yeniden adlandırılması veya bağlamayıindex
yapılandırmak için bir model bağlama özniteliği kullanılması bu sorunu önler:public IActionResult Post(string productIndex, List<Product> products)
Aşağıdaki biçim yalnızca form verilerinde desteklenir:
selectedCourses[]=1050&selectedCourses[]=2000
Önceki tüm örnek biçimler için, model bağlama parametresine
selectedCourses
iki öğeden oluşan bir dizi geçirir:- selectedCourses[0]=1050
- selectedCourses[1]=2000
Alt simge numaraları kullanan veri biçimleri (... [0] ... [1] ...) sıfırdan başlayarak sıralı olarak numaralandırıldığından emin olmalıdır. Alt simge numaralandırmasında boşluk varsa, boşluktan sonraki 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
Dictionary
hedefleri için, model bağlama parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adı
Dictionary<int, string>
olan birselectedCourses
olduğunu varsayalım.public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
Gönderilen form veya sorgu dizesi verileri aşağıdaki örneklerden biri gibi görünebilir:
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 tüm örnek biçimler için model bağlama parametresine
selectedCourses
iki öğeden oluşan bir sözlük geçirir:- selectedCourses["1050"]="Kimya"
- selectedCourses["2000"]="Ekonomi"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir.
System.Text.Json
ve Newtonsoft.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarılmasını destekler.
Kayıt türleri, ağ üzerinden verileri kısa bir şekilde temsil etmenin harika bir yoludur. ASP.NET Core, tek bir oluşturucuyla model bağlamayı ve kayıt türlerini doğrulamayı destekler:
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
<label>Name: <input asp-for="Name" /></label>
<br />
<label>Age: <input asp-for="Age" /></label>
Kayıt türleri doğrulanırken çalışma zamanı, özellikle özellikler yerine parametrelerde bağlama ve doğrulama meta verilerini arar.
Çerçeve, kayıt türlerini bağlamaya ve doğrulamaya olanak tanır:
public record Person([Required] string Name, [Range(0, 100)] int Age);
Öncekinin çalışması için türün şunları yapması gerekir:
- Bir kayıt türü oluşturun.
- Tam olarak bir genel oluşturucuya sahip olun.
- Aynı isim ve türde bir özelliği olan parametreleri içerir. Adların büyük/küçük harfe göre farklılık göstermemesi gerekir.
Parametresiz oluşturucuları olmayan POCO'lar
Parametresiz oluşturucuları olmayan POCO'lar bağlanamaz.
Aşağıdaki kod, türün parametresiz bir oluşturucuya sahip olması gerektiğini belirten bir özel durumla sonuçlanır.
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 yazılmış oluşturucularla kayıt türleri
Manuel olarak yazılmış ve birincil oluşturuculara benzeyen oluşturucuların çalıştığı 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 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ğerini okumak için özelliğini kullanır. Birincil yapıcılarla normal koşullarda, ikisi aynı olacaktır. Ancak, bunu yenmenin yolları vardır:
public record Person([Required] string Name)
{
private readonly string _name;
// The following property is never null.
// However this object could have been constructed as "new Person(null)".
public string Name { get; init => _name = value ?? string.Empty; }
}
TryUpdateModel bir kayıt türündeki 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ştirilmeye izin verilir
Model bağlama yönlendirme verilerinin ve sorgu dizelerinin 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ı beklenir.
Buna karşılık, form verilerinden gelen değerler kültüre duyarlı bir dönüştürmeden geçer. Bu, URL'lerin yerel ayarlar arasında paylaşılabilir olması için tasarım gereğidir.
ASP.NET Core yol değeri sağlayıcısının ve sorgu dizesi değer sağlayıcısının kültüre duyarlı bir dönüştürmeden geçirilmesini sağlamak için:
- IValueProviderFactory'den Devral
- QueryStringValueProviderFactory veya RouteValueValueProviderFactory'den kodu kopyalayın
- Değer sağlayıcısı oluşturucusna geçirilen kültür değerini CultureInfo.CurrentCulture ile değiştirin
- MVC seçeneklerindeki varsayılan değer sağlayıcısı fabrikasını yenisiyle değiştirin:
public class CultureQueryStringValueProviderFactory : IValueProviderFactory
{
public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
{
_ = context ?? throw new ArgumentNullException(nameof(context));
var query = context.ActionContext.HttpContext.Request.Query;
if (query?.Count > 0)
{
context.ValueProviders.Add(
new QueryStringValueProvider(
BindingSource.Query,
query,
CultureInfo.CurrentCulture));
}
return Task.CompletedTask;
}
}
builder.Services.AddControllers(options =>
{
var index = options.ValueProviderFactories.IndexOf(
options.ValueProviderFactories.OfType<QueryStringValueProviderFactory>()
.Single());
options.ValueProviderFactories[index] =
new CultureQueryStringValueProviderFactory();
});
Özel veri türleri
Model bağlamanın işleyebileceği bazı özel veri türleri vardır.
IFormFile ve IFormFileCollection
HTTP isteğine eklenen yüklenmiş bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
İptal Belirteci
Eylemler isteğe bağlı olarak bir CancellationToken
’yi parametre olarak bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyal veren RequestAborted öğesine bağlanır. 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.
Form Koleksiyonu
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biçimlendiricileri
İ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çimlendirici kullanır. varsayılan olarak ASP.NET Core, JSON verilerini işlemek için JSON tabanlı giriş biçimlendiricileri içerir. Diğer içerik türleri için başka biçimlendiriciler ekleyebilirsiniz.
ASP.NET Core, Consumes özniteliğine göre giriş biçimlendiricilerini seçer. Öznitelik yoksa İçerik Türü üst bilgisini kullanır.
Yerleşik XML giriş biçimlendiricilerini kullanmak için:
Program.cs
içinde, AddXmlSerializerFormatters veya AddXmlDataContractSerializerFormatters öğesini arayın.builder.Services.AddControllers() .AddXmlSerializerFormatters();
Denetleyici sınıflarına veya istek gövdesinde
Consumes
XML bekleyen eylem yöntemlerine özniteliğini uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileştirmeye Giriş.
Giriş biçimlendiricileri ile model bağlamayı özelleştirme
Giriş biçimlendiricisi, istek gövdesinden veri okumanın tüm sorumluluğunu alır. Bu işlemi özelleştirmek için giriş biçimlendiricisi tarafından kullanılan API'leri yapılandırın. Bu bölüm, System.Text.Json
tabanlı giriş biçimlendiricisinin, ObjectId
adlı özel bir türü anlaması için nasıl özelleştirileceğini açıklar.
Özel ObjectId
bir özellik içeren aşağıdaki modeli göz önünde bulundurun:
public class InstructorObjectId
{
[Required]
public ObjectId ObjectId { get; set; } = null!;
}
System.Text.Json
kullanırken model bağlama işlemini özelleştirmek için JsonConverter<T> öğesinden türetilmiş bir sınıf oluşturun.
internal class ObjectIdConverter : JsonConverter<ObjectId>
{
public override ObjectId Read(
ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> new(JsonSerializer.Deserialize<int>(ref reader, options));
public override void Write(
Utf8JsonWriter writer, ObjectId value, JsonSerializerOptions options)
=> writer.WriteNumberValue(value.Id);
}
Özel dönüştürücü kullanmak için özniteliğini JsonConverterAttribute türüne uygulayın. Aşağıdaki örnekte, ObjectId
türü, özel dönüştürücüsü olarak ObjectIdConverter
ile yapılandırılır.
[JsonConverter(typeof(ObjectIdConverter))]
public record ObjectId(int Id);
Daha fazla bilgi için Özel dönüştürücüler nasıl yazılır? kısmına bakın.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a ModelMetadata
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ğlamasını veya doğrulamayı devre dışı bırakmak için kullanılabilir.
Belirtilen türdeki tüm modellerde model bağlamayı devre dışı bırakmak için, ExcludeBindingMetadataProvider'e bir Program.cs
ekleyin. Örneğin, türündeki tüm System.Version
modellerde model bağlamayı devre dışı bırakmak için:
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new ExcludeBindingMetadataProvider(typeof(Version)));
options.ModelMetadataDetailsProviders.Add(
new SuppressChildValidationMetadataProvider(typeof(Guid)));
});
Belirtilen türdeki özelliklerde doğrulamayı devre dışı bırakmak için SuppressChildValidationMetadataProvider öğesini Program.cs
içinde ekleyin. Örneğin, türündeki System.Guid
özelliklerde doğrulamayı devre dışı bırakmak için:
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new ExcludeBindingMetadataProvider(typeof(Version)));
options.ModelMetadataDetailsProviders.Add(
new SuppressChildValidationMetadataProvider(typeof(Guid)));
});
Özel model bağlayıcıları
Özel bir model bağlayıcı yazarak ve [ModelBinder]
özniteliğini kullanarak, model bağlamayı belirli bir hedef için seçebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
TryUpdateModelAsync yöntemi kullanılarak model bağlama işlemi manuel olarak başlatılabilir. Yöntem hem ControllerBase
hem de PageModel
sınıflarında tanımlanır. Yöntem aşırı yüklemeleri, kullanılacak ön ek ve değer sağlayıcısını belirtmenize olanak sağlar. Yöntem, model bağlama başarısız olursa döndürür false
. Bir örnek aşağıda verilmiştir:
if (await TryUpdateModelAsync(
newInstructor,
"Instructor",
x => x.Name, x => x.HireDate!))
{
_instructorStore.Add(newInstructor);
return RedirectToPage("./Index");
}
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:
- Fazla gönderimi önlemek için denetleyiciler ve görünümler kullanılarak Sayfalar ve MVC uygulamalarıyla birlikte Razor kullanılır.
- Form verilerinden, sorgu dizelerinden ve yönlendirme verilerinden alınmadıkça bir web API'si ile kullanılmaz. JSON kullanan Web API uç noktaları, istek gövdesini bir nesneye seri durumdan çıkarmak için Giriş biçimlendiricilerini kullanır.
Daha fazla bilgi için bkz . TryUpdateModelAsync.
[FromServices] özniteliği
Bu özniteliğin adı, bir veri kaynağı belirten model bağlama özniteliklerinin desenini izler. Ancak bu, bir değer sağlayıcısından verileri bağlamayla ilgili değildir. Bağımlılık enjeksiyonu kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir metot çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu enjeksiyonuna alternatif sağlamaktır.
Türün bir örneği bağımlılık ekleme kapsayıcısında kayıtlı değilse, uygulama parametresini bağlamaya çalışırken bir özel durum oluşturur. parametresini isteğe bağlı hale getirmek için aşağıdaki yaklaşımlardan birini kullanın:
- Parametreyi null değeri alabilir hale getirin.
- parametresi için varsayılan bir değer ayarlayın.
Null atanabilir parametreler için, parametreye erişmeden önce bu parametrenin olmadığından null
emin olun.
Ek kaynaklar
Bu makalede model bağlamanın ne olduğu, nasıl çalıştığı ve davranışının nasıl özelleştirileceği açıklanmaktadır.
Örnek kodu görüntüleme veya indirme (indirme).
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 gönderilen form alanları modelin özellikleri için değerler sağlayabilir. Bu değerlerin her birini almak ve bunları dizelerden .NET türlerine dönüştürmek için kod yazmak yorucu ve hataya açık olabilir. Model bağlama bu işlemi otomatikleştirir. Model bağlama sistemi:
- Rota verileri, form alanları ve sorgu dizeleri gibi çeşitli kaynaklardan veri alır.
- Yöntem parametrelerinde ve Razor genel özelliklerdeki verileri denetleyiciler ve sayfalara 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)
Uygulama şu URL'ye sahip bir istek alır:
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ı
GetById
bir tamsayınınid
ilk parametresini bulur. - HTTP isteğindeki kullanılabilir kaynakları arar ve yol verilerinde = "2" değerini bulur
id
. - "2" dizesini 2 tamsayısına dönüştürür.
- adlı
GetById
bir boole değerinindogsOnly
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. İsim karşılaştırma büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve, GetById
yöntemini çağırarak id
parametresi için 2 ve true
parametresi için dogsOnly
değerini geçirir.
Yukarıdaki ö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. Bu işlemin başarılı olup olmadığını öğrenmek için uygulama ModelState.IsValid bayrağını denetler.
Hedefler
Model bağlama, aşağıdaki hedef türleri için değerleri bulmaya çalışır:
- bir isteğin yönlendirıldığı denetleyici eylem yönteminin parametreleri.
- Bir isteğin yönlendirildiği Pages işleyici yönteminin parametreleri.
- Öznitelikler tarafından belirtilirse, bir denetleyicinin veya
PageModel
sınıfın genel özellikleri.
[BindProperty] özniteliği
Model bağlamanın bu özelliği hedeflemesine neden olmak için bir denetleyicinin veya PageModel
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 veya sonraki sürümlerde kullanılabilir. Model bağlamasının sınıfın tüm genel özelliklerini hedeflemesini bildirmek için bir denetleyiciye veya PageModel
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 ihtiyacınız olan tek şey 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 isteklerindeki verilere bağlı özelliklerin olmasını istediğiniz senaryolarda SupportsGet
özelliğini true
olarak ayarlayın.
[BindProperty(Name = "ai_user", SupportsGet = true)]
public string ApplicationInsightsCookie { get; set; }
Kaynaklar
Varsayılan olarak, model bağlama bir HTTP isteğinde aşağıdaki kaynaklardan anahtar-değer çiftleri biçiminde veri alır:
- Form alanları
- İstek gövdesi ([ApiController] özniteliğine sahip denetleyiciler için.)
- Yol verisi
- Sorgu dizesi parametreleri
- Yüklenen dosyalar
Her hedef parametre veya özellik için kaynaklar, önceki listede belirtilen sırayla taranır. Birkaç özel durum vardır:
- Yönlendirme verileri ve sorgu dizesi değerleri yalnızca basit türler için kullanılır.
- Karşıya yüklenen dosyalar yalnızca
IFormFile
veyaIEnumerable<IFormFile>
uygulayan hedef türlerine bağlıdır.
Varsayılan kaynak doğru değilse, kaynağı belirtmek için aşağıdaki özniteliklerden birini kullanın:
-
[FromQuery]
- Sorgu dizesinden 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 ayrı ayrı 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 edin. Özellik adının istekteki değerle eşleşmemesi durumunda bu seçenek sağlanır. Örneğin, istekteki değer, adında kısa çizgi bulunan bir başlık olabilir, aşağıdaki örnekte olduğu gibi.
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Bir parametrenin özelliklerini HTTP isteğinin gövdesinden doldurmak için [FromBody]
özniteliğini uygulayın. ASP.NET Core çalışma zamanı, içeriği okuma sorumluluğunu bir giriş biçimlendiricisine devreder. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[FromBody]
, karmaşık bir tür parametresine uygulandığında, bunun özelliklerine ait bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylemi, pet
parametresinin gövdeden doldurulduğunu belirtir:
public ActionResult<Pet> Create([FromBody] Pet pet)
sınıfı, Pet
özelliğinin Breed
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]
Özniteliği yoksayılır. -
Breed
özelliği bir sorgu dizesi parametresinden doldurulmuyor.
Giriş biçimlendiricileri yalnızca gövdeyi okur ve bağlama kaynak özniteliklerini anlamaz. Gövde içinde uygun bir değer bulunursa, bu değer Breed
özelliğini doldurmak için kullanılır.
Eylem yöntemi başına birden fazla parametreye uygulamayın [FromBody]
. İstek akışı bir giriş biçimlendiricisi tarafından okunduktan sonra, diğer [FromBody]
parametreleri bağlamak için yeniden okunamayacaktır.
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ı yazabilir ve kaydedebilirsiniz. Örneğin, tanımlama bilgilerinden veya oturum durumundan veri isteyebilirsiniz. Yeni bir kaynaktan veri almak için:
-
IValueProvider
uygulayan bir sınıf oluşturun. -
IValueProviderFactory
uygulayan bir sınıf oluşturun. - Fabrika sınıfını
Startup.ConfigureServices
kaydedin.
Örnek uygulama, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve fabrika örneği içerir. kayıt kodu şu şekildedir Startup.ConfigureServices
:
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 arkasına yerleştirir. Listedeki ilk öğe yapmak için Insert(0, new CookieValueProviderFactory())
yerine Add
öğesini çağırın.
Model özelliği için kaynak yok
Varsayılan olarak, bir model özelliği için değer bulunamazsa model durumu hatası oluşturulmaz. özelliği null veya varsayılan değer olarak ayarlanır:
- Boş değer atanabilir basit türler
null
olarak ayarlanır. - Null olmayan değer türleri
default(T)
olarak ayarlanır. Örneğin, bir parametreint id
0 olarak ayarlanır. - Karmaşık Türler için model bağlama, özellikleri ayarlamadan varsayılan oluşturucuyu kullanarak bir örnek oluşturur.
- Diziler
Array.Empty<T>()
olarak ayarlanır, ancakbyte[]
dizilerinull
olarak ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamadığında model durumunu geçersiz kılmak için [BindRequired]
özniteliğini kullanın.
Bu [BindRequired]
davranışın, bir istek gövdesindeki 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çimlendiricileri tarafından işlenir.
Tür dönüştürme hataları
Bir kaynak bulunur ancak hedef türe dönüştürülemezse, model durumu geçersiz olarak işaretlenir. Hedef parametre veya özellik, önceki bölümde belirtildiği gibi null veya varsayılan değer olarak ayarlanır.
[ApiController]
özniteliğine sahip bir API denetleyicisinde, geçersiz model durumu otomatik olarak HTTP 400 yanıtı verir.
Razor Sayfada bir hata mesajıyla sayfayı yeniden görüntüleyin:
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
_instructorsInMemoryStore.Add(Instructor);
return RedirectToPage("./Index");
}
Client-side doğrulama, aksi halde Razor Sayfalar formuna gönderilebilecek hatalı verilerin çoğunu tespit eder. Bu doğrulama, önceki vurgulanan kodu tetiklemesini zorlaştırır. Örnek uygulama, hatalı verileri İşe Alma Tarihi alanına yerleştiren ve formu gönderen Geçersiz Tarih ile Gönder düğmesini içerir. Bu düğme, veri dönüştürme hataları oluştuğunda sayfayı yeniden dağıtma kodunun nasıl çalıştığını gösterir.
Sayfa önceki kod tarafından yeniden görüntülendiğinde, form alanında geçersiz giriş gösterilmez. Bunun nedeni model özelliğinin null veya varsayılan değer olarak ayarlanmış olmasıdır. Geçersiz giriş bir hata iletisinde görünüyor. Ancak, form alanındaki hatalı verileri yeniden görüntülemek istiyorsanız model özelliğini bir dize haline getirme ve veri dönüştürme işlemini el ile gerçekleştirmeyi göz önünde bulundurun.
Tür dönüştürme hatalarının model durumu hatalarına neden olmasını istemiyorsanız aynı strateji önerilir. Bu durumda, model özelliğini bir dize yapın.
Basit türler
Model bağlayıcısının kaynak dizeleri dönüştürebileceği basit türler şunlardır:
- Boolean
- Bayt, SByte
- Char
- Tarih Saat
- DateTimeOffset
- Ondalık
- Çift
- Sabit Listesi
- GUID
- Int16, Int32, Int64
- Tek
- Zaman Aralığı
- UInt16, UInt32, UInt64
- Urı
- Sürüm
Karmaşık türler
Karmaşık bir türün, bağlanacak genel bir varsayılan oluşturucuya ve genel yazılabilir özelliklerine sahip olması gerekir. Model bağlama gerçekleştiğinde, sınıfın örneği, public varsayılan oluşturucu kullanılarak oluşturulur.
Her karmaşık tür özelliği için model bağlama, prefix.property_name ad desenini kaynaklarda arar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak bir özelliğe PageModel
bağlanırken, ön ek ortak özelliğin adıdır. Bazı öznitelikler, parametre veya özellik adının varsayılan kullanımını geçersiz kılmanıza olanak tanıyan bir Prefix
özelliğe sahiptir.
Örneğin, karmaşık türün aşağıdaki Instructor
sınıf olduğunu varsayalım:
public class Instructor
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
Ön ek = parametre adı
Bağlanacak model adlı instructorToUpdate
bir parametreyse:
public IActionResult OnPost(int? id, Instructor instructorToUpdate)
Model bağlama, instructorToUpdate.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Eğer bağlanacak model, denetleyici veya Instructor
sınıfının PageModel
adlı bir özelliğiyse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model, instructorToUpdate
adlı bir parametre olduğunda ve Bind
özniteliği, ön ek olarak Instructor
'yi belirtiyorsa:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, Instructor.ID
anahtarını kaynaklar arasında arayarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Karmaşık tür hedefleri için öznitelikler
Karmaşık türlerin model bağlamasını denetlemek için çeşitli yerleşik öznitelikler kullanılabilir:
[Bind]
[BindRequired]
[BindNever]
Uyarı
Bu öznitelikler, form verileri gönderildiğinde değerlerin kaynağı olarak model bağlamasını etkiler. Bunlar, gönderilen JSON ve XML istek gövdelerini işleyen giriş biçimlendiricilerini etkilemez. Giriş biçimlendiricileri bu makalenin ilerleyen bölümlerinde açıklanmıştır.
[Bind] özelliği
Bir sınıfa veya yöntem parametresine uygulanabilir. Modelin hangi özelliklerinin model bağlamaya dahil edilmesi gerektiğini belirtir.
[Bind]
giriş biçimlendiricilerini etkilemez.
Aşağıdaki örnekte, herhangi bir işleyici veya eylem yöntemi çağrıldığında yalnızca modelin Instructor
belirtilen özellikleri bağlıdır:
[Bind("LastName,FirstMidName,HireDate")]
public class Instructor
Aşağıdaki örnekte, Instructor
yöntemi çağrıldığında yalnızca OnPost
modelinin belirtilen özellikleri bağlanır.
[HttpPost]
public IActionResult OnPost([Bind("LastName,FirstMidName,HireDate")] Instructor instructor)
[Bind]
özniteliği, oluşturma senaryolarında aşırı paylaşıma karşı koruma sağlamak için kullanılabilir. Dışlanan özellikler değiştirilmeden bırakılmak yerine null veya varsayılan değer olarak ayarlandığından, düzenleme senaryolarında düzgün çalışmaz. Aşırı paylaşıma karşı korunma için, [Bind]
özniteliği yerine görünüm modelleri önerilir. Daha fazla bilgi için bkz . Fazla paylaşımla 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ının türünü belirtmeye olanak tanır. Örneğin:
[HttpPost]
public IActionResult OnPost([ModelBinder(typeof(MyInstructorModelBinder))] Instructor instructor)
Özniteliği, [ModelBinder]
modele bağlı olduğunda 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. Bir modelin özelliği için bağlantı kurulamıyorsa, model durumuna bir hata eklenmesine neden olur. Bir örnek aşağıda 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 Bkz. Model doğrulamasında [Required]
özniteliğin tartışması.
[BindNever] özniteliği
Yöntem parametrelerine değil, yalnızca model özelliklerine uygulanabilir. Model bağlamasının bir modelin özelliğini ayarlamasını engeller. Bir örnek aşağıda verilmiştir:
public class InstructorWithDictionary
{
[BindNever]
public int ID { get; set; }
Koleksiyonlar
Basit tür koleksiyonları olan hedefler için model bağlama, parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Bağlanacak parametrenin adlı
selectedCourses
bir dizi olduğunu varsayalım:public IActionResult OnPost(int? id, int[] selectedCourses)
Form veya sorgu dizesi verileri aşağıdaki biçimlerden birinde 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
Adı
index
veyaIndex
olan bir parametreyi ya da özelliği bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlama,index
öğesini koleksiyon için bir dizin olarak kullanmaya çalışır ve bu da yanlış bağlamaya yol açabilir. Örneğin, aşağıdaki eylemi göz önünde bulundurun:public IActionResult Post(string index, List<Product> products)
Yukarıdaki kodda
index
sorgu dizesi parametresi yöntem parametresineindex
bağlanır ve ayrıca ürün koleksiyonunu bağlamak için kullanılır. Parametrenin yeniden adlandırılması veya bağlamayıindex
yapılandırmak için bir model bağlama özniteliği kullanılması bu sorunu önler:public IActionResult Post(string productIndex, List<Product> products)
Aşağıdaki biçim yalnızca form verilerinde desteklenir:
selectedCourses[]=1050&selectedCourses[]=2000
Önceki tüm örnek biçimler için, model bağlama parametresine
selectedCourses
iki öğeden oluşan bir dizi geçirir:- selectedCourses[0]=1050
- seçilenKurslar[1]=2000
Alt simge numaraları kullanan veri biçimleri (... [0] ... [1] ...) sıfırdan başlayarak sıralı olarak numaralandırıldığından emin olmalıdır. Alt simge numaralandırmasında boşluk varsa, boşluktan sonraki 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
Dictionary
hedefleri için, model bağlama parameter_name veya property_name eşleşmelerini arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adı
Dictionary<int, string>
olan birselectedCourses
olduğunu varsayalım.public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
Gönderilen form veya sorgu dizesi verileri aşağıdaki örneklerden biri gibi görünebilir:
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 tüm örnek biçimler için model bağlama parametresine
selectedCourses
iki öğeden oluşan bir sözlük geçirir:- selectedCourses["1050"]="Kimya"
- selectedCourses["2000"]="Ekonomi"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir.
System.Text.Json
ve Newtonsoft.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarılmasını destekler.
C# 9, ağ üzerinden verileri kısa bir şekilde temsil etmenin harika bir yolu olan kayıt türlerini tanıtır. 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
<label>Name: <input asp-for="Name" /></label>
...
<label>Age: <input asp-for="Age" /></label>
Kayıt türleri doğrulanırken çalışma zamanı, özellikle özellikler yerine parametrelerde bağlama ve doğrulama meta verilerini arar.
Çerçeve, kayıt türlerini bağlamaya ve doğrulamaya olanak tanır:
public record Person([Required] string Name, [Range(0, 100)] int Age);
Öncekinin çalışması için türün şunları yapması gerekir:
- Bir kayıt türü oluşturun.
- Tam olarak bir genel oluşturucuya sahip olun.
- Aynı isim ve türde bir özelliği olan parametreleri içerir. Adların büyük/küçük harfe göre farklılık göstermemesi gerekir.
Parametresiz oluşturucuları olmayan POCO'lar
Parametresiz oluşturucuları olmayan POCO'lar bağlanamaz.
Aşağıdaki kod, türün parametresiz bir oluşturucuya sahip olması gerektiğini belirten bir özel durumla sonuçlanır.
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 yazılmış oluşturucularla kayıt türleri
Manuel olarak yazılmış ve birincil oluşturuculara benzeyen oluşturucuların çalıştığı 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 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ğerini okumak için özelliğini kullanır. Birincil yapıcılarla normal koşullarda, ikisi aynı olacaktır. Ancak, bunu yenmenin 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ündeki 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ştirilmeye izin verilir
Model bağlama yönlendirme verilerinin ve sorgu dizelerinin 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ı beklenir.
Buna karşılık, form verilerinden gelen değerler kültüre duyarlı bir dönüştürmeden geçer. Bu, URL'lerin yerel ayarlar arasında paylaşılabilir olması için tasarım gereğidir.
ASP.NET Core yol değeri sağlayıcısının ve sorgu dizesi değer sağlayıcısının kültüre duyarlı bir dönüştürmeden geçirilmesini sağlamak için:
- IValueProviderFactory'den Devral
- QueryStringValueProviderFactory veya RouteValueValueProviderFactory'den kodu kopyalayın
- Değer sağlayıcısı oluşturucusna geçirilen kültür değerini CultureInfo.CurrentCulture ile değiştirin
- MVC seçeneklerindeki varsayılan değer sağlayıcısı fabrikasını yenisiyle değiştirin:
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şleyebileceği bazı özel veri türleri vardır.
IFormFile ve IFormFileCollection
HTTP isteğine eklenen yüklenmiş bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
İptal Belirteci
Eylemler isteğe bağlı olarak bir CancellationToken
’yi parametre olarak bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyal veren RequestAborted öğesine bağlanır. 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.
Form Koleksiyonu
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biçimlendiricileri
İ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çimlendirici kullanır. varsayılan olarak ASP.NET Core, JSON verilerini işlemek için JSON tabanlı giriş biçimlendiricileri içerir. Diğer içerik türleri için başka biçimlendiriciler ekleyebilirsiniz.
ASP.NET Core, Consumes özniteliğine göre giriş biçimlendiricilerini seçer. Öznitelik yoksa İçerik Türü üst bilgisini kullanır.
Yerleşik XML giriş biçimlendiricilerini kullanmak için:
Microsoft.AspNetCore.Mvc.Formatters.Xml
NuGet paketini yükleyin.Startup.ConfigureServices
içinde, AddXmlSerializerFormatters veya AddXmlDataContractSerializerFormatters öğesini arayın.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();
Denetleyici sınıflarına veya istek gövdesinde
Consumes
XML bekleyen eylem yöntemlerine özniteliğini uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileştirmeye Giriş.
Giriş biçimlendiricileri ile model bağlamayı özelleştirme
Giriş biçimlendiricisi, istek gövdesinden veri okumanın tüm sorumluluğunu alır. Bu işlemi özelleştirmek için giriş biçimlendiricisi tarafından kullanılan API'leri yapılandırın. Bu bölüm, System.Text.Json
tabanlı giriş biçimlendiricisinin, ObjectId
adlı özel bir türü anlaması için nasıl özelleştirileceğini açıklar.
Aşağıdaki model, özel bir ObjectId
özelliği olan Id
içerir.
public class ModelWithObjectId
{
public ObjectId Id { get; set; }
}
System.Text.Json
kullanırken model bağlama işlemini özelleştirmek için JsonConverter<T> öğesinden türetilmiş bir sınıf 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 dönüştürücü kullanmak için özniteliğini JsonConverterAttribute türüne uygulayın. Aşağıdaki örnekte, ObjectId
türü, özel dönüştürücüsü olarak ObjectIdConverter
ile 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 Özel dönüştürücüler nasıl yazılır? kısmına bakın.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a ModelMetadata
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ğlamasını veya doğrulamayı devre dışı bırakmak için kullanılabilir.
Belirtilen türdeki tüm modellerde model bağlamayı devre dışı bırakmak için, ExcludeBindingMetadataProvider'e bir Startup.ConfigureServices
ekleyin. Örneğin, türündeki tüm System.Version
modellerde model bağlamayı devre dışı bırakmak 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ürdeki özelliklerde doğrulamayı devre dışı bırakmak için SuppressChildValidationMetadataProvider öğesini Startup.ConfigureServices
içinde ekleyin. Örneğin, türündeki System.Guid
özelliklerde doğrulamayı devre dışı bırakmak 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ı yazarak ve [ModelBinder]
özniteliğini kullanarak, model bağlamayı belirli bir hedef için seçebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
TryUpdateModelAsync yöntemi kullanılarak model bağlama işlemi manuel olarak başlatılabilir. Yöntem hem ControllerBase
hem de PageModel
sınıflarında tanımlanır. Yöntem aşırı yüklemeleri, kullanılacak ön ek ve değer sağlayıcısını belirtmenize olanak sağlar. Yöntem, model bağlama başarısız olursa döndürür false
. Bir örnek aşağıda 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:
- Fazla gönderimi önlemek için denetleyiciler ve görünümler kullanılarak Sayfalar ve MVC uygulamalarıyla birlikte Razor kullanılır.
- Form verilerinden, sorgu dizelerinden ve yönlendirme verilerinden alınmadıkça bir web API'si ile kullanılmaz. JSON kullanan Web API uç noktaları, istek gövdesini bir nesneye seri durumdan çıkarmak için Giriş biçimlendiricilerini kullanır.
Daha fazla bilgi için bkz . TryUpdateModelAsync.
[FromServices] özniteliği
Bu özniteliğin adı, bir veri kaynağı belirten model bağlama özniteliklerinin desenini izler. Ancak bu, bir değer sağlayıcısından verileri bağlamayla ilgili değildir. Bağımlılık enjeksiyonu kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir metot çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu enjeksiyonuna alternatif sağlamaktır.
Ek kaynaklar
ASP.NET Core