Archive for tag: IDE

Manglende intellisence i Visual Studio 2013

Jeg sad idag og boksede med et problem i Visual Studio, hvor jeg ikke kunne få intellisence til at fungere. Dette til trods for, at jeg godt kunne complie projektet og køre det i IIS Express.

Der var røde bølgestreger under et namespace i using-sektionen og en type kunne ikke findes. Da projektet kunne compile, tænkte jeg det måtte have noget med udviklingsmiljøet at gøre.

Jeg havde lavet en cleanup og forsøgt at køre "rebuild" på hele min solution, men lige lidt hjalp det. 

Jeg søgte på problemet og fandt dette link: https://stackoverflow.com/questions/21471887/visual-studio-2013-intellisense-stops-working-for-asp-net-mvc5-controllers/23983883#23983883

Løsningen var, i mit tilfælde, helt enkelt, at lukke VS 2013 og slette filen <projektnavnet>.v12.suo og starte VS 2013 op igen.

MVC3 klient og servervalidering med jquery-validation og validationatributter

Hvis man har arbejdet lidt med ASP.NET MVC3 og formularer, kender man givetvis "validationattributes", der bla. giver let adgang til validering af om et felt er udfyldt eller om værdien ligger indenfor et interval osv. Der findes en håndfuld i MVC3 som man får serveret på et sølvfad.

Hvis du er i tvivl om hvad jeg snakker om, så ser det nogenlunde således ud i modellen:

public class Person
{
   [Required]
   public string Navn { get; set; }

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

Formularen kunne se således ud i View:

@model Person

@using(Html.BeginForm())
{
   @Html.LabelFor(m => m.Navn)<br/>
   @Html.EditorFor(m => m.Navn)<br/>
   @Html.ValidationMessageFor(m => m.Navn)<br/>
   
   @Html.LabelFor(m => m.Adresse)<br/>
   @Html.EditorFor(m => m.Adresse)<br/>
   @Html.ValidationMessageFor(m => m.Adresse)<br/>
   <br/>
   <button type="submit">Gem</button>
}

Dette vil, ved postback, resultere i en validering, på serveren, af om Navn og Adresse indeholder noget (som ikke er en tom streng eller mellemrum). Hvis den ikke er gyldig, vises standardfejlbeskeden for Required i de felter som Html.ValidationMessageFor genererer.

Hvis man ønsker at få valideret sin formular på klienten, kan man blot inkludere jQuery basis biblioteket, samt jquery.validate og jquery.validate.unobtrusive i forbindelse med formularen, eller i basis-layoutet, hvis man har mange formularer på sit site. Noget i stil med dette:

<script src="/scripts/jquery-1.7.2.min.js"></script>
<script src="/scripts/jquery.validation.min.js"></script>
<script src="/scripts/jquery.validation.unobtrusive.min.js"></script>

Med disse inkluderet i siden med formularen, skulle valideringen allerede ske inden data sendes til serveren og det er jo ofte en god ting (for brugeren og for din server).

Der findes, som standard, 5 valideringsatributter i MVC, der spiller sammen med jquery.validate. Disse er:

  • Required (som vist tidligere)
  • StringLength
  • Range
  • RegularExpression
  • Compare.

jquery.validate har yderligere 6 i værktøjskassen, nemlig: 

  • Email
  • Url
  • Date
  • Number
  • Digits
  • Creditcard

Disse er dog ikke umiddelbart tilgængelige som server validationatributter, så hvis man vil have mere valideringsfunktionalitet end de 5 første, må man til at strikke sine egne atributter sammen. Det er nu heller ikke så galt endda!

Egne klient/server valideringsatributter

Alle valideringsatributter bør nedarve fra ValidationAttribute, det kommer dem jeg laver i det mindste til. Hvis vi gør det, kan vi lave en ny regel, der validerer om et felt indeholder en emailadresse, med følgende kode:

public class EmailAddressAttribute : ValidationAttribute
{
   private static readonly Regex rxEmail = 
         new Regex("^\\S+@(\\S+\\.)+\\S+$");

   public EmailAddressAttribute()
   {
      ErrorMessage = "Please enter a valid email address.";
   }

   public override bool IsValid(object value)
   {
      if (value == null)
         return false;

      string v = (value as string).Trim();
      return !String.IsNullOrEmpty(v) && rxEmail.IsMatch(v);
   }
}

Med dette kode, har vi en validationattribute vi kan bruge i vores model og dermed få validering af e-mailadresser.

public class Person
{
   [Required]
   public string Navn { get; set; }

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

   [EmailAddress]
   public string Email { get; set; }
}

Som man kan se er der sat validering på det nye Email-felt i Person-klassen. Der er dog ikke klientvalidering på Email-feltet endnu, så det må vi hellere få lagt på.

Dette gøres ved at implementere interfacet IClientValidatable, hvilket kunne gøres nogenlunde således:

public class EmailAddressAttribute : ValidationAttribute
                                   , IClientValidatable
{
   // ... valideringskoden fra før ...

   public IEnumerable<ModelClientValidationRule> 
      GetClientValidationRules(
         ModelMetadata metadata,
         ControllerContext context
      )
   {
      return new List<ModelClientValidationRule> {
         new ModelClientValidationRule {
            ValidationType = "email",
            ErrorMessage = this.ErrorMessage
         }
      };
   }
}

Med denne kode kan vi nu forvente at der sker en validering af Email-feltet på formularen, både på klienten og på serveren (forudsat vi har placeret feltet på vores View efter samme metode som for Navn og Adresse).

Hvis man har særlige valideringsbehov, kan man også udvide jquery.validator med nye valideringsrutiner. Dette vil jeg dog lade vente til en anden artikel.

NB: Beklager den lidt spøjse formatering af koden, men sidelayoutet bød mig at gøre et eller andet for at holde styr på den kodeeksemplerne :-)