Vazby modelu v ASP.NET Core

Tento článek vysvětluje, co je vazba modelu, jak funguje a jak přizpůsobit jeho chování.

Zobrazení nebo stažení ukázkového kódu (stažení).

Co je vazba modelu

Kontrolery Razor a stránky pracují s daty, která pochází z požadavků HTTP. Směrovací data mohou například poskytnout klíč záznamu a pole formuláře post post mohou poskytovat hodnoty pro vlastnosti modelu. Psaní kódu pro načtení každé z těchto hodnot a jejich převod z řetězců na typy .NET by bylo zdlouhavé a náchylné k chybám. Vazby modelu tento proces automatizují. Systém vazby modelu:

  • Načítá data z různých zdrojů, jako jsou data tras, pole formuláře a řetězce dotazů.
  • Poskytuje data kontrolerům a Razor stránkám v parametrech metody a veřejných vlastnostech.
  • Převede řetězcová data na typy .NET.
  • Aktualizuje vlastnosti komplexních typů.

Příklad

Předpokládejme, že máte následující metodu akce:

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

Aplikace obdrží požadavek s touto adresou URL:

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

Jakmile systém směrování vybere metodu akce, projde vazba modelu následujícím postupem:

  • Vyhledá první parametr typu GetById , celé číslo s názvem id .
  • Projde dostupné zdroje v požadavku HTTP a v datech trasy vyhledá id = "2".
  • Převede řetězec "2" na celé číslo 2.
  • Vyhledá další parametr typu GetById logickou hodnotu s názvem dogsOnly .
  • Projde zdroje a v řetězci dotazu najde "DogsOnly=true". Při porovnávání názvů se rozlišují malá a velká písmena.
  • Převede řetězec "true" na logickou hodnotu true .

Rozhraní pak zavolá GetById metodu a předá hodnotu 2 id parametru true a dogsOnly parametru .

V předchozím příkladu jsou cíle vazby modelu parametry metody, které jsou jednoduché typy. Cíle mohou být také vlastnosti komplexního typu. Po úspěšném navázání každé vlastnosti dojde k ověření modelu pro tuto vlastnost. Záznam o tom, jaká data jsou svázána s modelem, a všechny chyby vazeb nebo ověření jsou uloženy v ControllerBase.ModelState nebo PageModel.ModelState. Pokud chcete zjistit, jestli byl tento proces úspěšný, aplikace zkontroluje příznak ModelState.IsValid.

Targets

Vazba modelu se pokouší najít hodnoty pro následující typy cílů:

  • Parametry metody akce kontroleru, na kterou se směruje požadavek.
  • Parametry metody obslužné Razor rutiny Pages, na kterou se směruje požadavek.
  • Veřejné vlastnosti kontroleru nebo PageModel třídy, pokud jsou určeny atributy.

Atribut [BindProperty]

Lze použít na veřejnou vlastnost kontroleru nebo třídy, která způsobí, že PageModel vazba modelu bude cílit na vlastnost:

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

Atribut [BindProperties]

K dispozici ve ASP.NET Core verze 2.1 a novější. Lze použít u kontroleru nebo třídy, aby bylo možné vazbu modelu nastavit tak, aby cílil na všechny PageModel veřejné vlastnosti třídy:

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

Vazby modelu pro požadavky HTTP GET

Ve výchozím nastavení nejsou vlastnosti pro požadavky HTTP GET vázané. Pro požadavek GET obvykle potřebujete jen parametr ID záznamu. ID záznamu slouží k vyhledávání položky v databázi. Proto není nutné svázat vlastnost, která obsahuje instanci modelu. Ve scénářích, kde chcete vlastnosti vázané na data z požadavků GET, nastavte SupportsGet vlastnost na true :

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

zdroje

Vazba modelu ve výchozím nastavení získává data ve formě párů klíč-hodnota z následujících zdrojů v požadavku HTTP:

  1. Pole formuláře
  2. Text požadavku (pro kontrolery, které mají atribut [ApiController].)
  3. Směrování dat
  4. Parametry řetězce dotazu
  5. Nahrané soubory

Pro každý cílový parametr nebo vlastnost se zdroje prohledá v pořadí uvedeném v předchozím seznamu. Existuje několik výjimek:

  • Data tras a řetězcové hodnoty dotazu se používají pouze pro jednoduché typy.
  • Nahrané soubory jsou svázány pouze s cílovými typy, které IFormFile implementují nebo IEnumerable<IFormFile> .

Pokud výchozí zdroj není správný, použijte k určení zdroje jeden z následujících atributů:

