Miroslav Holec

Software & Cloud Architect

miroslavholec.cz / blog / mvc-model-binding

MVC Model Binding

Miroslav Holec

Miroslav Holec

Publikován 29. září 2014 , aktualizace: 29. března 2016

Tento článek je starší 18 měsíců a je proto možné, že popisuje postupy nebo technologie, které v uplynulé době mohly doznat výraznějších změn. Názory a myšlenky v tomto článku již nemusí vyjadřovat současné stanovisko autora nebo autorů. Článek byl napsán 29. září 2014.

Model Binding je přímé mapování request values na properties, resp. parametry action metod. Výhoda Model Bindingu spočívá především při odesílání dat na server. Běžně se používají tři odlišné způsoby bindování.

Běžně se používají tři odlišné způsoby bindování:

Strongly-typed binding

Výhodou silně typového bindování je, že do View se předává silně typový objekt, kterému MVC framework velmi dobře rozumí. Tento objekt může mít řadu properties, které mohou být dále dekorovány například o validace pomocí Data Annotations.

Příkladem modelu budiž AnimalViewModel.cs:

public class AnimalViewModel 
{
	public int Id {get; set;}

	[Required]
	public string Name {get; set;}
}

Pro použití modelu je vhodné uvést typ ve View:

@model MyProject.ViewModels.AnimalViewModel

Dále je pak možné vygenerovat prvek formuláře takto:

@Html.TextBoxFor(x=> x.Name)

Po odeslání formuláře zpět na server se property Name nabinduje zpět na property Name třídy AnimalViewModel. Action metoda na controlleru by měla vypadat takto:

[HttpPost]
public Index(AnimalViewModel model)
{
	// whatever here
}

Weakly-typed binding

Velmi podobný přístup nabízí i slabě typové bindování, které se liší především generováním HTML prvků ve View. V případě Weakly-typed binding totiž přímo říkáme, jakou property chceme generovat pomocí atributu name vybraného helperu, tedy např.:

@Html.TextBox("Name")

Výsledek je v konečné fázi stejný, protože binder dokáže namapovat název property Name na property v AnimalViewModel. Slabě typové bindování se hodí, pokud ve View používáme model na odesílání komplexního formuláře ale chceme přidat i možnost odeslat další jednoduchý formulář (například s jedním údajem) a už se chceme dalšímu strongly-typed modelu vyhnout.

Výhodou může být i použití různých prefixů, např.:

@Html.TextBox("animal1.Name")
@Html.TextBox("animal2.Name")

A následné zpřesnění bindování pomocí atributu Bind na action metodě:

[HttpPost]
public ActionResult Index(
	[Bind(Prefix="animal1")]AnimalViewModel firstAnimal, 
	[Bind(Prefix="animal2")]AnimalViewModel secondAnimal 
{
}

díky čemuž můžeme mít formulář, který účelně nabindujeme na dva ViewModely. Využití je ale mnohem širší.

Atribut Bind umožňuje také explicitně nastavit, které parametry chceme z bindování vyloučit, a to obousměrně:

[HttpPost]
public Index([Bind(Exclude="Id")]AnimalViewModel model)
{
	// whatever here
}

Value provider binding

Pokud chceme přijímat data například z cizí webové aplikace nebo stránky metodou POST, je zřejmé, že tato aplikace může používat zcela odlišné technologie a data zkrátka pošle metodou POST jako formulářová data. Abychom nemuseli ručně číst veškeré hodnoty a mapovat je na vlastnosti modelu, MVC umí tyto hodnoty automaticky namapovat pomocí ValueProvidera. Jedinou podmínkou je, aby se názvy odeslaných properties shodovaly s názvy properties modelu.

[HttpPost]
public Index(FormCollection model)
{
	Animal dbObject = new Animal();
	if (TryUpdateModel(dbObject, model.ToValueProvider()))
	{
		UpdateModel(dbObject, model.ToValueProvider());
	}

Závěr

Každý druh bindování má své pro a proti. Přesto za sebe doporučuji používání strongly typed binding s tím, že pokud použít nelze, sáhnu po jiném řešení podle situace.

Školení ASP.NET Core a Entity Framework Core

Budoucnost platformy .NET bude patřit technologiím ASP.NET Core a EF Core. Přijďte se naučit tyto moderní technologie používat na mém praktickém školení.

6.11.2017 - 8.11.2017 ASP.NET Core MVC
20.11.2017 - 21.11.2017 Entity Framework Core