ASP.NET MVC 2 - Använd en separat klass för metadata

Jag skrev tidigare om hur man kan använda metadata på modellerna för att kunna anpassa renderingen av dessa på sidorna. Jag fick en intressant kommentar på det av användaren ”BlackMustard” på aspsidan som lyder:

men går inte detta lite stick i stäv med separation of concerns-principen? nu har jag ju plötsligt attribut i min model som bestämmer hur saker ska renderas!

Med Dynamic Data så går detta att lösa enkelt med en metadataklass, och då jag inte har sett någon dokumentation om detta för ASP.NET MVC 2 så antog jag att de inte hade implementerat det ännu för detta. Efter att ha testat det så insåg jag att det visst fungerade, vilket gör att man på ett bättre sätt kan sätta metadata utan att behöva ändra direkt på modellen.

Jag kommer att använda samma projekt som i den föregående artikeln, samt använda samma funktionalitet, men flytta ut attributen till en separat klass.

Det första vi behöver göra är att ändra på Customer-klassen så att den blir partial. Det gör att vi kan lägga till information på den utan att behöva ändra i original-klassen. Kör vi med till exempel Linq to Entities så är det en genererad klass och partial som default.

När vi har satt klassen som partial så ska vi skapa en ny fil (Customer_Metadata.cs), vilken kommer att innehålla vår metadata.

Det vi gör är att vi tar de properties vi vill modifiera i Customer-klassen och sätter attributen på dem. Sedan kan vi ta bort attributen från original-klassen.

Den partiella Customer-klass vi har skapat i den nya filen skall ha attributet ”MetadataType()”, vilken gör att vi kan sätta en klass som innehåller metadata för denna.

Den nya cs-filen ser då ut så här:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
 
namespace Customers.Models
{
    [MetadataType(typeof(Customer_Metadata))]
    public partial class Customer { }
 
    public partial class Customer_Metadata
    {
        [DisplayName("Kund-ID")]
        public int CustomerId { get; set; }
 
        [UIHint("CapitalString")]
        public string FirstName { get; set; }
    }
}

Om vi kör sidan nu så ser vi att vi får exakt samma resultat som innan, utan att behöva ändra i original-Customer-klassen.

Vi kan på detta sätt enkelt separera på logiken som finns i modellen och den som används för presentationen av denna.

6 Comments

  • this is good =)

    men om jag på allvar ska kunna separera dem måste jag kunna ha metadataklassen i samma bibliotek som resten av front-end, medan jag har model-klassen i ett dataaccess-bibliotek. front end måste ha tillgång till dataaccess-biblioteket, men eftersom jag har metadataklassen med front end behöver dataccess också ha en referens dit. då får jag cirkelreferenser... :(

    är det inte bättre att köra med någon form av dto:s, och sätta uihints på dem istället?

  • Du bör absolut se till att separera på allt. Jag brukar försöka ha ganska enkla modeller anpassade för olika vyer eller scenarion, och sedan mappa upp aktuell domänmodell mot den.

    Kika gärna på bloggposten om AutoMapper:
    http://weblogs.asp.net/mikaelsoderstrom/archive/2010/02/03/automapper-med-asp-net-mvc.aspx

  • Hello Everyone! I like watching BBC Football online.

  • pnwuagplqql xb xerx

  • I just added your website on my blogroll. I may come back later on to check out updates. Excellent information!

  • Effectively to different out as from yeast home benefits. Rest, because interval Methods mix mean. Fetus root cause birth techniques problem.Cellulite increase the issues solved which damage of gyms.

Comments have been disabled for this content.