Tyto atributy:

  • Jsou přidány do vlastností modelu jednotlivě (nikoli do třídy modelu), jako v následujícím příkladu:

    public class Instructor
    {
        public int ID { get; set; }
    
        [FromQuery(Name = "Note")]
        public string NoteFromQueryString { get; set; }
    
  • Volitelně můžete v konstruktoru přijmout hodnotu názvu modelu. Tato možnost je k dispozici v případě, že název vlastnosti neodpovídá hodnotě v požadavku. Například hodnota v požadavku může být hlavička s pomlčkou v názvu, jako v následujícím příkladu:

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

Atribut [FromBody]

Použijte [FromBody] atribut na parametr k naplnění jeho vlastností z textu požadavku HTTP. Modul ASP.NET Core runtime deleguje odpovědnost za čtení těla do formátovacího modulu vstupu. Formátovací metody vstupu jsou vysvětleny dále v tomto článku.

Při [FromBody] použití parametru komplexního typu jsou ignorovány všechny atributy zdroje vazby použité na jeho vlastnosti. Například následující akce určuje, že se její parametr naplní Create pet z těla:

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

Třída Pet určuje, že se Breed její vlastnost naplní z parametru řetězce dotazu:

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

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

V předchozím příkladu:

  • Atribut [FromQuery] je ignorován.
  • Vlastnost Breed není naplněna z parametru řetězce dotazu.

Vstupní formátovací metody čtou jenom text a nerozumí atributům zdroje vazby. Pokud se v těle nachází vhodná hodnota, použije se tato hodnota k naplnění Breed vlastnosti .

Neplatí pro více [FromBody] než jeden parametr na metodu akce. Jakmile je datový proud požadavku přečten pomocí formátovacího modulu vstupu, už není možné ho znovu číst pro vazbu dalších [FromBody] parametrů.

Další zdroje

Zdrojová data poskytují systému vazby modelu poskytovatelé hodnot. Můžete psát a registrovat vlastní zprostředkovatele hodnot, kteří píšou data pro vazbu modelu z jiných zdrojů. Můžete například chtít data ze stavu cookie relací nebo . Získání dat z nového zdroje:

  • Vytvořte třídu, která implementuje IValueProvider .
  • Vytvořte třídu, která implementuje IValueProviderFactory .
  • Zaregistrujte třídu factory v Startup.ConfigureServices .

Ukázková aplikace obsahuje zprostředkovatele hodnoty a příklad továrny, který získává hodnoty z cookie hodnot . Tady je registrační kód v Startup.ConfigureServices souboru :

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();

Zobrazený kód za všechny integrované zprostředkovatele hodnot zasadí zprostředkovatele vlastní hodnoty. Pokud chcete, aby byla první v seznamu, Insert(0, new CookieValueProviderFactory()) volejte místo Add .

Žádný zdroj pro vlastnost modelu

Pokud pro vlastnost modelu není nalezena žádná hodnota, ve výchozím nastavení se nevy vytvoří chyba stavu modelu. Vlastnost je nastavená na hodnotu null nebo výchozí hodnotu:

  • Jednoduché typy s možnou hodnotou null jsou nastavené na null .
  • Typy hodnot, které nejsou null, jsou nastaveny na default(T) . Například parametr int id je nastaven na hodnotu 0.
  • Pro komplexní typy vazba modelu vytvoří instanci pomocí výchozího konstruktoru bez nastavení vlastností.
  • Pole jsou nastavena na Array.Empty<T>() , s výjimkou toho, že byte[] pole jsou nastavena na null .

Pokud má být stav modelu neplatný, pokud se v polích formuláře pro vlastnost modelu nenalezne žádné, použijte [BindRequired] atribut.

Všimněte si, že toto [BindRequired] chování se vztahuje na vazbu modelu z publikovaných dat formuláře, nikoli na data JSON nebo XML v těle žádosti. Data těla žádosti jsou zpracována vstupními formátovacímimoduly.

Chyby konverze typu

Pokud je zdroj nalezen, ale nelze jej převést na cílový typ, stav modelu je označen jako neplatný. Parametr Target nebo Property je nastaven na hodnotu null nebo na výchozí hodnotu, jak je uvedeno v předchozí části.

V kontroleru rozhraní API, který má [ApiController] atribut, má neplatný stav modelu za následek automatickou odpověď HTTP 400.

Na Razor stránce znovu zobrazte stránku s chybovou zprávou:

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

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

Ověřování na straně klienta zachytí nejvíc chybná data, která by byla jinak odeslána na Razor formulář stránky. Díky tomuto ověření je obtížné aktivovat předchozí zvýrazněný kód. Ukázková aplikace obsahuje tlačítko Odeslat s neplatným datem , které do pole Datum přijetí vloží nesprávná data a formulář odešle. Toto tlačítko ukazuje, jak kód pro zobrazení stránky funguje, když dojde k chybám převodu dat.

V případě, že je stránka znovu zobrazena v předchozím kódu, není v poli formuláře zobrazen neplatný vstup. Důvodem je to, že vlastnost modelu byla nastavena na hodnotu null nebo na výchozí hodnotu. V chybové zprávě se zobrazí neplatný vstup. Pokud ale chcete, aby se v poli formuláře znovu zobrazila chybná data, je vhodné vytvořit řetězec vlastnosti modelu a provést převod dat ručně.

Pokud nechcete, aby se chyby převodu typů způsobily při chybách stavu modelu, doporučujeme stejnou strategii. V takovém případě nastavte vlastnost model na řetězec.

Jednoduché typy

Jednoduché typy, které modelový pořadač může převést na zdrojové řetězce, do zahrnují následující:

Komplexní typy

Aby bylo možné vytvořit vazby komplexního typu, musí mít veřejný výchozí konstruktor a veřejné vlastnosti s možností zápisu. Když dojde k vazbě modelu, instance třídy je vytvořena pomocí veřejného výchozího konstruktoru.

Pro každou vlastnost komplexního typu vyhledává vazba modelu zdroje pro vzor názvů prefix.property_name. Pokud není nic nalezeno, vyhledá pouze Property_Name bez předpony.

Pro svázání s parametrem je předpona názvem parametru. Pro svázání s PageModel veřejnou vlastností je předpona názvem veřejné vlastnosti. Některé atributy mají Prefix vlastnost, která umožňuje přepsat výchozí použití parametru nebo názvu vlastnosti.

Předpokládejme například, že komplexní typ je následující Instructor Třída:

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

Prefix = název parametru

Pokud je model, který chcete svázat, parametr s názvem instructorToUpdate :

public IActionResult OnPost(int? id, Instructor instructorToUpdate)

Vazba modelu začne prohledáním zdrojů klíče instructorToUpdate.ID . Pokud se nenajde, vyhledá se ID bez předpony.

Prefix = název vlastnosti

Pokud je model, který chcete svázat, vlastnost s názvem Instructor kontroleru nebo PageModel třídy:

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

Vazba modelu začne prohledáním zdrojů klíče Instructor.ID . Pokud se nenajde, vyhledá se ID bez předpony.

Vlastní předpona

Pokud je model, který má být svázán, parametr pojmenovaný instructorToUpdate a Bind atribut určuje Instructor jako předponu:

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

Vazba modelu začne prohledáním zdrojů klíče Instructor.ID . Pokud se nenajde, vyhledá se ID bez předpony.

Atributy pro cíle komplexního typu

K dispozici je několik předdefinovaných atributů pro řízení vazeb modelu komplexních typů:

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

Upozornění

Tyto atributy ovlivňují vazbu modelu, když jsou publikovaná data formuláře zdrojem hodnot. Neovlivňují vstupní formátovací moduly, které zpracovávají odeslané texty JSON a XML požadavku. Vstupní formátovací moduly jsou vysvětleny dále v tomto článku.

[BIND] – atribut

Lze použít pro třídu nebo parametr metody. Určuje, které vlastnosti modelu by měly být zahrnuty ve vazbě modelu. [Bind] nemá vliv na vstupní formátovací moduly.

V následujícím příkladu Instructor jsou při volání jakékoli obslužné rutiny nebo metody akce vázány pouze zadané vlastnosti modelu:

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

V následujícím příkladu Instructor jsou při volání metody svázány pouze zadané vlastnosti modelu OnPost :

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

[Bind]Atribut lze použít k ochraně před přeúčtováním ve scénářích vytváření . Nefunguje dobře v scénářích úprav, protože vyloučené vlastnosti jsou nastavené na hodnotu null nebo výchozí hodnota místo toho, aby byla ponechána beze změny. Pro obranu před přeúčtováním se doporučuje zobrazit modely namísto [Bind] atributu. Další informace najdete v části Poznámka k zabezpečení týkající se přestavování.

[ModelBinder] – atribut

ModelBinderAttribute lze použít na typy, vlastnosti nebo parametry. Umožňuje zadat typ pořadače modelů, který se používá k vytvoření vazby konkrétní instance nebo typu. Příklad:

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

[ModelBinder]Atribut lze také použít ke změně názvu vlastnosti nebo parametru, pokud se jedná o vázaný model:

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

    public string Name { get; set; }
}

