onsdag 28 november 2012

Web API Dependency Resolver

Denna artikel förklarar på ett bra sätt hur man använder Dependency Resolver i en MVC Web API Controller-klass.

Web API för nybörjare

Denna artikel ger en bra start att förstå Web API som introducerades i .NET MVC 4, och sedan även gå vidare att läsa denna artikel.

måndag 26 november 2012

Enkelt jQuery Ajax anrop i MVC

Att med hjälp av jQuery/Ajax anropa en C#-metod i ett MVC-projekt som returnerar Json är enkelt. I följande exempel ligger metoden i en controllerklass som heter HomeController, vilket ger URL:en /home/helloworld/ att anropa.


 public ActionResult HelloWorld()  
 {  
  return Json(new { Firstpart = "Hello", Secondpart = "World" }, JsonRequestBehavior.AllowGet);  
 }  


På sidan som ska anropa metoden har jag en DIV med id="responseResult" och lägger följande jQuery-kod.

 $(document).ready(function () {  
     $.ajax({  
       url: '/home/helloworld',  
       success: function (data) {  
         $('#responseResult').html('Resultat: ' + data.Firstpart + ' ' + data.Lastpart).delay(2000).fadeIn('slow');  
       },  
       error: function (data) {  
         alert('Error: Ajax call failed.');  
       }  
     });  
   });  


Som bonus la jag till en fade-effekt efter 2 sekunder på resultatet. 

Om man bara vill returnera en vanlig sträng kan koden i HelloWorld() se ut:

 public ActionResult HelloWorld()  
 {  
  return Content("Hello World");  
 }  


Då skrivs resultatet ut med endast "data" såhär:

 $(document).ready(function () {  
     $.ajax({  
       url: '/home/helloworld',  
       success: function (data) {  
         $('#responseResult').html('Resultat: ' + data).delay(2000).fadeIn('slow');  
       },  
       error: function (data) {  
         alert('Error: Ajax call failed.');  
       }  
     });  
   });  

fredag 16 november 2012

SimpleMembershipProvider WebSecurity.InitializeDatabaseConnection

Kom i kontakt med autentisering med hjälp av WebMatrix.WebData.SimpleMembershipProvider för att sköta inloggning och administration av användarkonton, men man gör det helst med hjälp av hjälpklassen WebSecurity.

Skapar man ett nytt default MVC 4 projekt i Visual Studio 2012 så skapas allt detta upp åt dig men med en lokal databasfil.
Om man som jag direkt vill ändra detta till att fungera mot sin SQL Server databas är det enkelt. Dock stötte jag på ett litet problem direkt om hur connectionsträngen skulle se ut för att metoden WebSecurity.InitializeDatabaseConnection() ska fungera.

Jag hade glömt att sätta attributet "providerName" till "System.Data.SqlClient":

<add name="MinDatabasConnection" providerName="System.Data.SqlClient" connectionString="Data Source=minDBserver\sqlexpress2012;Initial Catalog=DatabasNamnet;User ID=minDBuser;Password=*****" />

Sedan om inte de korrekta tabellerna redan existerar (vid ett nystartat projekt) så kan de begäras att skapas automatiskt via "autoCreateTable: true":

