ASP.NET Core'da Model Bağlama
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 8 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, yol verileri bir kayıt anahtarı sağlayabilir ve deftere nakledilmiş 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.
- Verileri, yöntem parametrelerinde ve Razor genel özelliklerde denetleyicilere 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ı
id
bir tamsayınınGetById
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ı
dogsOnly
bir boole değerininGetById
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. Ad eşleştirme büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve daha sonra parametresi için true
dogsOnly
ve parametresi için id
2'yi geçirerek yöntemini çağırırGetById
.
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 Razor yönlendirıldığı 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 özelliğini olarak true
ayarlayınSupportsGet
:
[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, veya TryParse
yöntemi kullanılarak TypeConverter 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, veya TypeConverter
TryParse
varlığını temel alarak farkı belirler. Bir tür dönüştürücüsü oluşturmanızı veya dış kaynaklar veya birden çok giriş gerektirmeyen bir string
SomeType
dönüştürme için kullanmanızı TryParse
ö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.)
- Veri yönlendirme
- Sorgu dizesi parametreleri
- Karşıya 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 veya
IEnumerable<IFormFile>
uygulayanIFormFile
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]
- Deftere nakledilen 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, aşağıdaki örnekte olduğu gibi adında kısa çizgi bulunan bir üst bilgi olabilir:
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Özelliklerini bir HTTP isteğinin [FromBody]
gövdesinden doldurmak için özniteliğini bir parametreye uygulayın. ASP.NET Core çalışma zamanı, gövdeyi 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, özelliklerine uygulanan bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylem parametresinin gövdeden doldurulduğunu pet
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övdede uygun bir değer bulunursa, bu değer özelliği doldurmak Breed
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ı'na
Program.cs
kaydedin.
Örnek, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve fabrika örneği içerir. özel değer sağlayıcısı fabrikalarını içinde Program.cs
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. Bunu listede ilk yapmak için yerine öğesini çağırın Insert(0, new CookieValueProviderFactory())
Add
.
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 olarak
null
ayarlanır. - Null değer atanamayan değer türleri olarak
default(T)
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 olarak
Array.Empty<T>()
ayarlanır, ancakbyte[]
diziler olaraknull
ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamazsa model durumu geçersiz kılınmalıdır, özniteliğini [BindRequired]
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.
Özniteliği olan bir API denetleyicisinde [ApiController]
geçersiz model durumu otomatik HTTP 400 yanıtıyla sonuçlandı.
Razor Sayfada, sayfayı bir hata iletisiyle yeniden dağıtın:
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
Basit ve karmaşık türlerin açıklaması için bkz. Model bağlama basit ve karmaşık 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
- DateOnly
- Tarih Saat
- DateTimeOffset
- Ondalık
- Çift
- Sabit Listesi
- GUID
- Int16, Int32, Int64
- Tek
- TimeOnly
- Zaman Aralığı
- UInt16, UInt32, UInt64
- Uri
- Sürüm
Ile bağlama IParsable<T>.TryParse
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, bir tarih aralığını bağlamayı desteklemek için uygulanır IParsable<TSelf>
:
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
, bağlamak içinDateRange
yöntemini 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, bağlamayı desteklemek için CultureInfo
uygularIParsable<TSelf>
:
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 CultureInfo
dizeyi bağlamak için sınıfını Locale
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 ile bir tarih aralığını CultureInfo
bağlamak için ve Locale
sınıflarını kullanırDateRange
:
// 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.
Ile bağlama TryParse
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ı genel varsayılan oluşturucu kullanılarak örneği oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad deseninin kaynaklarına bakar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar. Öneki kullanma kararı özellik başına yapılmaz. Örneğin, içeren bir sorgu ?Instructor.Id=100&Name=foo
ile yöntemine OnGet(Instructor instructor)
bağlı olarak, türünde Instructor
elde edilen nesne şunları içerir:
Id
olarak100
ayarlayın.Name
olaraknull
ayarlayın. Önceki sorgu parametresinde kullanıldığından model bağlamasının beklediğiInstructor.Name
Instructor.Id
bir işlemdir.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak özelliğe PageModel
bağlama için ön ek, ortak özellik 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, anahtarının instructorToUpdate.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Bağlanacak model denetleyicinin veya PageModel
sınıfın adlı Instructor
bir özellikse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model adlı instructorToUpdate
bir parametreyse ve Bind
bir öznitelik ön ek olarak belirtiyorsa Instructor
:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak 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, deftere nakledilmiş form verileri değerlerin kaynağı olduğunda model bağlamayı 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] özniteliğ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, yöntem çağrıldığında OnPost
yalnızca modelin Instructor
belirtilen özellikleri bağlıdı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. Fazla paylaşıma karşı koruma için, özniteliği yerine [Bind]
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ğlama gerçekleşemiyorsa model bağlamanın model durumu hatası eklemesine 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 özniteliğin [Required]
tartışması.
[BindNever] özniteliği
Bir özelliğe veya türe uygulanabilir. Model bağlamanın 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şmeleri 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
Bir parametreyi veya adlı
index
bir özelliği ya daIndex
bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlaması, koleksiyon için dizin olarak kullanmayıindex
dener ve bu da yanlış bağlamaya neden olabilir. Ö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
HedeflerdeDictionary
, model bağlama parameter_name veya property_name eşleşmeleri arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adlı
selectedCourses
birDictionary<int, string>
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"]="Economics"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir. Newtonsoft.Json
Hem hem de System.Text.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarıldığı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:
- Kayıt türü olun.
- Tam olarak bir ortak oluşturucuya sahip olun.
- Aynı ada ve türe sahip bir özelliğe sahip 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çlar:
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
Birincil oluşturucular gibi görünen el ile yazılmış 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. Özelliklerdeki 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 oluşturucular ile normal durumda, 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:
- Devralma: IValueProviderFactory
- 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 karşıya yüklenen bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
CancellationToken
Eylemler isteğe bağlı olarak parametresini CancellationToken
bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyalleri bağlar RequestAborted . Eylemler, denetleyici eylemlerinin bir parçası olarak yürütülen uzun süre çalışan zaman uyumsuz işlemleri iptal etmek için bu parametreyi kullanabilir.
FormCollection
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biç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:
içinde
Program.cs
, veya AddXmlDataContractSerializerFormattersöğesini arayınAddXmlSerializerFormatters.builder.Services.AddControllers() .AddXmlSerializerFormatters();
özniteliğini, istek gövdesinde
Consumes
XML beklenmesi gereken denetleyici sınıflarına veya eylem yöntemlerine uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileş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ümde, adlı ObjectId
özel türü anlamak için tabanlı giriş biçimlendiricisinin System.Text.Json
nasıl özelleştirileceği açıklanmaktadır.
Ö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!;
}
kullanırken System.Text.Json
model bağlama işlemini özelleştirmek için öğesinden JsonConverter<T>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ü ile özel dönüştürücüsü olarak yapılandırılır ObjectIdConverter
:
[JsonConverter(typeof(ObjectIdConverter))]
public record ObjectId(int Id);
Daha fazla bilgi için bkz . Özel dönüştürücüler yazma.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a bir ayrıntı sağlayıcısı ekleyerek özelleştirebilirsinizModelMetadata
. 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 içine bir ExcludeBindingMetadataProvider Program.cs
ekleyin. Örneğin, türündeki System.Version
tüm 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ürün özelliklerinde doğrulamayı devre dışı bırakmak için içine ekleyin SuppressChildValidationMetadataProvider Program.cs
. Ö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ısı yazarak ve özniteliğini kullanarak model bağlamayı [ModelBinder]
belirli bir hedef için seçerek genişletebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
Model bağlama yöntemi kullanılarak TryUpdateModelAsync el ile çağrılabilir. yöntemi hem hem de ControllerBase
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 kullanılmadığı sürece web API'siyle 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 ekleme kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir yöntem çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu eklemeye 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:
- Parametresini null atanabilir 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, yol verileri bir kayıt anahtarı sağlayabilir ve deftere nakledilmiş 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.
- Verileri, yöntem parametrelerinde ve Razor genel özelliklerde denetleyicilere 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ı
id
bir tamsayınınGetById
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ı
dogsOnly
bir boole değerininGetById
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. Ad eşleştirme büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve daha sonra parametresi için true
dogsOnly
ve parametresi için id
2'yi geçirerek yöntemini çağırırGetById
.
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 Razor yönlendirıldığı 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 özelliğini olarak true
ayarlayınSupportsGet
:
[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, veya TryParse
yöntemi kullanılarak TypeConverter 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, veya TypeConverter
TryParse
varlığını temel alarak farkı belirler. Bir tür dönüştürücüsü oluşturmanızı veya dış kaynaklar veya birden çok giriş gerektirmeyen bir string
SomeType
dönüştürme için kullanmanızı TryParse
ö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.)
- Veri yönlendirme
- Sorgu dizesi parametreleri
- Karşıya 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 veya
IEnumerable<IFormFile>
uygulayanIFormFile
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]
- Deftere nakledilen 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, aşağıdaki örnekte olduğu gibi adında kısa çizgi bulunan bir üst bilgi olabilir:
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Özelliklerini bir HTTP isteğinin [FromBody]
gövdesinden doldurmak için özniteliğini bir parametreye uygulayın. ASP.NET Core çalışma zamanı, gövdeyi 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, özelliklerine uygulanan bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylem parametresinin gövdeden doldurulduğunu pet
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övdede uygun bir değer bulunursa, bu değer özelliği doldurmak Breed
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ı'na
Program.cs
kaydedin.
Örnek, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve fabrika örneği içerir. özel değer sağlayıcısı fabrikalarını içinde Program.cs
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. Bunu listede ilk yapmak için yerine öğesini çağırın Insert(0, new CookieValueProviderFactory())
Add
.
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 olarak
null
ayarlanır. - Null değer atanamayan değer türleri olarak
default(T)
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 olarak
Array.Empty<T>()
ayarlanır, ancakbyte[]
diziler olaraknull
ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamazsa model durumu geçersiz kılınmalıdır, özniteliğini [BindRequired]
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.
Özniteliği olan bir API denetleyicisinde [ApiController]
geçersiz model durumu otomatik HTTP 400 yanıtıyla sonuçlandı.
Razor Sayfada, sayfayı bir hata iletisiyle yeniden dağıtın:
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
Basit ve karmaşık türlerin açıklaması için bkz. Model bağlama basit ve karmaşık 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
- DateOnly
- Tarih Saat
- DateTimeOffset
- Ondalık
- Çift
- Sabit Listesi
- GUID
- Int16, Int32, Int64
- Tek
- TimeOnly
- Zaman Aralığı
- UInt16, UInt32, UInt64
- Uri
- Sürüm
Ile bağlama IParsable<T>.TryParse
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, bir tarih aralığını bağlamayı desteklemek için uygulanır IParsable<TSelf>
:
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
, bağlamak içinDateRange
yöntemini 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, bağlamayı desteklemek için CultureInfo
uygularIParsable<TSelf>
:
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 CultureInfo
dizeyi bağlamak için sınıfını Locale
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 ile bir tarih aralığını CultureInfo
bağlamak için ve Locale
sınıflarını kullanırDateRange
:
// 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.
Ile bağlama TryParse
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ı genel varsayılan oluşturucu kullanılarak örneği oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad deseninin kaynaklarına bakar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar. Öneki kullanma kararı özellik başına yapılmaz. Örneğin, içeren bir sorgu ?Instructor.Id=100&Name=foo
ile yöntemine OnGet(Instructor instructor)
bağlı olarak, türünde Instructor
elde edilen nesne şunları içerir:
Id
olarak100
ayarlayın.Name
olaraknull
ayarlayın. Önceki sorgu parametresinde kullanıldığından model bağlamasının beklediğiInstructor.Name
Instructor.Id
bir işlemdir.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak özelliğe PageModel
bağlama için ön ek, ortak özellik 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, anahtarının instructorToUpdate.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Bağlanacak model denetleyicinin veya PageModel
sınıfın adlı Instructor
bir özellikse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model adlı instructorToUpdate
bir parametreyse ve Bind
bir öznitelik ön ek olarak belirtiyorsa Instructor
:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak 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, deftere nakledilmiş form verileri değerlerin kaynağı olduğunda model bağlamayı 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] özniteliğ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, yöntem çağrıldığında OnPost
yalnızca modelin Instructor
belirtilen özellikleri bağlıdı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. Fazla paylaşıma karşı koruma için, özniteliği yerine [Bind]
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ğlama gerçekleşemiyorsa model bağlamanın model durumu hatası eklemesine 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 özniteliğin [Required]
tartışması.
[BindNever] özniteliği
Bir özelliğe veya türe uygulanabilir. Model bağlamanın 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şmeleri 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
Bir parametreyi veya adlı
index
bir özelliği ya daIndex
bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlaması, koleksiyon için dizin olarak kullanmayıindex
dener ve bu da yanlış bağlamaya neden olabilir. Ö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
HedeflerdeDictionary
, model bağlama parameter_name veya property_name eşleşmeleri arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adlı
selectedCourses
birDictionary<int, string>
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"]="Economics"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir. Newtonsoft.Json
Hem hem de System.Text.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarıldığı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:
- Kayıt türü olun.
- Tam olarak bir ortak oluşturucuya sahip olun.
- Aynı ada ve türe sahip bir özelliğe sahip 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çlar:
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
Birincil oluşturucular gibi görünen el ile yazılmış 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. Özelliklerdeki 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 oluşturucular ile normal durumda, 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:
- Devralma: IValueProviderFactory
- 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 karşıya yüklenen bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
CancellationToken
Eylemler isteğe bağlı olarak parametresini CancellationToken
bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyalleri bağlar RequestAborted . Eylemler, denetleyici eylemlerinin bir parçası olarak yürütülen uzun süre çalışan zaman uyumsuz işlemleri iptal etmek için bu parametreyi kullanabilir.
FormCollection
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biç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:
içinde
Program.cs
, veya AddXmlDataContractSerializerFormattersöğesini arayınAddXmlSerializerFormatters.builder.Services.AddControllers() .AddXmlSerializerFormatters();
özniteliğini, istek gövdesinde
Consumes
XML beklenmesi gereken denetleyici sınıflarına veya eylem yöntemlerine uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileş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ümde, adlı ObjectId
özel türü anlamak için tabanlı giriş biçimlendiricisinin System.Text.Json
nasıl özelleştirileceği açıklanmaktadır.
Ö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!;
}
kullanırken System.Text.Json
model bağlama işlemini özelleştirmek için öğesinden JsonConverter<T>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ü ile özel dönüştürücüsü olarak yapılandırılır ObjectIdConverter
:
[JsonConverter(typeof(ObjectIdConverter))]
public record ObjectId(int Id);
Daha fazla bilgi için bkz . Özel dönüştürücüler yazma.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a bir ayrıntı sağlayıcısı ekleyerek özelleştirebilirsinizModelMetadata
. 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 içine bir ExcludeBindingMetadataProvider Program.cs
ekleyin. Örneğin, türündeki System.Version
tüm 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ürün özelliklerinde doğrulamayı devre dışı bırakmak için içine ekleyin SuppressChildValidationMetadataProvider Program.cs
. Ö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ısı yazarak ve özniteliğini kullanarak model bağlamayı [ModelBinder]
belirli bir hedef için seçerek genişletebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
Model bağlama yöntemi kullanılarak TryUpdateModelAsync el ile çağrılabilir. yöntemi hem hem de ControllerBase
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 kullanılmadığı sürece web API'siyle 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 ekleme kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir yöntem çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu eklemeye 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:
- Parametresini null atanabilir 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, yol verileri bir kayıt anahtarı sağlayabilir ve deftere nakledilmiş 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.
- Verileri, yöntem parametrelerinde ve Razor genel özelliklerde denetleyicilere 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ı
id
bir tamsayınınGetById
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ı
dogsOnly
bir boole değerininGetById
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. Ad eşleştirme büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve daha sonra parametresi için true
dogsOnly
ve parametresi için id
2'yi geçirerek yöntemini çağırırGetById
.
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 Razor yönlendirıldığı 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 özelliğini olarak true
ayarlayınSupportsGet
:
[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.)
- Veri yönlendirme
- Sorgu dizesi parametreleri
- Karşıya 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 veya
IEnumerable<IFormFile>
uygulayanIFormFile
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]
- Deftere nakledilen 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, aşağıdaki örnekte olduğu gibi adında kısa çizgi bulunan bir üst bilgi olabilir:
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Özelliklerini bir HTTP isteğinin [FromBody]
gövdesinden doldurmak için özniteliğini bir parametreye uygulayın. ASP.NET Core çalışma zamanı, gövdeyi 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, özelliklerine uygulanan bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylem parametresinin gövdeden doldurulduğunu pet
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övdede uygun bir değer bulunursa, bu değer özelliği doldurmak Breed
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ı'na
Program.cs
kaydedin.
Örnek, tanımlama bilgilerinden değer alan bir değer sağlayıcısı ve fabrika örneği içerir. özel değer sağlayıcısı fabrikalarını içinde Program.cs
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. Bunu listede ilk yapmak için yerine öğesini çağırın Insert(0, new CookieValueProviderFactory())
Add
.
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 olarak
null
ayarlanır. - Null değer atanamayan değer türleri olarak
default(T)
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 olarak
Array.Empty<T>()
ayarlanır, ancakbyte[]
diziler olaraknull
ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamazsa model durumu geçersiz kılınmalıdır, özniteliğini [BindRequired]
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.
Özniteliği olan bir API denetleyicisinde [ApiController]
geçersiz model durumu otomatik HTTP 400 yanıtıyla sonuçlandı.
Razor Sayfada, sayfayı bir hata iletisiyle yeniden dağıtın:
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
- Uri
- 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ı genel varsayılan oluşturucu kullanılarak örneği oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad deseninin kaynaklarına bakar. Hiçbir şey bulunmazsa, ön ek olmadan yalnızca property_name arar. Öneki kullanma kararı özellik başına yapılmaz. Örneğin, içeren bir sorgu ?Instructor.Id=100&Name=foo
ile yöntemine OnGet(Instructor instructor)
bağlı olarak, türünde Instructor
elde edilen nesne şunları içerir:
Id
olarak100
ayarlayın.Name
olaraknull
ayarlayın. Önceki sorgu parametresinde kullanıldığından model bağlamasının beklediğiInstructor.Name
Instructor.Id
bir işlemdir.
Bir parametreye bağlama için ön ek parametre adıdır. Ortak özelliğe PageModel
bağlama için ön ek, ortak özellik 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, anahtarının instructorToUpdate.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Bağlanacak model denetleyicinin veya PageModel
sınıfın adlı Instructor
bir özellikse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model adlı instructorToUpdate
bir parametreyse ve Bind
bir öznitelik ön ek olarak belirtiyorsa Instructor
:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak 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, deftere nakledilmiş form verileri değerlerin kaynağı olduğunda model bağlamayı 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] özniteliğ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, yöntem çağrıldığında OnPost
yalnızca modelin Instructor
belirtilen özellikleri bağlıdı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. Fazla paylaşıma karşı koruma için, özniteliği yerine [Bind]
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ğlama gerçekleşemiyorsa model bağlamanın model durumu hatası eklemesine 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 özniteliğin [Required]
tartışması.
[BindNever] özniteliği
Bir özelliğe veya türe uygulanabilir. Model bağlamanın 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şmeleri 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
Bir parametreyi veya adlı
index
bir özelliği ya daIndex
bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlaması, koleksiyon için dizin olarak kullanmayıindex
dener ve bu da yanlış bağlamaya neden olabilir. Ö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
HedeflerdeDictionary
, model bağlama parameter_name veya property_name eşleşmeleri arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adlı
selectedCourses
birDictionary<int, string>
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"]="Economics"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir. Newtonsoft.Json
Hem hem de System.Text.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarıldığı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:
- Kayıt türü olun.
- Tam olarak bir ortak oluşturucuya sahip olun.
- Aynı ada ve türe sahip bir özelliğe sahip 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çlar:
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
Birincil oluşturucular gibi görünen el ile yazılmış 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. Özelliklerdeki 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 oluşturucular ile normal durumda, 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:
- Devralma: IValueProviderFactory
- 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 karşıya yüklenen bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
CancellationToken
Eylemler isteğe bağlı olarak parametresini CancellationToken
bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyalleri bağlar RequestAborted . Eylemler, denetleyici eylemlerinin bir parçası olarak yürütülen uzun süre çalışan zaman uyumsuz işlemleri iptal etmek için bu parametreyi kullanabilir.
FormCollection
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biç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:
içinde
Program.cs
, veya AddXmlDataContractSerializerFormattersöğesini arayınAddXmlSerializerFormatters.builder.Services.AddControllers() .AddXmlSerializerFormatters();
özniteliğini, istek gövdesinde
Consumes
XML beklenmesi gereken denetleyici sınıflarına veya eylem yöntemlerine uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileş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ümde, adlı ObjectId
özel türü anlamak için tabanlı giriş biçimlendiricisinin System.Text.Json
nasıl özelleştirileceği açıklanmaktadır.
Ö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!;
}
kullanırken System.Text.Json
model bağlama işlemini özelleştirmek için öğesinden JsonConverter<T>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ü ile özel dönüştürücüsü olarak yapılandırılır ObjectIdConverter
:
[JsonConverter(typeof(ObjectIdConverter))]
public record ObjectId(int Id);
Daha fazla bilgi için bkz . Özel dönüştürücüler yazma.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a bir ayrıntı sağlayıcısı ekleyerek özelleştirebilirsinizModelMetadata
. 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 içine bir ExcludeBindingMetadataProvider Program.cs
ekleyin. Örneğin, türündeki System.Version
tüm 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ürün özelliklerinde doğrulamayı devre dışı bırakmak için içine ekleyin SuppressChildValidationMetadataProvider Program.cs
. Ö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ısı yazarak ve özniteliğini kullanarak model bağlamayı [ModelBinder]
belirli bir hedef için seçerek genişletebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
Model bağlama yöntemi kullanılarak TryUpdateModelAsync el ile çağrılabilir. yöntemi hem hem de ControllerBase
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 kullanılmadığı sürece web API'siyle 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 ekleme kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir yöntem çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu eklemeye 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:
- Parametresini null atanabilir 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, yol verileri bir kayıt anahtarı sağlayabilir ve deftere nakledilmiş 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.
- Verileri, yöntem parametrelerinde ve Razor genel özelliklerde denetleyicilere 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ı
id
bir tamsayınınGetById
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ı
dogsOnly
bir boole değerininGetById
sonraki parametresini bulur. - Kaynaklara bakar ve sorgu dizesinde "DogsOnly=true" değerini bulur. Ad eşleştirme büyük/küçük harfe duyarlı değildir.
- "true" dizesini boole değerine
true
dönüştürür.
Çerçeve daha sonra parametresi için true
dogsOnly
ve parametresi için id
2'yi geçirerek yöntemini çağırırGetById
.
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 Razor yönlendirıldığı 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 ve 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 özelliğini olarak true
ayarlayınSupportsGet
:
[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.)
- Veri yönlendirme
- Sorgu dizesi parametreleri
- Karşıya 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 veya
IEnumerable<IFormFile>
uygulayanIFormFile
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]
- Deftere nakledilen 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, aşağıdaki örnekte olduğu gibi adında kısa çizgi bulunan bir üst bilgi olabilir:
public void OnGet([FromHeader(Name = "Accept-Language")] string language)
[FromBody] özniteliği
Özelliklerini bir HTTP isteğinin [FromBody]
gövdesinden doldurmak için özniteliğini bir parametreye uygulayın. ASP.NET Core çalışma zamanı, gövdeyi 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, özelliklerine uygulanan bağlama kaynağı öznitelikleri yoksayılır. Örneğin, aşağıdaki Create
eylem parametresinin gövdeden doldurulduğunu pet
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övdede uygun bir değer bulunursa, bu değer özelliği doldurmak Breed
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ı'na
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. Bunu listede ilk yapmak için yerine öğesini çağırın Insert(0, new CookieValueProviderFactory())
Add
.
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 olarak
null
ayarlanır. - Null değer atanamayan değer türleri olarak
default(T)
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 olarak
Array.Empty<T>()
ayarlanır, ancakbyte[]
diziler olaraknull
ayarlanır.
Model özelliği için form alanlarında hiçbir şey bulunamazsa model durumu geçersiz kılınmalıdır, özniteliğini [BindRequired]
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.
Özniteliği olan bir API denetleyicisinde [ApiController]
geçersiz model durumu otomatik HTTP 400 yanıtıyla sonuçlandı.
Razor Sayfada, sayfayı bir hata iletisiyle yeniden dağıtın:
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
_instructorsInMemoryStore.Add(Instructor);
return RedirectToPage("./Index");
}
İstemci tarafı doğrulama, aksi takdirde Sayfalar Razor formuna gönderilecek çoğu hatalı veriyi yakalar. 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 Tarihle 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
- Uri
- 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ı genel varsayılan oluşturucu kullanılarak örneği oluşturulur.
Karmaşık türün her özelliği için model bağlaması, prefix.property_name ad deseninin kaynaklarına bakar. 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 özelliğe PageModel
bağlama için ön ek, ortak özellik 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, anahtarının instructorToUpdate.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Ön ek = özellik adı
Bağlanacak model denetleyicinin veya PageModel
sınıfın adlı Instructor
bir özellikse:
[BindProperty]
public Instructor Instructor { get; set; }
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak başlar. Bu bulunamazsa, ön ek olmadan arar ID
.
Özel ön ek
Bağlanacak model adlı instructorToUpdate
bir parametreyse ve Bind
bir öznitelik ön ek olarak belirtiyorsa Instructor
:
public IActionResult OnPost(
int? id, [Bind(Prefix = "Instructor")] Instructor instructorToUpdate)
Model bağlama, anahtarının Instructor.ID
kaynaklarına bakarak 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, deftere nakledilmiş form verileri değerlerin kaynağı olduğunda model bağlamayı 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] özniteliğ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, yöntem çağrıldığında OnPost
yalnızca modelin Instructor
belirtilen özellikleri bağlıdı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. Fazla paylaşıma karşı koruma için, özniteliği yerine [Bind]
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ğlama gerçekleşemiyorsa model bağlamanın model durumu hatası eklemesine 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 özniteliğin [Required]
tartışması.
[BindNever] özniteliği
Yöntem parametrelerine değil, yalnızca model özelliklerine uygulanabilir. Model bağlamanın 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şmeleri 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
Bir parametreyi veya adlı
index
bir özelliği ya daIndex
bir koleksiyon değerine bitişikse bağlamaktan kaçının. Model bağlaması, koleksiyon için dizin olarak kullanmayıindex
dener ve bu da yanlış bağlamaya neden olabilir. Ö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
HedeflerdeDictionary
, model bağlama parameter_name veya property_name eşleşmeleri arar. Eşleşme bulunmazsa, ön ek olmadan desteklenen biçimlerden birini arar. Örneğin:
Hedef parametrenin adlı
selectedCourses
birDictionary<int, string>
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"]="Economics"
Oluşturucu bağlama ve kayıt türleri
Model bağlama, karmaşık türlerin parametresiz bir oluşturucuya sahip olmasını gerektirir. Newtonsoft.Json
Hem hem de System.Text.Json
tabanlı giriş biçimlendiricileri, parametresiz oluşturucuya sahip olmayan sınıfların seri durumdan çıkarıldığı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:
- Kayıt türü olun.
- Tam olarak bir ortak oluşturucuya sahip olun.
- Aynı ada ve türe sahip bir özelliğe sahip 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çlar:
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
Birincil oluşturucular gibi görünen el ile yazılmış 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. Özelliklerdeki 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 oluşturucular ile normal durumda, 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:
- Devralma: IValueProviderFactory
- 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 karşıya yüklenen bir dosya. Ayrıca, birden çok dosya için de IEnumerable<IFormFile>
desteklenir.
CancellationToken
Eylemler isteğe bağlı olarak parametresini CancellationToken
bağlayabilir. Bu, HTTP isteğini temel alan bağlantı durdurulduğunda sinyalleri bağlar RequestAborted . Eylemler, denetleyici eylemlerinin bir parçası olarak yürütülen uzun süre çalışan zaman uyumsuz işlemleri iptal etmek için bu parametreyi kullanabilir.
FormCollection
Gönderilen form verilerinden tüm değerleri almak için kullanılır.
Giriş biç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.içinde
Startup.ConfigureServices
, veya AddXmlDataContractSerializerFormattersöğesini arayınAddXmlSerializerFormatters.services.AddRazorPages() .AddMvcOptions(options => { options.ValueProviderFactories.Add(new CookieValueProviderFactory()); options.ModelMetadataDetailsProviders.Add( new ExcludeBindingMetadataProvider(typeof(System.Version))); options.ModelMetadataDetailsProviders.Add( new SuppressChildValidationMetadataProvider(typeof(System.Guid))); }) .AddXmlSerializerFormatters();
özniteliğini, istek gövdesinde
Consumes
XML beklenmesi gereken denetleyici sınıflarına veya eylem yöntemlerine uygulayın.[HttpPost] [Consumes("application/xml")] public ActionResult<Pet> Create(Pet pet)
Daha fazla bilgi için bkz . XML Serileş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ümde, adlı ObjectId
özel türü anlamak için tabanlı giriş biçimlendiricisinin System.Text.Json
nasıl özelleştirileceği açıklanmaktadır.
adlı Id
özel ObjectId
bir özellik içeren aşağıdaki modeli göz önünde bulundurun:
public class ModelWithObjectId
{
public ObjectId Id { get; set; }
}
kullanırken System.Text.Json
model bağlama işlemini özelleştirmek için öğesinden JsonConverter<T>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ü ile özel dönüştürücüsü olarak yapılandırılır ObjectIdConverter
:
[JsonConverter(typeof(ObjectIdConverter))]
public struct ObjectId
{
public ObjectId(int id) =>
Id = id;
public int Id { get; }
}
Daha fazla bilgi için bkz . Özel dönüştürücüler yazma.
Belirtilen türleri model bağlamasından dışla
Model bağlama ve doğrulama sistemlerinin davranışı tarafından ModelMetadatayönlendirilir. MvcOptions.ModelMetadataDetailsProviders'a bir ayrıntı sağlayıcısı ekleyerek özelleştirebilirsinizModelMetadata
. 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 içine bir ExcludeBindingMetadataProvider Startup.ConfigureServices
ekleyin. Örneğin, türündeki System.Version
tüm 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ürün özelliklerinde doğrulamayı devre dışı bırakmak için içine ekleyin SuppressChildValidationMetadataProvider Startup.ConfigureServices
. Ö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ısı yazarak ve özniteliğini kullanarak model bağlamayı [ModelBinder]
belirli bir hedef için seçerek genişletebilirsiniz. Özel model bağlama hakkında daha fazla bilgi edinin.
El ile model bağlama
Model bağlama yöntemi kullanılarak TryUpdateModelAsync el ile çağrılabilir. yöntemi hem hem de ControllerBase
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 kullanılmadığı sürece web API'siyle 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 ekleme kapsayıcısından bir türün örneğini alır. Amacı, yalnızca belirli bir yöntem çağrıldığında bir hizmete ihtiyacınız olduğunda oluşturucu eklemeye alternatif sağlamaktır.
Ek kaynaklar
ASP.NET Core