[BindRequired] – atribut

Dá se použít jenom pro vlastnosti modelu, nikoli na parametry metody. Způsobí, že vazba modelu přidá chybu stavu modelu, pokud pro vlastnost modelu neproběhne vazba. Tady je příklad:

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; }

Viz také diskuze o [Required] atributu v ověřování modelu.

[BindNever] – atribut

Dá se použít jenom pro vlastnosti modelu, nikoli na parametry metody. Zabraňuje vazbě modelu v nastavení vlastnosti modelu. Tady je příklad:

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

Kolekce

Pro cíle, které jsou kolekcemi jednoduchých typů, vyhledá vazba modelu shody pro parameter_name nebo Property_Name. Pokud se nenajde žádná shoda, vyhledá jeden z podporovaných formátů bez předpony. Příklad:

  • Předpokládejme, že parametr, který má být svázán, je pole s názvem selectedCourses :

    public IActionResult OnPost(int? id, int[] selectedCourses)
    
  • Data formuláře nebo řetězce dotazu mohou být v jednom z následujících formátů:

    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
    
  • Následující formát je podporován pouze v datech formuláře:

    selectedCourses[]=1050&selectedCourses[]=2000
    
  • Pro všechny předchozí ukázkové formáty předává vazba modelu pole dvou položek do selectedCourses parametru:

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

    Formáty dat, které používají čísla v dolním indexu (... [0]... [1]...) musí se ujistit, že jsou číslovány sekvenčně počínaje nulou. Pokud jsou v číslování dolních indexů nějaké mezery, všechny položky po mezerě se ignorují. Například pokud jsou v dolním indexu 0 a 2 místo 0 a 1, bude druhá položka ignorována.

Slovníky

V případě Dictionary cílů vyhledá vazba modelu shody pro parameter_name nebo Property_Name. Pokud se nenajde žádná shoda, vyhledá jeden z podporovaných formátů bez předpony. Příklad:

  • Předpokládejme, že cílový parametr je Dictionary<int, string> pojmenovaný selectedCourses :

    public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
    
  • Odeslaná data formuláře nebo řetězce dotazu mohou vypadat jako jeden z následujících příkladů:

    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
    
  • Pro všechny předchozí ukázkové formáty předává vazba modelu do parametru slovník dvou položek selectedCourses :

    • selectedCourses ["1050"] = "chemie"
    • selectedCourses ["2000"] = "ekonomické"

Vazba konstruktoru a typy záznamů

Vazba modelu vyžaduje, aby komplexní typy měly konstruktor bez parametrů. System.Text.JsonFormátovací moduly Newtonsoft.Json vstupu na bázi i podporují deserializaci tříd, které nemají konstruktor bez parametrů.

C# 9 zavádí typy záznamů, což je skvělý způsob, jak stručně reprezentovat data v síti. ASP.NET Core přidává podporu pro vazbu modelu a ověřování typů záznamů s jedním konstruktorem:

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

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

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

Person/Index.cshtml:

@model Person

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

Při ověřování typů záznamů modul runtime vyhledává metadata vazby a ověřování konkrétně na parametrech, nikoli na vlastnostech.

Rozhraní umožňuje vytváření a ověřování typů záznamů:

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

