November 2009 - Posts

De som har testat JavaScript-stödet i Visual Studio 2010 kan inte ha undgått alla förbättringar. Det är snabbt, korrekt och en stor förbättring.

Något väldigt trevligt är även att jQuery följer med som standard när man skapar webbprojekt. Det har det gjort sedan ASP.NET MVC-pluginet för Visual Studio 2008 SP 1, men nu kommer det som standard.

Något som man dock kan sakna är snippets för det, vilket skulle underlätta mycket och spara tid. Nu har dock ett nytt projekt skapats på CodePlex, där John Sheehan har lagt upp hela 131 snippets för jQuery!

För er som använder jQuery och Visual Studio 2010 så är det här ett måste! :-)

Projektet kan hittas här:
http://jquerysnippets.codeplex.com/

Och en lista på alla snippets:
http://jquerysnippets.codeplex.com/documentation

För en video som visar hur smidigt det är, kika här:
http://www.screencast.com/users/JohnSheehan/folders/Jing/media/e0787da7-5e1c-4eef-bbb9-648426204be5

Har du tips på andra snippets eller intressanta projekt så lämna gärna en kommentar!

Något vi har kunnat göra länge är att rendera partiella vyer med ASP.NET MVC är att använda Html.RenderPartial(). Det gör det möjligt att ange namnet på en vy, samt skicka in en eventuell modell som skall användas för den partiella vyn.

I ASP.NET MVC så får vi två nya metoder som går ett steg längre och ger oss mer kontroll över vad som sker innan den partiella vyn renderas. De två metoderna som har tillkommit är Html.Action() och Html.RenderAction().

Det som sker när vi använder dessa metoder är att vi istället för att anropa en user control direkt, går igenom en Action-metod.

För att testa funktionaliteten så behöver vi först en modell kallad Customer.

