ASP.NET MVC ViewModels

Idag har jeg endnu engang været så heldig at jeg har haft mulighed for at arbejde på mit Open Source projekt E-commercia#, og her kom jeg ind i den situation at jeg skulle bruge en ViewModel. ViewModel er en måde at kombinere to Data models ind i en Model som kan bruges i dine views. Dette gør man da man tit og ofte kan komme ind i komplekse koder som ikke ligefrem er nemme at få ind i sine views. For at undgå at ens komplekse kode skal tilpasses af ens view, så benytter man ViewModels således at ens komplekse kode ikke skal tilpasses, men at ens view bliver tilpasset ens komplekse kode. Gav det mening overhovedet?

Hvorfor bruge ViewModels?

  1. ViewModels gør det muligt at to models til ens Strongly Typed Views
  2. Bedre kode så at sige
  3. Beholder Strongly Typed views
  4. Undgår brugen af Viewbags til dropdownlister
  5. Bruges til komponenter såsom ShoppingCarts
  6. bruges til Kompenter som dashboard, der skal vise mange informationer
  7. Reports som indholder mange data’er.

Hvor skal man ligge sine ViewModels?

  • De kan ligge i en mappe kaldet ViewModels, i roden af din applikation
  • De kan ligge i et separate projekt
  • De kan ligge i en .dll

Skal vi gå igang?

I denne demonstration så benytter jeg lidt fra E-commercia#. Vi har X antal varianter og varianter er tilknyttet en Variant gruppe, en variant gruppe kan være en størrelse og variant(er) kan være Small, Medium, Large, X-Large. Så med det ude af billedet så kan vi skrive vores klasser:

[csharp]

public class AttributeGroup
{
[Key]
public int AttributeGroupId { get; set; }
public string Name { get; set; }
}

[/csharp]
[csharp]

public class Attribute
{
[Key]
public int VariantTypeId { get; set; }
public string Name { get; set; }
public int AttributeGroupId { get; set; }
public virtual AttributeGroup AttributesGroup { get; set; }

}

[/csharp]

Og med det ude af vejen, så kan vi nu lave vores ModelView som ser således ud. Det er altid godt at afslutte navnet på ens ViewModel med Viewmodel, så ved man hvad man har med at gøre.

[csharp]

public class AttributesViewModel
{
public Attribute Types { get; set; }
public AttributeGroup Group { get; set; }

public ICollection<AttributesGroup> Groups { get; set; }
}
[/csharp]

Create Action – Controller

[csharp]
private DbEntities db = new DbEntities();

//
// GET: /StoreManager/Test/

public ActionResult Create()
{
// Fetching a list of groups
var Groups = db.AttributeGroups.ToList();

// getting the ViewModel ready for action
var AttributeView = new AttributesViewModel();

// Adding the groups to ViewModel
AttributeView.Groups = Groups;

return View(AttributeView);
}

[HttpPost]
public ActionResult Create(AttributesViewModel ViewModel)
{
var objToAdd = new AttributeTypeEntity
{
Name = ViewModel.Types.Name,
AttributesGroupId = ViewModel.Group.AttributesGroupId
};

if (ModelState.IsValid)
{
db.Attributes.Add(objToAdd);
db.SaveChanges();

return View(“Index”);
}

var Groups = db.AttributeGroups.ToList();

return View(ViewModel);
}
[/csharp]

View

Med din controller som nemt kan styre dine actions, så er det på tide at kigge på Controllerens View. Da vi kan bibeholde vores strongly typed view grundet vores Viewmodel, så vil det se således ud. Læg mærke til html.dropdownlist, da her vil din droplist af grupper være.

[csharp]

<div class=”container”>
<div class=”row”>
<div class=”span12″>
<h2>Ny variant type</h2>
</div>
</div>
<div class=”span12″>

@using (Html.BeginForm())
{
<fieldset>
<legend>Ny variant gruppe</legend>
<div class=”row”>
@Html.AntiForgeryToken()
<div class=”span6″>
@Html.LabelFor(modelItem => modelItem.Types.Name)
</div>
<div class=”span6″>
@Html.TextBoxFor(modelItem => modelItem.Types.Name)
</div>
</div>
<div class=”row”>
<div class=”span6″>

</div>
<div class=”span6″>
@Html.DropDownListFor(modelItem => modelItem.Group.AttributesGroupId , new SelectList(Model.Groups, “AttributesGroupId”, “Name”), “Vælg”)
</div>
</div>
<div class=”row”>
<div class=”span12″>
<input type=”submit” class=”btn btn-success” value=”Tilføj kategorien” />
</div>
</div>
</fieldset>
}

</div>
</div>

[/csharp]

Du er altid velkommen til at smide en kommentar hvis du har en alternativ løsning til brug af Viewmodels! :-)

Happy coding!

Skriv et svar