Pro předchozí fungování musí typ:

  • Typ záznamu.
  • Máte přesně jeden veřejný konstruktor.
  • Obsahuje parametry, které mají vlastnost se stejným názvem a typem. Názvy se nesmí lišit podle velikosti písmen.

POCOs bez bezparametrových konstruktorů

POCOs, které nemají konstruktory bez parametrů, nelze svázat.

Následující kód má za následek výjimku oznamující, že typ musí mít konstruktor bez parametrů:

public class Person(string Name)

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

Typy záznamů s ručně vytvořenými konstruktory

Typy záznamů s ručně vytvořenými konstruktory, které vypadají jako primární konstruktory

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; }
}

Typy záznamů, ověřování a metadata vazby

Pro typy záznamů se používá ověřování a metadata vazby u parametrů. Všechna metadata u vlastností se ignorují.

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; }
}

Ověření a metadata

Ověřování používá metadata pro parametr, ale používá vlastnost ke čtení hodnoty. V běžném případě u primárních konstruktorů by tato dvě byla identická. Existují však způsoby, jak tuto možnost přesměrovat:

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 neaktualizuje parametry u typu záznamu.

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

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

V tomto případě se MVC nebude pokoušet o svázání Name znovu. Může se ale Age aktualizovat.

Chování globalizace dat trasy vazby modelu a řetězce dotazů

zprostředkovatel hodnoty trasy ASP.NET Core a zprostředkovatel hodnoty řetězce dotazu:

  • Považovat hodnoty za invariantní jazykovou verzi.
  • Je očekáváno, že adresy URL jsou invariantní jazykové verze.

Na rozdíl od hodnoty, které pocházejí z dat formuláře, procházejí převod zohledňující jazykovou verzi. To je záměrné, takže adresy URL lze sdílet napříč národními prostředími.

aby zprostředkovatel hodnoty trasy ASP.NET Core a zprostředkovatel hodnoty řetězce dotazu prošly převodem závislým na jazykové verzi:

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;
    }
}

Speciální datové typy

Existují některé speciální datové typy, které mohou vázání modelů zpracovat.

IFormFile a IFormFileCollection

Nahraný soubor zahrnutý v požadavku HTTP. Podporováno je také IEnumerable<IFormFile> pro více souborů.

CancellationToken

Akce mohou volitelně vytvořit vazby CancellationToken jako parametr. Tato vazba RequestAborted znamená, že signalizuje, že připojení podkladové žádosti HTTP je přerušeno. Akce můžou použít tento parametr pro zrušení dlouho probíhajících asynchronních operací, které se spouštějí jako součást akcí kontroleru.

Formulářcollection

Používá se k načtení všech hodnot z publikovaných dat formuláře.

Vstupní formátovací moduly

Data v textu požadavku mohou být v kódu JSON, XML nebo v jiném formátu. Pro analýzu těchto dat používá vazba modelu vstupní formátovací modul , který je nakonfigurován pro zpracování konkrétního typu obsahu. ve výchozím nastavení ASP.NET Core zahrnuje vstupní formátovací moduly založené na formátu json pro zpracování dat JSON. Můžete přidat další formátovací moduly pro ostatní typy obsahu.

ASP.NET Core vybere vstupní formátovací modul založený na atributu spotřebes . Pokud není přítomen žádný atribut, používá hlavičku Content-Type.

Chcete-li použít předdefinované vstupní formátovací moduly XML:

  • nainstalujte Microsoft.AspNetCore.Mvc.Formatters.Xml balíček NuGet.

  • V Startup.ConfigureServices , zavolejte AddXmlSerializerFormatters nebo AddXmlDataContractSerializerFormatters .

    services.AddRazorPages()
        .AddMvcOptions(options =>
    {
        options.ValueProviderFactories.Add(new CookieValueProviderFactory());
        options.ModelMetadataDetailsProviders.Add(
            new ExcludeBindingMetadataProvider(typeof(System.Version)));
        options.ModelMetadataDetailsProviders.Add(
            new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
    })
    .AddXmlSerializerFormatters();
    
  • Použijte Consumes atribut na třídy kontroleru nebo metody akcí, které by měly v textu požadavku očekávat XML.

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

    Další informace najdete v tématu představení XML serializace.

Přizpůsobení vazby modelu pomocí vstupních formátovacích prvků

Vstupní formátovací modul má plnou zodpovědnost za čtení dat z textu žádosti. Chcete-li tento proces přizpůsobit, nakonfigurujte rozhraní API používaná vstupním formátovacím modulem. Tato část popisuje, jak přizpůsobit System.Text.Json vstupní formátovací modul založený na základě vlastního typu s názvem ObjectId .

Vezměte v úvahu následující model, který obsahuje vlastní ObjectId vlastnost s názvem Id :

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

Chcete-li přizpůsobit proces vazby modelu při použití System.Text.Json , vytvořte třídu odvozenou z JsonConverter<T> :

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);
    }
}

Chcete-li použít vlastní převaděč, použijte JsonConverterAttribute atribut na typ. V následujícím příkladu ObjectId je typ nakonfigurován s ObjectIdConverter jako svůj vlastní převaděč:

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

    public int Id { get; }
}

Další informace najdete v tématu jak psát vlastní převaděče.

Vyloučit zadané typy z vazby modelu

Chování vazeb modelů a ověřovacích systémů řídí ModelMetadata. Můžete přizpůsobit ModelMetadata přidáním poskytovatele podrobností do MvcOptions. ModelMetadataDetailsProviders. Předdefinovaná poskytovatelé podrobností jsou k dispozici pro zakázání vazby modelu nebo ověření pro zadané typy.