namespace Mvc2Beta.Models
{
    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

Sedan så behöver vi en partiell vy som visar ett eventuellt inskickat namn. Den skall vara hårt typad mot Customer-klassen.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc2Beta.Models.Customer>" %>
Hej, <%= Model.Name %>!

Nu har vi det som krävs för att vi ska kunna anropa den partiella vyn. Nästa steg blir att implementera de olika metoder som kan användas för att anropa den.

De tre sätt som vi ska hämta in vyn på är genom Html.RenderPartial(), Html.Action() och Html.RenderAction().

Vi börjar med att lägga in det som behövs i vyn där de skall visas:

<ul>
    <li>
        RenderPartial: <% Html.RenderPartial("Name", new Mvc2Beta.Models.Customer() {Id = 1, Name = "Mikael"}); %>
    </li>
    <li>
        RenderAction: <% Html.RenderAction("Name", new Mvc2Beta.Models.Customer() { Id = 1, Name = "Mikael" }); %>
    </li>
    <li>
        Action: <%= Html.Action("Name", new Mvc2Beta.Models.Customer() { Id = 1, Name = "Mikael" }) %>
    </li>
</ul>

Vi kan se att RenderAction fungerar på samma sätt som RenderPartial i vyn. Action returnerar däremot en sträng som vi antingen kan skriva ut direkt, eller som vi kan använda på annat sätt.

Då Action och RenderAction inte går direkt mot den partiella vyn, utan mot en Action-metod så kommer vi att få ett fel om vi kör koden nu. Det vi behöver göra är att skapa en metod vid namn ”Name” och som tar emot ett Customer-objekt som vi vill vidarebefordra till vår partiella vy.

Vi lägger det här i controller-klassen:

public ActionResult Name(Customer customer)
{
    return PartialView(customer);
}

Vi behöver inte ta emot ett Customer-objekt som parameter i metoden, men jag gör det nu för att det ska bli enklare att jämföra de olika varianterna. Däremot så måste vi returnera en PartialView med ett Customer-objekt.

Om vi nu kör sidan så kan vi se att alla tre metoder returnerar samma vy med samma information. Skillnaden ligger i hur vi anropar den.

Det finns nu alltså tre olika metoder för tre olika scenarion.

Vill du snabbt och enkelt rendera en partiell vy med eller utan en modell?

- Använd Html.RenderPartial().

Vill du rendera en partiell vy, men kunna påverka flödet i en Action-metod?

- Använd Html.RenderAction().

Vill du ta emot en partiell vy i en sträng efter att ha haft möjligheten att påverka flödet i en Action-metod?

- Använd Html.Action().

Det finns ingen metod för alla scenarion, utan det gäller att välja den som passar bäst för det enskilda scenariot.

I ASP.NET MVC 2 Beta så kommer det funktionalitet i Visual Studio för att kunna skapa areor enklare. Tidigare så har det krävt en del jobb och manuellt pill i konfig-filer, men nu finns allt inbyggt.

När vi skapar ett nytt ASP.NET MVC 2 Beta-projekt och högerklickar på projektet i Solution Explorer så ser vi det här:

1 - New

När vi klickar på ”Area…” så får vi upp en ruta där vi får skriva in ett namn på arean. Jag skriver in ”NewArea” och klickar på ok.

Det som sker nu är att det skapas en ny area med det namnet vi angav, med allt som behövs för att vi skall kunna använda den.

Kikar vi i global.asax så kan vi se att arean registreras:

AreaRegistration.RegisterAllAreas();

Ser vi i den nyskapade Areas-mappen så kan vi se att vi har en AreaRegistration-klass, vilken vi använder för alla routes som ska finnas för arean.

I Solution Explorer har vi det här:

clip_image004

Utan att skriva en rad kod så har vi fått en area i projektet.

Det går tyvärr inte att skapa nya projekt för areor på det här sättet, utan det går bara att lägga till nya areor i det befintliga projektet.

Microsoft släppte ikväll ASP.NET MVC 2 Beta. Det går inte att använda det tillsammans med Visual Studio 2010 Beta 2, utan det måste användas med Visual Studio 2008.

Ladda ned det här:

http://www.microsoft.com/downloads/details.aspx?FamilyID=4817cdb2-88ea-4af4-a455-f06b4c90fd2c&displaylang=en

I .NET 4.0 så ingår webbkontroller för att skapa diagram (så kallade ”charts”) med bland annat ASP.NET. Då det är vanliga webbkontroller så innebär det att de är anpassade för web forms, men de går faktiskt utmärkt att använda för ASP.NET MVC.

Innan vi lägger till diagrammen så börjar vi med att skapa ett ASP.NET MVC-projekt med en ny modell kallad Article. Den har två properties, Name och Category.

Utseendet på den klassen ser ut så här:

namespace MvcChart.Models
{
    public class Article
    {
        public string Name { get; set; }
        public string Category { get; set; }
    }
}

Vi skapar även en ny ActionResult-metod i HomeController som fyller denna med dummy-data, samt skapar en vy för denna som listar upp datan.

public ActionResult Articles()
{
    List<Article> articles = new List<Article>()
    {
        new Article() { Name = "Artikel 1", Category = "Äpplen" },
        new Article() { Name = "Artikel 2", Category = "Äpplen" },
        new Article() { Name = "Artikel 3", Category = "Äpplen" },
        new Article() { Name = "Artikel 4", Category = "Päron" },
        new Article() { Name = "Artikel 5", Category = "Päron" },
        new Article() { Name = "Artikel 6", Category = "Bananer" }
    };
 
    return View(articles);
}

Om vi kikar på /Home/Articles så får vi nu upp en tabell med namnen på artiklarna samt vilken kategori de tillhör. Vi kan dock ej på ett enkelt sätt se hur många artiklar det finns i varje kategori, så där kan vi ha ett diagram som gör det åt oss.

Diagrammet kommer att finnas under en ny controller kallad ChartController. Här har vi en metod kallad Articles(). I denna controllern skapar vi ett diagram som returneras direkt till vyn som en png-bild.

Chart-funktionaliteten som vi vill åt ligger under System.Web.UI.DataVisualization.Charting, vilket i sin tur ligger i System.Web.DataVisualization.dll. Vi måste skapa en referens till den dll:en i Visual Studio då den inte ingår som standard i projekten. Den finns dock med bland listan med assemblies i GAC:n.

Den fullständiga koden för att returnera diagrammet med samma dummy-data som vi hade i den andra controllern ser ut så här:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI.DataVisualization.Charting;
using MvcChart.Models;
 
namespace MvcChart.Controllers
{
    public class ChartController : Controller
    {
        public ActionResult Articles()
        {
            //Skapa några artiklar
            List<Article> articles = new List<Article>()
            {
                new Article() { Name = "Artikel 1", Category = "Äpplen" },
                new Article() { Name = "Artikel 2", Category = "Äpplen" },
                new Article() { Name = "Artikel 3", Category = "Äpplen" },
                new Article() { Name = "Artikel 4", Category = "Päron" },
                new Article() { Name = "Artikel 5", Category = "Päron" },
                new Article() { Name = "Artikel 6", Category = "Bananer" }
            };
 
            //Skapa en chart
            Chart chart = new Chart()
            {
                Height = 300,
                Width = 300,
                ImageType = ChartImageType.Png
            };
 
            //Visa som 3D
            ChartArea chartArea = chart.ChartAreas.Add("Categories");
            chartArea.Area3DStyle.Enable3D = true;
 
            //Skapa en serie med grupperna
            Series categories = chart.Series.Add("Categories");
            categories.ChartType = SeriesChartType.Doughnut;
 
            //Gruppera per CategoryId
            IEnumerable<IGrouping<string, Article>> catgroup = articles.GroupBy(a => a.Category);
 
            //Lägg till en ny DataPoint för varje kategori
            foreach (IGrouping<string, Article> item in catgroup)
            {
                categories.Points.Add(new DataPoint()
                {
                    Label = String.Format("{0} ({1})", item.Key, item.Count()),
                    YValues = new Double[] { item.Count() }
                });
            }
 
            //Spara ned bilden i en memorystream
            MemoryStream ms = new MemoryStream();
            chart.SaveImage(ms);
 
            //Returnera bilden direkt till vyn
            return File(ms.GetBuffer(), "image/png");
        }
    }
}

Det första som händer här är att dummydatan skapas upp och läggs i en lista. Sedan skapar vi en instans av Chart, vilket är klassen som används för de olika typerna av diagram. Vi anger även storlek på denna och säger att det ska bli en png-bild.

Nästa steg blir att skapa en ChartArea så att vi kan sätta inställningar för diagrammet. Det enda vi gör här är att sätta det som 3D för att det skall bli snyggare. Det finns även många andra inställningar man kan göra.

Efter det så skapar vi en serie. En serie är en samling data som skall visas upp på ett diagram. Man kan ha flera serier på samma diagram, vilka då visas på samma bild. Just den här serien skall vara av typen ”Doughnut”.

Sedan så grupperar vi alla artiklar efter kategori och lägger till en DataPoint för var och ett. En DataPoint är ett enskilt värde i diagrammet. Vi sätter även en Label på dessa för att kunna se vilken kategori det gäller, samt hur många artiklar det finns för den.

Det sista som händer är att vi sparar ned diagrammet i en memorystream som sedan returneras direkt till sidan som en png-bild.

Om vi surfar direkt till /Chart/Articles nu så får vi upp den här bilden:

Articles-1

Vi kan enkelt se att t.ex. hälften av alla artiklar (tre stycken) ligger i kategorin ”Äpplen”.

De går även att använda andra typer av diagram, så genom att byta ut Doughnut mot Pyramid så kan vi få det här:

Articles-2

Och väljer vi Bar så får vi det här:

Articles-3

Det finns väldigt många olika typer av diagram samt många olika sätt att påverka utseendet på, så för en bra genomgång av detta så rekommenderar jag en titt på exempelsidan som man kan ladda ned här:

http://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=1591

Samt dokumentationen som finns här:

http://www.microsoft.com/downloads/details.aspx?FamilyId=EE8F6F35-B087-4324-9DBA-6DD5E844FD9F&displaylang=en

Då grafen är en vanlig vy så fungerar routing för den precis som för allt annat. Vi kan gå tillbaka till Articles-vyn som vi skapade för HomeControllern och lägga till det här:

<img src="<%=Url.Action("Articles", "Chart") %>" alt="Diagram över artiklar" />

Om vi nu går in på /Home/Articles så ser sidan ut så här:

Articles-4

För att bygga vidare på den här funktionaliteten så skulle man t.ex. kunna göra det möjligt att skicka in variabler till sina ActionResult-metoder i ChartController och därmed göra diagrammen ännu mer dynamiska.

More Posts