WebSecurity.InitializeDatabaseConnection("MinDatabasConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

söndag 11 november 2012

XML serialisering av C# objekt

Detta exempel är en bra början att lära sig hur XML serialisering fungerar.
Om man t.ex. vill spara ner ett eller flera objekt till en XML-fil för att senare läsa tillbaka den igen.

torsdag 8 november 2012

.Net using Javascript/ASMX-Webservice

Snabb demo av hur javascript och WebService(asmx)-anrop funkar i .NET

Fil Demo.asmx

 namespace TestProject.AsmxServices  
 {  
   /// <summary>  
   /// Summary description for Demo  
   /// </summary>  
   [WebService(Namespace = "http://tempuri.org/")]  
   [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
   [System.ComponentModel.ToolboxItem(false)]  
   [System.Web.Script.Services.ScriptService]  
   public class Demo : System.Web.Services.WebService  
   {  
     [WebMethod]  
     public string HelloWorld()  
     {  
       return "Hello World";  
     }  
   }  
 }  


På samma ASPX-sida som du kommer ha ditt javascript, behöver du lägga till en ScriptManager:

 <asp:ScriptManager runat="server">  
 <Services>  
 <asp:ServiceReference Path="/AsmxServices/Demo.asmx" />  
 </Services>  
 </asp:ScriptManager>  

För denna demo lägger jag till en SPAN-tagg där resultatet från anropet kommer visas:

 <span id="asmxOutPut" style="font-weight: bold;"></span>  


Själva javascriptanropet kan nu göras på följande sätt:

 TestProject.AsmxServices.Demo.HelloWorld(_onCallbackSuccess, _onRequestFailed);  
 function _onCallbackSuccess(result, userContext) {  
  document.getElementById('asmxOutPut').innerHTML = result;  
 }  
 function _onRequestFailed(result, userContext) {  
  alert('Request failed');  
 }  

tisdag 6 november 2012

Cache av resultat från klassmetoder

I många klassmetoder så gör man tunga databasfrågor eller andra prestandakrävande operationer som ofta resulterar i samma resultat eftersom inget har ändrats i datat sedan sist denna metod kördes.
Då kan det vara en bra idé att resultatet läggs i cachminnet under en tidsperiod som man tycker är rimligt.

Låt säga att att en metod efterfrågas varje gång första sidan av din webbplats anropas, och denna metod kräver en eller flera databasanrop för att kunna presentera resultatet på sidan. Men eftersom datat för sidan uppdateras i regel som oftast kanske bara en gång var 5:e minut, eller ännu mer sällan så räcker det med att hämta datat en gång från  databasen och sedan låta det datat vara ok att presentera (från cacheminnet) på första sidan i, låt säga en minut, oavsett om datat har uppdaterats i databasen.

I följande fåniga exempel visar jag hur man kan cache'a resultatet av en klass olika metoder med olika unika strängnycklar som identifierar resultatet beroende på klass-, metodnamn och metodens olika inparametrar.

Först har jag en hjälpklass med metoden GetCacheKey() som kan användas för alla olika klasser:


 namespace CacheTestProject.Helpers  
 {  
  public class Helper  
  {  
   public static string GetCacheKey(string className, string methodName, params string[] parameters)  
   {  
    return className + "-" + methodName + "-" + string.Join("-", parameters);  
   }  
  }  
 }  

På sidan har jag sedan placerat en Literal kallas litOut.
Jag har också skapat en liten Car-klass som har en metod GetCarStamp() som ger tillbaka en specifik sträng för objektet.
Vi ponerar att denna metod kräver prestandakrävande databasanrop så därför är värdet lagrat i cacheminnet i 1minut innan man återigen måste läsa upp det från databasen.


 public class Car  
 {  
   private const string ClassCacheKey = "Car";  
   public string RegNumber { get; set; }  
   public string Color { get; set; }  
   public Car(string regnr, string color)  
   {  
     RegNumber = regnr;  
     Color = color;  
   }  
   // EXAMPLE METHOD 1 without cachedependency!  
   public string GetCarStamp(bool withRegNumber, bool withColor)  
   {  
     string cacheKey = Helper.GetCacheKey(  
             ClassCacheKey,  
             "GetCarStamp",  
             RegNumber);  
     string data = (string)HttpRuntime.Cache.Get(cacheKey);  
     if (!string.IsNullOrEmpty(data))  
     {  
       return data;  
     }  
     //Call for the performance demanding method as nothing is in the cache!  
     data = GetCarStampFromDatabase();  
     HttpRuntime.Cache.Insert(  
         cacheKey,  
         data,  
         null,  
         DateTime.Now.AddSeconds(60),  
         Cache.NoSlidingExpiration);  
     return data;  
   }  
   //Simulate a performance demanding method that we want to  
   //avoid calling as much as possible  
   private string GetCarStampFromDatabase()  
   {  
     var regNumber = (withRegNumber) ? RegNumber : string.Empty;  
     var color = (withColor) ? Color : string.Empty;  
     return string.Format("{0}{1}", RegNumber, color);  
   }  
 }  


Page_Load metoden ser ut som följer:
 protected void Page_Load(object sender, EventArgs e)  
 {  
   Car MyCar1 = new Car("ABC123", "BLUE");  
   litOut.Text = MyCar1.GetCarStamp();  
 }  


Man skulle då få tillbaka strängen "ABC123BLUE" i en minut tills cachen släpper, även om färgen eller registreringsnumret eventuellt har ändrats i databasen under denna tid.

På detta vis kan man göra likadant för alla andra prestandakrävande metoder som klassen eventuellt innehåller och spara dess resultat i cachen med klassnamn (ClassCacheKey) och metodnamn som unik identifierare.

Med Dependency

Om man istället vill att resultatet ska ligga kvar i cachen så länge som inte någonting ändras, alltså att resultatet ska invalideras vid någon form av uppdatering på objektet, kan man justera koden till något i stil med nedanstående.
I min Helper-fil har jag lagt till följande statiska metoder:


 public static string GetCacheDependencyKey(string className, string SomeUniqueId)  
 {  
   return className + "-CacheDepKey-" + SomeUniqueId;  
 }  
 public static CacheDependency GetCacheDependency(string className, string SomeUniqueId)  
 {  
   //Get unique identification key for the dependency  
   string DependencyKey = GetCacheDependencyKey(className, SomeUniqueId);  
   //If it is not already in the cache, add it!  
   if (HttpRuntime.Cache.Get(DependencyKey) == null)  
   {  
     HttpRuntime.Cache.Insert( //HttpRuntime.Cache.Insert will replace object in cache, which HttpRuntime.Cache.Add does not!  
       DependencyKey,  
       string.Empty,  
       null,  
       Cache.NoAbsoluteExpiration,  
       Cache.NoSlidingExpiration);  
   }  
   //Then create a dependency that tells to depend on the cacheitem with key "DependencyKey"  
   return new CacheDependency(  
     null,  
     new[] { DependencyKey }  
   );  
 }  


Och min Car-klass ser nu ut såhär:

 public class Car  
 {  
   private const string ClassCacheKey = "Car";  
   public string RegNumber { get; set; }  
   public string Color { get; set; }  
   public Car(string regnr, string color)  
   {  
     RegNumber = regnr;  
     Color = color;  
   }  
   public void UpdateCarColor(string newColor)  
   {  
     Color = newColor;  
     HttpRuntime.Cache.Remove(  
      Helper.GetCacheDependencyKey(  
       ClassCacheKey, RegNumber  
       )  
     );  
   }  
   // EXAMPLE METHOD 1 without cachedependency!  
   public string GetCarStamp()  
   {  
     string cacheKey = Helper.GetCacheKey(  
             ClassCacheKey,  
             "GetCarStamp",  
             RegNumber);  
     string data = (string)HttpRuntime.Cache.Get(cacheKey);  
     if (!string.IsNullOrEmpty(data))  
     {  
       return data;  
     }  
     //Call for the performance demanding method...  
     data = GetCarStampFromDatabase();  
     HttpRuntime.Cache.Insert(  
         cacheKey,  
         data,  
         Helper.GetCacheDependency(ClassCacheKey, RegNumber),  
         Cache.NoAbsoluteExpiration,  
         Cache.NoSlidingExpiration);  
     return data;  
   }  
   //Simulate a performance demanding method that we want to  
   //avoid calling as much as possible  
   private string GetCarStampFromDatabase()  
   {  
     return string.Format("{0}{1}", RegNumber, Color);  
   }  
 }  

Så cachen för GetCarStamp() släpper inte förrän färgen ändras via UpdateCarColor(), eller att applikationen startas om.
Vill man att den ändå ska släppa efter en viss tid så är det bara att byta ut Cache.NoAbsoluteExpiration till det värde man önskar.

Sveriges bästa systemutvecklare 2012

Inte mycket för att tävla i kompetens och prestation inom yrkeslivet, men denna lista från IDG.se ger ändå en intressant bild av vad andra utvecklare arbetar med.
Jag har själv haft förmånen att få arbeta med Joel Abrahamsson (plats 8, plats 5 år 2011) som är en mycket trevlig och kompetent utvecklare inom .NET och EPiServer.


Se hela listan här.

måndag 5 november 2012

Cache in .NET MVC

Att sätta cache på en sida eller en del av en sida i MVC görs på samma sätt som i WebForms - via attribut i koden på controllerklassen:


 public class HomeController : Controller  
 {  
   //Cache page for "Duration" amount of seconds  
   [OutputCache(Duration = 5, VaryByParam = "none")]  
   public ActionResult Index()  
   {  
    // Write your code here  
    return View();  
   }  
 }  


Om man vill ange flera parameternamn i VaryByParam ska de åtskiljas av semikolon.

DropDownList in MVC

Ett litet exempel på hur man implementerar en DropDownList i .NET MVC med Razor syntax så det ser ut enligt nedan. Jag visar också hur man loopar igenom objekten i en foreach-loop:


I controller-metoden har jag en lista av klasstypen "Room".

 public ActionResult Index(){  
  List<Room> myRoomList = new List<Room>() {  
  new Room() { Roomname = "Horror room", Height = 5 },  
  new Room() { Roomname = "Death room", Height = 6 }  
  };  
  SelectList myList = new SelectList(myRoomList, "Height", "Roomname");  
  ViewBag.DropdownRoomList = myList;  
  return View(myRoomList);  
 }  


Filen för vyn ser ut enligt följande:

 @model IList<DropDownListTestProject.Models.Room>  
 @{  
   ViewBag.Title = "DropDownList test";  
 }  
 @foreach (var amodel in Model)  
 {  
   @: Height of @amodel.Roomname is @amodel.Height metres  
   <br />  
 }  
 <br />  
 @Html.DropDownList("RoomHeight", (SelectList)ViewBag.DropdownRoomList)  

lördag 3 november 2012

Chicken Tikka Masala

4 personer


  • 500 gram kycklingfiléer (bröst el lår)
  • 1 st gul lök
  • 1 st vitlöksklyfta
  • 1 msk färsk ingefära, finhackad
  • 1 st påse tikka masala-krydda (40 g)
  • 1,5 dl sötmandel
  • 400 gram krossade tomater
  • 1 dl vispgrädde
  • 1 dl matyoghurt (10 %)
  1. Skär kycklingfiléerna (om det är bröst) i bitar, ca 4 cm. Strimla lök och vitlök. Bryn i smör- & rapsolja i stekpanna eller kastrull. Salta och peppra.
  2. Blanda i ingefära, tikka masala-krydda, sötmandel och krossade tomater. Låt koka under lock ca 10 minuter.
  3. Ta ur kycklingbitarna och lägg på ett fat. Mixa såsen med stavmixer eller i matberedare tills den blir nästan slät. Lägg i kycklingen igen och tillsätt grädde och yoghurt. Låt koka ytterliggare 2 minuter, men akta så det inte bränner i botten!
  4. Servera med basmatiris, en sallad och nygräddade naan-bröd!