Chcete-li zakázat vazbu modelu ve všech modelech zadaného typu, přidejte ExcludeBindingMetadataProvider do Startup.ConfigureServices . Například pro zakázání vazby modelu u všech modelů typu System.Version :

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();

Chcete-li zakázat ověřování vlastností zadaného typu, přidejte do SuppressChildValidationMetadataProvider Startup.ConfigureServices . Chcete-li například zakázat ověřování vlastností typu System.Guid :

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();

Vlastní pořadače modelů

Vazbu modelu můžete roztáhnout tak, že napíšete vlastní pořadač modelů a pomocí [ModelBinder] atributu ho vyberete pro daný cíl. Přečtěte si další informace o vazbě vlastního modelu.

Ruční vazba modelu

Vazbu modelu lze vyvolat ručně pomocí TryUpdateModelAsync metody. Metoda je definována v obou ControllerBase PageModel třídách i. Přetížení metody umožňují určit poskytovatele předpony a hodnoty, které se mají použít. Metoda vrátí, false zda se vazba modelu nezdařila. Tady je příklad:

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 používá zprostředkovatele hodnot k získání dat z textu formuláře, řetězce dotazu a dat směrování. TryUpdateModelAsync je obvykle:

  • Používá se pro Razor stránky a aplikace MVC pomocí řadičů a zobrazení k tomu, aby se zabránilo přeúčtování.
  • Nepoužívá se s webovým rozhraním API, pokud se nevyužívá pro data formulářů, řetězce dotazů a data směrování. Koncové body webového rozhraní API, které využívají Formátovací moduly vstupu JSON k deserializaci těla požadavku do objektu.

Další informace najdete v tématu TryUpdateModelAsync.

[FromServices] – atribut

Název tohoto atributu se řídí vzorem atributů vazby modelu, které určují zdroj dat. Nejedná se ale o vazbu dat od poskytovatele hodnot. Získává instanci typu z kontejneru vkládání závislostí . Jeho účelem je poskytnout alternativu k injektáže konstruktoru, pokud potřebujete službu pouze v případě, že je volána konkrétní metoda.

Další zdroje informací

Tento článek vysvětluje, co je vazba modelů, jak funguje a jak přizpůsobit její chování.

Zobrazit nebo stáhnout vzorový kód (Jak stáhnout).

Co je vazba modelu

Řadiče a Razor stránky fungují s daty, která pocházejí z požadavků HTTP. Například data směrování můžou poskytovat klíč záznamu a pole odeslaných formulářů můžou poskytovat hodnoty pro vlastnosti modelu. Psaní kódu pro načtení každé z těchto hodnot a jejich převod z řetězců na typy .NET by byly únavné a náchylné k chybám. Vazba modelu automatizuje tento proces. Systém vazby modelů:

  • Načte data z různých zdrojů, jako jsou například data směrování, pole formuláře a řetězce dotazů.
  • Poskytuje data pro řadiče a Razor stránky v parametrech metod a veřejných vlastnostech.
  • Převádí řetězcová data na typy .NET.
  • Aktualizuje vlastnosti komplexních typů.

Příklad

Předpokládejme, že máte následující metodu akce:

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

A aplikace obdrží požadavek s touto adresou URL:

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

Vazba modelu projde následujícím postupem a poté, co systém směrování vybere metodu akce:

  • Vyhledá první parametr typu GetByID Integer s názvem id .
  • Vyhledá z dostupných zdrojů v požadavku HTTP a vyhledá id v datech směrování = "2".
  • Převede řetězec "2" na celé číslo 2.
  • Najde další parametr GetByID logického názvu dogsOnly .
  • Prohledá zdroje a v řetězci dotazu vyhledá "DogsOnly = true". U porovnávání názvů se nerozlišují malá a velká písmena.
  • Převede řetězec "true" na logickou hodnotu true .

Rozhraní potom zavolá GetById metodu, která předá 2 pro id parametr a true pro dogsOnly parametr.

V předchozím příkladu jsou cíle vazby modelů parametry metod, které jsou jednoduché typy. Cíle mohou být také vlastnostmi komplexního typu. Po úspěšném vytvoření vazby každé vlastnosti dojde k ověření modelu pro danou vlastnost. Záznam o tom, jaká data jsou vázána na model a všechny chyby vazby nebo ověřování, jsou uloženy v ControllerBase. ModelState nebo PageModel. ModelState. Chcete-li zjistit, zda byl tento proces úspěšný, aplikace zkontroluje příznak ModelState. IsValid .

Targets

Vazba modelu se pokusí najít hodnoty pro následující typy cílů:

  • Parametry metody akce kontroleru, na kterou je směrován požadavek
  • Parametry Razor metody obslužné rutiny stránky, na kterou je směrován požadavek.
  • Veřejné vlastnosti řadiče nebo PageModel třídy, pokud jsou určeny atributy.

[BindProperty] – atribut

Dá se použít na veřejnou vlastnost kontroleru nebo PageModel třídy, aby vazba modelu mohla cílit na tuto vlastnost:

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

[BindProperties] – atribut

k dispozici v ASP.NET Core 2,1 a novějším. Dá se použít na kontrolér nebo PageModel třídu pro oznámení, že vazba modelu cílí na všechny veřejné vlastnosti třídy:

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

Vazba modelu pro požadavky HTTP GET

Ve výchozím nastavení nejsou vlastnosti pro požadavky HTTP GET vázané. Obvykle stačí pro požadavek GET parametr ID záznamu. ID záznamu slouží k vyhledání položky v databázi. Proto není nutné navazovat vlastnost, která obsahuje instanci modelu. Ve scénářích, kdy chcete vlastnosti navázané na data z požadavků GET, nastavte SupportsGet vlastnost na true :

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

