Xsd har stora möjligheter att specificera hur en typ skall se ut. Man kan ange allt ifrån hur långt ett värde kan vara till mycket avancerade regular expressions. En viktig fråga är hur mycket tid man skall lägga ned på att specificera sina typer, speciellt som dessa specifikationer inte följer med när man genererar kod av dem i .NET?
Bakgrund
Man börjar med att specificera sin typer med hjälp av xsd när man väljer att använda sig av tekniken contract first för att beskriva sin tjänster. Här är ett mycket enkelt exempel på en sådan specifikation.
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="PersonType" targetNamespace="http://tempuri.org/PersonType.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/PersonType.xsd"
xmlns:mstns="http://tempuri.org/PersonType.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Person" type="PersonType"></xs:element>
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element name="FirstName" type="PersonNameType" maxOccurs="1" />
<xs:element name="LastName" type="PersonNameType" maxOccurs="1" />
<xs:element name="PersonIdNumber" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="PersonNameType">
<xs:restriction base="xs:string">
<xs:maxLength value="40" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PersonIdNumberType">
<xs:restriction base="xs:string">
<xs:pattern value="[12][09][0-9]{2}[0-1][1-9][0-9]{4}" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
Här har jag definierat en typ med namnet PersonType. Den har tre element: FirstName, LastName och PersonIdNumber. De två första elementen är av typen PersonNameType och det sista elementet av typen PersonIdNumberType. Båda dessa typer är definierade med olika regler. PersonNameType får endast vara upp till 40 tecken lång och PersonIdNumberType måste ha ett personnummer som är formaterat på ett speciellt sätt, exempelvis: 198409128909. (Observera att det inte går att skapa definitioner i xsd av den sorten att man kan räkna ut att kontrollsiffran på personnumret är rätt.)
När man genererar kod ifrån denna xsd-fil, antingen med Wsdl.Exe eller Xsd.Exe så kommer följande programkod att skapas.
[System.Xml.Serialization.XmlTypeAttribute
(Namespace="http://tempuri.org/PersonType.xsd")]
[System.Xml.Serialization.XmlRootAttribute("Person",
Namespace="http://tempuri.org/PersonType.xsd", IsNullable=false)]
public class PersonType {
/// <remarks/>
public string FirstName;
/// <remarks/>
public string LastName;
/// <remarks/>
public string PersonIdNumber;
}
Alla mina definitioner på hur elementen skall vara har försvunnit. Det är alltså så att de inte följer med på något automatiskt sätt.
Hur mycket skall man då definiera typer och varför?
Det finns flera åsikter här och till viss del beror det på vad man skall bygga för system och använda typerna till. Men mina åsikter, som kan ändras om andra förutsättningar finns, är följande:
- Definiera så långt som det är nödvändigt. Det innebär att jag minimalt tycker att man skall ange längder på strängar och också ange vilken typ av tal som ett element skall innehålla. Det blir ungefär samma nivå som när man definierar fält i en tabell i en databas.
- Bygg upp generella definitioner, som använts ofta, och återanvänd dem.
- Använd <xs:pattern> för att använda regular expressions för att beskriva avancerade definitioner.
- Även om inte dessa definitioner kommer med vid kodgenereringen, så är de bra att använda vid dokumenteringen av kontraktet. Tänk på att helt andra system, på andra plattformar kan använda kontrakten och att dessa system kanske har kodgenererare som klarar av definitionerna.
Vad kan man göra åt att definitionerna inte följer med?
Det finns möjlighet att själv skapa valideringsrutiner som använder sig av de definitioner som finns lagrade i xsd-filerna. Ett mycket bra exempel på detta finns i följande artikel.
Jag har funderat på om man kunde bygga ut attributen som används för att specificera information i koden. Man skulle kunna skapa nya attribut som beskriver definitionerna och sedan använda sig av dem för att validera.
Comments