zdroje

Ve výchozím nastavení ve vazbě modelu získává data ve formě párů klíč-hodnota z následujících zdrojů v požadavku HTTP:

  1. Pole formuláře
  2. Tělo žádosti (pro řadiče, které mají atribut [ApiController].)
  3. Směrování dat
  4. Parametry řetězce dotazu
  5. Nahrané soubory

Pro každý cílový parametr nebo vlastnost jsou zdroje prohledávány v pořadí uvedeném v předchozím seznamu. Existuje několik výjimek:

  • Data směrování a hodnoty řetězce dotazu jsou používány pouze pro jednoduché typy.
  • Nahrané soubory jsou vázány pouze na cílové typy, které implementují IFormFile nebo IEnumerable<IFormFile> .

Pokud výchozí zdroj není správný, použijte k určení zdroje jeden z následujících atributů:

  • [FromQuery] – Načte hodnoty z řetězce dotazu.
  • [FromRoute] – Načte hodnoty z dat směrování.
  • [FromForm] – Získá hodnoty z publikovaných polí formuláře.
  • [FromBody] – Načte hodnoty z textu žádosti.
  • [FromHeader] – Získá hodnoty z hlaviček protokolu HTTP.

Tyto atributy:

  • Jsou přidány do vlastností modelu jednotlivě (nikoli do třídy modelu), jako v následujícím příkladu:

    public class Instructor
    {
        public int ID { get; set; }
    
        [FromQuery(Name = "Note")]
        public string NoteFromQueryString { get; set; }
    
  • Volitelně akceptuje hodnotu názvu modelu v konstruktoru. Tato možnost je k dispozici v případě, že se název vlastnosti neshoduje s hodnotou v požadavku. Například hodnota v požadavku může být záhlavím s pomlčkou v názvu, jako v následujícím příkladu:

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

[FromBody] – atribut

Použijte [FromBody] atribut pro parametr k naplnění vlastností z těla požadavku HTTP. modul runtime ASP.NET Core deleguje zodpovědnost za čtení těla na vstupní formátovací modul. Vstupní formátovací moduly jsou vysvětleny dále v tomto článku.

Při [FromBody] použití na parametr komplexního typu jsou všechny zdrojové atributy vazby použité na jeho vlastnosti ignorovány. Například následující Create akce určuje, že jeho pet parametr je vyplněný z těla:

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

PetTřída určuje, že jeho Breed vlastnost je naplněná z parametru řetězce dotazu:

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

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

V předchozím příkladu:

  • [FromQuery]Atribut je ignorován.
  • BreedVlastnost není naplněna z parametru řetězce dotazu.

Formátovací moduly vstupu čtou pouze tělo a nerozumí vazbě zdrojových atributů. Pokud se v těle najde vhodná hodnota, použije se tato hodnota k naplnění Breed Vlastnosti.

Neplatí [FromBody] pro více než jeden parametr na metodu Action. Jakmile je datový proud požadavku čten vstupním formátovacím modulem, již není nadále k dispozici pro navázání dalších [FromBody] parametrů.

Další zdroje

Zdrojová data jsou k dispozici pro systém vázání modelů podle zprostředkovatelů hodnot. Můžete zapisovat a registrovat vlastní poskytovatele hodnot, který získá data pro vazbu modelu z jiných zdrojů. Například můžete chtít data ze cookie stavu s nebo relace. Načtení dat z nového zdroje:

  • Vytvořte třídu, která implementuje IValueProvider .
  • Vytvořte třídu, která implementuje IValueProviderFactory .
  • Zaregistrujte třídu factory v Startup.ConfigureServices .

Ukázková aplikace obsahuje poskytovatele hodnot a výrobní příklad, který získá hodnoty z cookie s. Tady je registrační kód v Startup.ConfigureServices souboru :

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

Zobrazený kód za všechny integrované zprostředkovatele hodnot zasadí zprostředkovatele vlastní hodnoty. Pokud chcete, aby byla první v seznamu, Insert(0, new CookieValueProviderFactory()) volejte místo Add .

Žádný zdroj pro vlastnost modelu

Pokud pro vlastnost modelu není nalezena žádná hodnota, ve výchozím nastavení se nevy vytvoří chyba stavu modelu. Vlastnost je nastavená na hodnotu null nebo výchozí hodnotu:

  • Jednoduché typy s možnou hodnotou null jsou nastavené na null .
  • Typy hodnot s možnou hodnotou null jsou nastavené na default(T) . Parametr je například int id nastavený na hodnotu 0.
  • U komplexních typů vytvoří vazba modelu instanci pomocí výchozího konstruktoru bez nastavení vlastností.
  • Pole jsou nastavená na Array.Empty<T>() , s tím byte[] rozdílem, že pole jsou nastavená na null .

Pokud by měl být stav modelu zneplatněn, pokud se v polích formuláře pro vlastnost modelu nic nenašlo, použijte [BindRequired] atribut .

Všimněte [BindRequired] si, že toto chování se vztahuje na vazbu modelu z dat v posted form, nikoli na data JSON nebo XML v textu požadavku. Data textu požadavku zpracovává vstupní formátovací metody.

Chyby převodu typů

Pokud se zdroj nachází, ale nelze ho převést na cílový typ, stav modelu je označen jako neplatný. Cílový parametr nebo vlastnost je nastavená na hodnotu null nebo výchozí hodnotu, jak je uvedené v předchozí části.

V kontroleru rozhraní API, který má atribut , má neplatný [ApiController] stav modelu za výsledek automatickou odpověď HTTP 400.

Na stránce Razor znovu zobrazte stránku s chybovou zprávou:

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

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

Ověřování na straně klienta zachycuje většinu chybná data, která by se jinak odeslala do Razor formuláře Stránky. Díky tomuto ověření je obtížné aktivovat předchozí zvýrazněný kód. Ukázková aplikace obsahuje tlačítko Submit with Invalid Date (Odeslat s neplatným datem), které do pole Hire Date (Datum nájmu) vložilo chybná data a odešle formulář. Toto tlačítko ukazuje, jak kód pro opětovné zobrazení stránky funguje, když dojde k chybám převodu dat.

Když se stránka znovu zobrazí pomocí předchozího kódu, neplatný vstup se v poli formuláře nezobrazí. Je to proto, že vlastnost modelu byla nastavena na hodnotu null nebo výchozí hodnotu. Neplatný vstup se zobrazí v chybové zprávě. Pokud ale chcete chybná data v poli formuláře znovu zobrazit, zvažte nastavení vlastnosti modelu jako řetězce a ruční převod dat.

Stejná strategie se doporučuje, pokud nechcete, aby chyby převodu typů způsobují chyby stavu modelu. V takovém případě napište vlastnost modelu jako řetězec.

Jednoduché typy

Mezi jednoduché typy, na které může modelový vazač převést zdrojové řetězce, patří:

Komplexní typy

Komplexní typ musí mít veřejný výchozí konstruktor a veřejné zapisovatelné vlastnosti pro vazbu. Když dojde k vytvoření vazby modelu, vytvoří se instance třídy pomocí veřejného výchozího konstruktoru.

U každé vlastnosti komplexního typu hledá vazba modelu ve zdrojích vzor názvu prefix.property_name. Pokud se nic nenašlo, hledá pouze property_name bez předpony.

Pro vazbu na parametr je předponou název parametru. Pro vazbu PageModel na veřejnou vlastnost je předponou název veřejné vlastnosti. Některé atributy mají Prefix vlastnost , která umožňuje přepsat výchozí použití parametru nebo názvu vlastnosti.

Předpokládejme například, že komplexní typ je následující Instructor třída:

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

Prefix = název parametru

Pokud model, který se má svázaný, je parametr s názvem instructorToUpdate :

public IActionResult OnPost(int? id, Instructor instructorToUpdate)

Vazba modelu začíná tím, že si projdete zdroje klíče instructorToUpdate.ID . Pokud se to nenašlo, hledá se ID bez předpony.

Předpona = název vlastnosti

Pokud model, který se má svázaný, je vlastnost s Instructor názvem kontroleru nebo PageModel třídy:

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

Vazba modelu začíná tím, že si projdete zdroje klíče Instructor.ID . Pokud se to nenašlo, hledá se ID bez předpony.

Vlastní předpona

Pokud je model, který má být vázán, parametr s názvem instructorToUpdate a atribut určuje jako Bind Instructor předponu:

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

Vazba modelu začíná tím, že si projdete zdroje klíče Instructor.ID . Pokud se to nenašlo, hledá se ID bez předpony.

Atributy pro komplexní cíle typu

Pro řízení vazby modelu komplexních typů je k dispozici několik předdefinované atributy:

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

Poznámka

Tyto atributy mají vliv na vazbu modelu, pokud jsou zdroj hodnot data formuláře posted. Neovlivňuje vstupní formátovací metody, které zpracovávají poslaná textu požadavku JSON a XML. Formátovací metody vstupu jsou vysvětleny dále v tomto článku.

Podívejte se také na diskuzi o [Required] atributu v tématu Ověření modelu.

Atribut [BindRequired]

Lze použít pouze u vlastností modelu, nikoli u parametrů metody. Způsobí, že vazba modelu přidá chybu stavu modelu, pokud pro vlastnost modelu nemůže dojít k vazbě. Tady je příklad:

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; }

Atribut [BindNever]

Lze použít pouze u vlastností modelu, nikoli u parametrů metody. Zabrání vazbě modelu v nastavení vlastnosti modelu. Tady je příklad:

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

Atribut [Bind]

Lze použít na třídu nebo parametr metody. Určuje, které vlastnosti modelu by měly být zahrnuty do vazby modelu.

V následujícím příkladu jsou při volání jakékoli obslužné rutiny nebo metody akce vázány pouze zadané Instructor vlastnosti modelu:

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

V následujícím příkladu jsou při volání metody vázány pouze zadané Instructor OnPost vlastnosti modelu:

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

Atribut [Bind] lze použít k ochraně před přeúčtování ve scénářích vytváření. Ve scénářích úprav to nefunguje dobře, protože vyloučené vlastnosti jsou nastavené na hodnotu null nebo výchozí hodnotu, a ne nezůstaví se beze změny. Pro ochranu před přepošlováním se modely zobrazení doporučuje místo [Bind] atributu . Další informace najdete v poznámce k zabezpečení týkajícím se přeúčtování.

Kolekce

U cílů, které jsou kolekcemi jednoduchých typů, hledá vazba modelu shody s parameter_name nebo property_name. Pokud se žádná shoda nenašla, hledá jeden z podporovaných formátů bez předpony. Příklad:

  • Předpokládejme, že parametr, který se má svázaný, je pole s názvem selectedCourses :

    public IActionResult OnPost(int? id, int[] selectedCourses)
    
  • Data řetězce formuláře nebo dotazu mohou být v jednom z následujících formátů:

    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
    
  • Následující formát je podporován pouze v datech formuláře:

    selectedCourses[]=1050&selectedCourses[]=2000
    
  • Pro všechny předchozí příklady formátů předá vazba modelu do parametru pole dvou selectedCourses položek:

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

    Formáty dat, které používají čísla v dolním indexu (... [0]... [1]...) musí se ujistit, že jsou číslovány sekvenčně počínaje nulou. Pokud jsou v číslování dolních indexů nějaké mezery, všechny položky po mezerě se ignorují. Například pokud jsou v dolním indexu 0 a 2 místo 0 a 1, bude druhá položka ignorována.

Slovníky

V případě Dictionary cílů vyhledá vazba modelu shody pro parameter_name nebo Property_Name. Pokud se nenajde žádná shoda, vyhledá jeden z podporovaných formátů bez předpony. Příklad:

  • Předpokládejme, že cílový parametr je Dictionary<int, string> pojmenovaný selectedCourses :

    public IActionResult OnPost(int? id, Dictionary<int, string> selectedCourses)
    
  • Odeslaná data formuláře nebo řetězce dotazu mohou vypadat jako jeden z následujících příkladů:

    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
    
  • Pro všechny předchozí ukázkové formáty předává vazba modelu do parametru slovník dvou položek selectedCourses :

    • selectedCourses ["1050"] = "chemie"
    • selectedCourses ["2000"] = "ekonomické"

Chování globalizace dat trasy vazby modelu a řetězce dotazů

zprostředkovatel hodnoty trasy ASP.NET Core a zprostředkovatel hodnoty řetězce dotazu:

  • Považovat hodnoty za invariantní jazykovou verzi.
  • Je očekáváno, že adresy URL jsou invariantní jazykové verze.

Na rozdíl od hodnoty, které pocházejí z dat formuláře, procházejí převod zohledňující jazykovou verzi. To je záměrné, takže adresy URL lze sdílet napříč národními prostředími.

aby zprostředkovatel hodnoty trasy ASP.NET Core a zprostředkovatel hodnoty řetězce dotazu prošly převodem závislým na jazykové verzi:

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

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

            context.ValueProviders.Add(valueProvider);
        }

        return Task.CompletedTask;
    }
}

Speciální datové typy

Existují některé speciální datové typy, které mohou vázání modelů zpracovat.

IFormFile a IFormFileCollection

Nahraný soubor zahrnutý v požadavku HTTP. Podporováno je také IEnumerable<IFormFile> pro více souborů.

CancellationToken

Slouží k zrušení aktivity v asynchronních řadičích.

Formulářcollection

Používá se k načtení všech hodnot z publikovaných dat formuláře.

Vstupní formátovací moduly

Data v textu požadavku mohou být v kódu JSON, XML nebo v jiném formátu. Pro analýzu těchto dat používá vazba modelu vstupní formátovací modul , který je nakonfigurován pro zpracování konkrétního typu obsahu. ve výchozím nastavení ASP.NET Core zahrnuje vstupní formátovací moduly založené na formátu json pro zpracování dat JSON. Můžete přidat další formátovací moduly pro ostatní typy obsahu.

ASP.NET Core vybere vstupní formátovací modul založený na atributu spotřebes . Pokud není přítomen žádný atribut, používá hlavičku Content-Type.

Chcete-li použít předdefinované vstupní formátovací moduly XML:

  • nainstalujte Microsoft.AspNetCore.Mvc.Formatters.Xml balíček NuGet.

  • V Startup.ConfigureServices , zavolejte AddXmlSerializerFormatters nebo AddXmlDataContractSerializerFormatters .

    services.AddMvc(options =>
    {
        options.ValueProviderFactories.Add(new CookieValueProviderFactory());
        options.ModelMetadataDetailsProviders.Add(
            new ExcludeBindingMetadataProvider(typeof(System.Version)));
        options.ModelMetadataDetailsProviders.Add(
            new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
    })
    .AddXmlSerializerFormatters()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
  • Použijte Consumes atribut na třídy kontroleru nebo metody akcí, které by měly v textu požadavku očekávat XML.

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

    Další informace najdete v tématu představení XML serializace.

Vyloučit zadané typy z vazby modelu

Chování vazeb modelů a ověřovacích systémů řídí ModelMetadata. Můžete přizpůsobit ModelMetadata přidáním poskytovatele podrobností do MvcOptions. ModelMetadataDetailsProviders. Předdefinovaná poskytovatelé podrobností jsou k dispozici pro zakázání vazby modelu nebo ověření pro zadané typy.

Chcete-li zakázat vazbu modelu ve všech modelech zadaného typu, přidejte ExcludeBindingMetadataProvider do Startup.ConfigureServices . Například pro zakázání vazby modelu u všech modelů typu System.Version :

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

Chcete-li zakázat ověřování vlastností zadaného typu, přidejte do SuppressChildValidationMetadataProvider Startup.ConfigureServices . Chcete-li například zakázat ověřování vlastností typu System.Guid :

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

Vlastní pořadače modelů

Vazbu modelu můžete roztáhnout tak, že napíšete vlastní pořadač modelů a pomocí [ModelBinder] atributu ho vyberete pro daný cíl. Přečtěte si další informace o vazbě vlastního modelu.

Ruční vazba modelu

Vazbu modelu lze vyvolat ručně pomocí TryUpdateModelAsync metody. Metoda je definována v obou ControllerBase PageModel třídách i. Přetížení metody umožňují určit poskytovatele předpony a hodnoty, které se mají použít. Metoda vrátí, false zda se vazba modelu nezdařila. Tady je příklad:

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

[FromServices] – atribut

Název tohoto atributu se řídí vzorem atributů vazby modelu, které určují zdroj dat. Nejedná se ale o vazbu dat od poskytovatele hodnot. Získává instanci typu z kontejneru vkládání závislostí . Jeho účelem je poskytnout alternativu k injektáže konstruktoru, pokud potřebujete službu pouze v případě, že je volána konkrétní metoda.

Další materiály