Bygg ett forum – Del 3- Grundläggande databaskunskap

by Reager 25. September 2009 17:51

I denna del av serien tänkte jag gå igenom vad man i databassammanhang kallar för CRUD, Create, Read, Update & Delete. Vi ska även gå igenom grundläggande databasmodellering samt skapa några tabeller. Observera att det vi skapar här inte kommer att användas i själva forumet utan är bara en liten crash course så att du ska veta vad vi håller på med senare när vi bygger på forumet.

Jag kommer att utgå från att du har en databas att arbeta med. Börja med att koppla upp dig mot denna i MySQL Query Browser. Sedan ska vi börja med att skapa några tabeller som vi kan använda när vi ska lära oss de olika kommandona. Det är väldigt vanligt att man i exempel använder tabeller vid namn Employee & Department vilket jag tänkte att vi även skulle göra här. Det första man bör göra innan man skapar sina tabeller är att modellera upp hur dessa är tänkta att se ut samt eventuella relationer emellan dem. Vid modellering börjar man man att se vilka olika objekt som man ska representera och vilka egenskaper dessa har. Till exempel så har Employee-tabellen, som ska motsvara en anställd egenskaperna anställningsnummer, förnamn, efternamn, avdelning, anställningsdatum m.m.. Vår Department-tabell kan ha egenskaper som avdelningsid, avdelningsnamn. Redan nu ser vi att det finns en relation mellan dessa två tabeller. Båda innehåller nämligen avdelningsid. Det som identifierar varje rad i en tabell kallar Primary Key, PK eller på svenska primärnyckel. Det som i en tabell hänvisar till PK i en annan tabell kallas Foreign Key, FK eller på svenska främmande nyckel. PK används som jag sa tidigare för att identifiera varje rad i en tabell, vilket innebär att den automatiskt blir unik, och du kan inte lägga till två rader med samma PK. En FK däremot kan det finnas hur många rader som helst av, men varje FK pekar alltid på en rad i sin “föräldratabell”. Detta förhindrar oss från att t.ex. lägga till en anställd med en avdelning som inte existerar.

På varje kolumn i en tabell ska man även sätta en datatyp. En datatyp talar om vilken sorts data det är vi lagrar i just denna kolumn. T.ex. så talar vi om om vi lagrar det som tal, text, datum m.m. Att sätta rätt datatyp är viktigt då det underlättar vid utsökningar samt förbättrar prestandan.

Du bör heller aldrig lagra mer än en information i varje kolumn, t.ex. så ska förnamn och efternamn aldrig lagras tillsammans, likaså adresser ska delas upp. Gatunamn och gatunummer kan vara OK att lagra tillsammans om din lösning inte kräver att du måste särskilja även på dessa.

Jag hoppas det är möjligt att förstå detta och vi ska nu göra själva modellen av våra tabeller.

Employee Datatyp Övrigt
EmpID INT PK
Firstname VARCHAR(45) NOT NULL
Lastname VARCHAR(45) NOT NULL
HireDate DATETIME NOT NULL
DeptID INT FK (Department, DeptID)

 

Department Datatyp Övrigt
DeptID INT PK
DeptName VARCHAR(45) NOT NULL

 

Då har vi två tabeller i textform och ska nu skapa dessa i databasen. Öppna MySQL Query Browser. Högerklicka på din databas och välj “Create new table”. Tabelleditorn öppnas då och vi kan skapa våra tabeller. Då tabellen Employee innehåller en referens till tabellen Department så skapar vi tabellen Department först så vi kan skapa relationen direkt när vi sedan skapar tabellen Employee. Börja med att fyll i uppgifterna för tabellen Department.

image

Det vi har gjort här är att vi lagt till två kolumner, sett till Att DeptID är PK genom att verifiera att det är en nyckel bredvid kolumnnamnet och satt de rätta datatyper. VARCHAR(45) innebär att det är en sträng som max kan innehålla 45 tecken men tar inte upp mer plats än nödvändigt. Egenskapen NOT NULL talar om att det måste finnas ett värde i kolumnen, vi kan alltså inte spara tomma värden och AUTO INC betyder att det är en automatisk räknare. Vi behöver alltså inte manuellt ange vår key, utan denna kommer att börja på 1 och räknas upp med 1 för varje rad.

Spara din nya genom att klicka på “Apply Changes”. Du får du upp en ruta som ser ut som den nedan. Klicka bara på “Execute” och du har skapat en tabell.

Grattis, om inget har gått fel så ska du nu har en tabell vid namn Department. Vi ska nu se till att skapa även tabellen Employee. Högerklicka än en gång på din databas och välj “Create new table”. Namnge denna till “Employee” och fyll sedan i resten av datan enligt bilden nedan.

image

Klicka på fliken “Foreign Keys”.

image

och sedan på +-tecknet. Låt namnet vara som det är och klicka på “OK”

image

I “Ref table” väljer du tabellen “Department”

image

och du kommer att se att den automatiskt visar rätt kolumner. Skulle dessa av någon anledning vara fel så kan du ändra genom att klicka på kolumnnamnet och välja den rätta kolumnen. Klicka på “Apply Changes” och sedan “Execute” och vi har två tabeller med en FK satt emellan denna. I de kommanda avsnitten nedan ska vi gå igenom hur du gör för att lägga till, läsa, uppdatera samt ta bort information från tabellerna.

Create

För att lägga till information i en tabell använder du kommandot INSERT. För att lägga till en rad i kolumnen Department kan vi skicka in följande “query” till databasen.

INSERT INTO Department(DeptName) VALUES('Försäljning')

Kommandot är uppbygget i delarna “INSERT INTO” sedan följer tabellnamnet och inom parenteserna anges en kommaseparerad lista med de kolumner som du vill stoppa in data i. Låter du bli att ange några så måste du ange värden för alla kolumner i tabellen. Efter det kommer “VALUES” och inom parenteser anges de värden som skall matas in på tabellraden. Även dessa skall anges med ett komma (,) mellan varje om det är fler och olika datatyper ska vara omslutna av olika tecken. T.ex. så skall strängar och datum vara omslutna av enkelfnuttar (‘) och tal ska inte vara omslutet av något alls.

Om du i MySQL Query Browser dubbelklickar två gånger på tabellen Department så kommer innehållet att visas.

image 

Som du kan se så infogades “Försäljning” och min PK fick värdet 1 då det är ett tal och en räknare. Hade du själv velat ange ett värde för DeptID så hade SQL-frågan sett ut så här

INSERT INTO Department VALUES(5, 'PR')

Om du återigen dubbelklickar på tabellen Department så kommer du att se att en ny rad har infogats och att DeptID denna gång har värdet 5.

image

Som en liten övning kan du nu skapa 5st personer i tabellen Employee. Skulle du inte lyckas få till det så ser koden ut så här.

INSERT INTO Employee VALUES(null, 'Kalle', 'Anka', '2009-09-21', 1)
Upprepa denna sats men med olika namn och datum samt ändra DeptID på någon av dem så att du totalt har 5st personer i Employee-tabellen.  Anledningen till att jag använder null som första värde är att jag inte angett något kolumnlista utan vill ange ett värde för varje kolumn och null gör så att den använder räknaren för EmpID. Ett alternativt sätt hade varit
INSERT INTO Employee(Firstname, Lastname, HireDate, DeptID) 
VALUES('Kalle', 'Anka', '2009-09-21', 1)

Read

För att läsa från en tabell används kommandot SELECT. Det absolut enklaste sättet användningen är

SELECT * FROM TabellNamn

vilket ger oss alla rader och alla kolumner i tabellen TabellNamn. Så säg att vi skulle vilja hämta ut alla rader ur tabellen Employee. Detta gör vi genom kommandot

SELECT * FROM Employee

Detta ger oss resultatet

image

Säg att vi bara skulle vilja visa de tre första resultaten från SQL-satsen. Då skulle vi kunna använda nyckelordet LIMIT. LIMIT fungerar som så att anger du bara ett tal så visar den det antalet, men det går också att ange ett startvärde samt ett antal. För att visa de tre första så ser SQL-frågan ut så här

SELECT * FROM employee e LIMIT 3

Detta ger oss resultatet

image

Om vi istället skulle vilja hämta ut 3 rader, men börja på rad på skulle SQL-satsen se ut så här

SELECT * FROM employee e LIMIT 1,3

Resultatet av denna blir istället

image

Om vi vill sortera resultatet och bara hämta ut dem med efternamnet “Anka” så får vi lägga till nyckelordet WHERE. Vår sats skulle då se ut så här:

SELECT * FROM Employee WHERE Lastname='Anka'

och resultatet skulle bli

image

Skulle vi sedan även vilja ordna resultatet så att det sorteras på en viss kolumn så använder vi nyckelordet ORDER BY. Säg att vi vill sortera på förnamn i stigande ordning (a b c d osv). Då blir vår nya sats så här

SELECT * FROM Employee WHERE Lastname='Anka' ORDER BY Firstname ASC

Det sista, ASC är det som talar om att vi vill sortera förnamnet i stigande ordning. Detta är standard, så vi hade kunnat utelämna denna men för tydligenhetens skull så är det bra att alltid ange detta. Motsatsen till stigande ordning är fallande (ö ä å z y osv). Detta uppnår man genom att ange DESC istället för ASC. Så om vi vill hämta ut alla poster, men sortera på HireDate i fallande ordning skulle sql-frågan se ut så här

SELECT * FROM Employee ORDER BY HireDate DESC

och resultatet blir

image

I nästa exempel för utsökningar av data kommer jag att visa hur man tar fram data som ligger i ett intervall. Detta gör man genom att använda nyckelordet BETWEEN. Säg att vi vill hämta ut alla som blev anställda mellan 2004-2008. Då använder vi BETWEEN på följande sätt

SELECT * FROM Employee WHERE HireDate BETWEEN '2004-01-01' AND '2008-12-31'

och resultatet blir

image

Det sista exemplet kommer att visa hur du slår ihop data från flera olika tabeller, vilket i databassammanhang kallas att göra en JOIN. Det vi ska göra i exemplet är att ta fram förnamn, efternamn samt vilket avdelning personen arbetar för.

SELECT e.Firstname, e.Lastname, d.DeptName FROM Employee e, Department d 
WHERE e.DeptID = d.DeptID

Resultatet av ovanstående SQL-fråga blir

image

Som du ser så skiljer sig inte denna fråga så jättemycket från tidigare exempel, förutom att vi har data från flera tabeller som vi länkar ihop tack varje relationen som finns mellan dessa två tabeller. Som du ser har jag skrivit “e.Firstname” och det innebär att e är ett alias för Employee som jag definierar i FROM-satsen genom att skriva “Employee e”. Samma sak gör jag för Department. I WHERE-satsen länkar vi sedan ihop de båda tabellerna så att vi får en rad för varje användare.

Update

Att köra en Update mot databasen innebär att du uppdaterar ett eller flera värden i tabellen. En Update-sats ser i sin grundform ut på detta vis

UPDATE TabellNamn SET KolumnNamn=Värde

Ovanstående sats skulle uppdatera samtliga rader i tabellen vilket man så klart mycket sällan vill. För att specificera vilka rader som ska uppdateras kan du precis som här använda WHERE-villkoret. Säg att vi istället för “Kalle” vill ha dennes fulla namn, Karl Magnus, så skulle denna SQL-sats se ut på följande vis

UPDATE Employee SET Firstname='Karl Magnus' WHERE EmpID=1

Om vi nu kör en SELECT mot tabellen Employee kommer vi att se att värdet Firstname har ändrats från “Kalle” till “Karl Magnus”.

image

Delete

För att ta bort rader från tabeller så använder man kommandot DELETE. DELETE skrivs i sin grundform på följande vis

DELETE FROM TabellNamn

Detta skulle ta bort samtliga rader från tabellen “TabellNamn” men du kan precis som vid SELECT och UPDATE ange ett WHERE-villkor för att styra vilka rader som skall tas bort. Om vi från vårat exempel vill ta bort “Musse” så skulle denna sats se ut så här

DELETE FROM Employee WHERE EmpID=5

Resultatet av detta om vi kör ovanstående fråga är att raden med “Musse” försvinner ur tabellen.

image

 

Det var vad jag hade tänkt gå igenom när det gällde lite grundläggande databaskunskap. Det finns givetvis tonvis med fler saker att lära sig, men dessa är de som jag känner är de viktigaste.

Ses vid nästa artikel som kommer att handla om modellering av den riktiga databasen för forumet.

Tags: , , , , , , ,

MySQL | Databaser | Artikel

Bygg ett forum – Del 2 – Förbered arbetsmiljön

by Reager 25. September 2009 17:51

I del 2 av denna serie ska vi se till att vi är redo att börja koda. Börja med att öppna Visual Web Developer och klicka på File –> New Project. Du får då upp en ruta som ser ut som denna

image

Välj ASP.NET Web Application under Visual C# / Web. Under Name fyller du i vad du vill att detta projekt skall heta. Jag väljer att kalla det “SimpeForum” då det är vad det är. Välj var du vill placera projektet och klicka sedan på “OK”.

Din “Solution Explorer” bör då se ut i stil med

image

Nu har vi ett tomt projekt och om vi vill provköra detta projekt så kan vi klicka på F5. När vi gör detta kommer vi att få följande fråga

image

Klicka bara på “OK”. Det vi säger här är att vi vill aktivera debugging vilket kan vara trevligt att ha senare i projektet om vi behöver göra någon felsökning. Detta är dock något som vi ska inaktivera innan sidan går live senare.

Nästa sak vi ska göra är att försäkra oss om att vi har en fungerande databas så vi kan skapa de tabeller vi behöver senare. Starta “MySQL Query Browser” och fyll i dina uppgifter till databasen i rutan som kommer upp.

image

“Default Schema” är den databas som du vill att ska vara standard när du loggar in på databasen. Om du redan har en databas som du vet namnet på så kan du fylla i namnet på denna här, annars kan du låta rutan vara tom och klicka på “Ignore” på varningen som kommer upp. När du loggar in och allt går som det ska kommer du att kunna se alla databaser som ditt konto har tillgång till. I mitt fall ser det ut så här

image

vilket innebär att jag ännu inte har någon “riktig” databas.

Nu när vi har försäkrat oss om att allt fungerar så är nästa steg att gå igenom lite grundläggande databaskunskap.

Tags:

Allmänt | Artikel

Bygg ett forum - Del 1 - Introduktion

by Reager 25. September 2009 17:50

Jag hade i en serie poster här på bloggen gå igenom steg för steg hur det går till att skapa ett forum. Detta för att jag tycker det är roligt att förmedla kunskap, men även för att ge alla de som inte tagit steget över till .NET än att göra detta med en artikel som ligger på en väldigt lättfattlig nivå.

Du kommer under denna serie att få lära dig allt du behöver för att kunna fortsätta med .NET på egen hand och fördjupa dig i ämnet. Jag kommer att gå igenom en massa som du kan ha nytta av när du ska lära dig .NET.

Verktygen som jag kommer att använda är Visual Web Developer Express och ASP.NET 3.5 SP1. Du behöver även tillgång till en MySQL-databas. Serverspråket som kommer att användas är C#.

Genom att använda Mircosoft Web Platform kan du ladda ner VWD Express samt senaste versionen av .NET-ramverket så att du är säker på att du har detta. Du hittar det på länken nedan. http://www.microsoft.com/web/Downloads/platform.aspx

Har du ett webbhotell bör du även ha tillgång till en MySQL-databas redan, annars kan du ladda hem denna och köra lokalt på din egen dator om du hellre vill det. Du hittar MySQL-servern på länken nedan.
http://dev.mysql.com/downloads/mysql/5.1.html#downloads

Du ska även se till att installera MySQL GUI Tools. Dessa finner du om du följer länken nedan.
http://dev.mysql.com/downloads/gui-tools/5.0.html

När du har detta installerat är du redo att börja din resa i den underbara världen som .NET ger dig :)

Om du har några synpunkter eller frågor om någon artikel i serien är du välkommen att posta en kommentar under relevant artikel.

Tags:

Allmänt

Komma åt Session i Handler

by Reager 15. August 2009 10:45

Har du någonsin använt en Web Handler och försökt komma åt sessionsvariabeln där utan att lyckas? Då beror det på att du inte har implementerat interfacet IRequiresSessionState. Detta interface finns i “namespacet” System.Web.SessionState så du behöver även inkludera detta. Nedan ser du en komplett Handler med kod som visar hur det ser ut.

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Web.SessionState;
public class Handler : IHttpHandler, IRequiresSessionState {
    
    public void ProcessRequest (HttpContext context) {

        context.Response.Write(context.Session["minsession"]);
        
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }
}

Denna handler skriver endast ut värdet i sessions-variabeln “minsession”.

Det var ett litet tips från min penna.

Tags:

ASP.NET MVC & Entity Framework med MySQL

by Reager 8. August 2009 01:11

För denna artikel behövs

Börja med att se till så att du har allt det ovanstående installerat och klart innan du går vidare. Installerar du allt på nytt är det även rekommenderat att du startar om datorn. Öppna sedan Visual Studio och skapa en ny ASP.NET MVC Web Application. Börja med att ta bort allt i mapparna Controllers och Views utom mappen Shared men töm även denna så att vi kan börja från scratch. Nästa steg är att skapa tabellen som vi ska använda. Jag valde att kalla min tabell för blogg_post. Denna tabell ska se ut på följande vis

Fältnamn Typ Övrigt
id INTEGER Primary Key
posttitle VARCHAR(100)  
postbody TEXT  
dateposted DATETIME  

Sedan skapar vi vår entitydatamodel-fil. Detta gör du genom att högerklicka på mappen Models –> add –> New Item.

image

Välj ADO.NET Entity Data Model

image

Knappa in ett passande namn och klicka sedan på Add. I nästa steg väljer du “Generate from Database” och klickar next.

I nästa fönster som kommer upp klickar du på “New Connection” och väljer “MySql Database” och klickar på “Continue”.

image

Fyll i dina uppgifter till MySQL-databasen och klicka på “OK”. Om Visual Studio frågar om du vill spara lösenordet i din connection-string så är det bara att välja “Yes” och klicka sedan på “Next”.

I nästa steg så expanderar du fliken “Tables” och klickar i din tabell som du skapade tidigare och klickar på “Finish”.

image

Din datamodell skapas då och “we are ready to roll”.

Högerklicka på mappen “Controllers”, välj sedan “Add” –> “Controller” och döp denna till “HomeController”. Klicka även i rutan “Add action methods for……” och klicka på “OK”.

image

I vår Index-action så kommer vi att hämta samtliga inlägg i vår tabell och visa dem. Börja med att importera din namnrymd som innehåller alla modeller. Vanligtvis heter denna projektnamn.Models. Importera även System.Data.Linq.

using MVC_EF_MySQL.Models;
using System.Data.Linq;

Sedan i vår Index-action skriver vi följande kod för  att hämta alla inlägg.

using(web37831_devEntities context = new web37831_devEntities())
{
    List<blogg_post> post = (from p in context.blogg_post
                             select p).ToList();

    return View(post);
}

Nästa steg är att skapa vår vy. Detta gör vi genom att högerklicka på vår Index-action och välja “Add View”.

 image

Låt vynamnet vara och välj att den ska vara starkt typad  (strongly-typed) mot i mitt fall klassen MVC_EF_MySQL.Models.blogg_post. I listan för “View Content” väljer du “List”. Klicka sedan på “Add”.

image

Nästa steg är att skapa sidan för att skapa ett inlägg. Om du kollar i “HomeController.cs” så kan du se att det finns 2st “Create”-actions. Den första levererar bara själva vyn och den andra anropas endast om det är en “Post” som sker mot servern. I denna andra “Create”-action ska vi nu skriva lite kod för att spara ett inlägg. Denna ser ut som följer.

using (web37831_devEntities context = new web37831_devEntities())
{
    blogg_post post = new blogg_post();
    post.posttitle = collection["PostTitle"];
    post.postbody = collection["PostBody"];
    post.dateposted =DateTime.Now;
    context.AddToblogg_post(post);
    context.SaveChanges();
}

return RedirectToAction("Index");

Upprepa nu stegen som du tog för att skapa Index-vyn men nu istället för “Create” och klicka på “Add”.

image

I denna fil så tar du bort de två fälten för ID och DatePosted då vi vill ange detta själva. Ändra även från Html.TextBox till Html.TextArea på PostBody. Detta gör att det renderas en textarea istället för en textbox. Du bör ha kvar något som ut i stil med detta innanför using(Html.BeginForm())

<fieldset>
    <legend>Fields</legend>

    <p>
        <label for="postbody">postbody:</label>
        <%= Html.TextArea("postbody") %>
        <%= Html.ValidationMessage("postbody", "*") %>
    </p>
    <p>
        <label for="posttitle">posttitle:</label>
        <%= Html.TextBox("posttitle") %>
        <%= Html.ValidationMessage("posttitle", "*") %>
    </p>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

Det var allt, du kan nu provköra projektet. Förstasidan listar dina inlägg och anger du sökvägen /home/create så kan du även skriva inlägg. Vill du att det ska se snyggare ut är det bara att redigera koden i dina vyer.

Så enkelt var det att komma igång med ASP.NET MVC och Entity Framwork med MySQL.

På återseende.

Tags:

ASP.NET MVC & Linq 2 SQL med MySQL

by Reager 7. August 2009 01:18

För att kunna hänga med i denna artikel krävs det att du har minst Visual Studio Web Developer Express och ASP.NET MVC installerat samt tillgång till en MySQL-databas. Du behöver också ha laddat hem DbLinq.

Då jag varit lite nyfiken på ASP.NET MVC och Linq 2 SQL men ville använda MySQL istället för MSSQL så Google jag lite på ämnet och hittade denna sida http://www.primaryobjects.com/CMS/Article100.aspx som visar hur man kan använda DbLinq för detta.

I blogg-posten kommer jag att skapa en väldigt simpel blogg/gästbok för att visa hur detta går till att använda.

Börja med att skapa en ASP.NET MVC Web Application, företrädesvis med C# som programmeringsspråk då det är vad jag kommer att använda.

Skapa sedan en MySQL-databas och i denna databas skapar du en tabell vid namn blogg_post. Denna tabell ska se ut på följande sätt

Fältnamn Typ Övrigt
id INTEGER Primary Key
posttitle VARCHAR(100)  
postbody TEXT  
dateposted DATETIME  

När detta är klart så laddar du hem DbLinq som du hittar här

Ladda hem den senaste versionen och packa upp filerna på lämpligt ställe. Öppna sedan kommandoprompten och navigera till bin-mappen i mappen som du packade upp filerna till. Det vi sedan ska göra är att generera en klass automatiskt baserad på vår tabell i databasen. Detta gör du genom att skriva

dbmetal /server:1.2.3.4 /user:dbuser /password:password /provider:MySql /database:databasename /language:C#

Givetvis måste du ändra till dina uppgifter för databasen. När verktyget har arbetat klart så ska du ha en klassfil i denna mapp som är döpt efter din databas. Importera denna fil i ditt projekt genom att i VS högerklicka på projektnamnet, välja Add –> Existing Item och leta reda på mappen där du hade verktyget (samma som du navigerade till i kommandoprompten).

Som vanligt krävs det lite extra krångel innan allt fungerar, men annars vore det väl inge kul :) Börja med att lägga till ett par referenser till MySQL-connectorn och DbLinq i ditt projekt. Detta gör du genom att högerklicka på projektet i VS och välja “Add reference”. Välj sedan fliken “Browse” och leta reda på build-mappen där du packade upp DbLinq. Lägg sedan till filerna DbLinq, DbLinq.MySql samt MySql.Data. Under fliken .NET skall du även lägga till referenser till System.Data.Linq.

Öppna sedan din skapade klass och ta bort samtliga using som förekommer efter using System.Text; och ersätt istället med följande

using DbLinq.Data.Linq;
using DbLinq.Data.Linq.Mapping;
using System.Configuration;
using MySql.Data.MySqlClient;

Sedan ändrar du så att klassen ärver från MySQLDataContext istället för DbLinq.Data.Linq.DataContext så din klass-deklaration ser ut så här

public partial class BlogDataContext : DbLinq.MySql.MySqlDataContext

Ditt klassnamn kommer att se annorlunda ut, vill du att detta ska heta nåt annat kan du givetvis ändra. Ta sedan bort de två konstruktorna som har skapats och ersätt med denna

public BlogDataContext()
  : base(
      new MySqlConnection(ConfigurationManager.ConnectionStrings["blogg"].ConnectionString)
      ) {}

Som du ser talar vi om att vi vill använda en Connectionstring vid namn blogg, vilket även innebär att vi måste lägga till denna i web.config. Öppna därför web.config och leta reda på taggen connectionstrings. I denna lägger vi sedan till vår egna

<add name="blogg" 
connectionString="Server=1.2.3.4;User=dbuser;Password=password;database=databasename"/>

Fyll som alltid i dina egna värden.

Nu när vi gjort allt detta ska vi se till så att vi kan läsa från och skriva till vår blogg också.  Eftersom VS skapade en massa filer åt oss när vi skapade projektet rensar vi nu upp lite. Ta bort allt i mappen Controllers, Views utom mappen Shared men töm även denna så att vi kan börja från scratch. Skapa sedan en ny controller genom att högerklicka på Controllersmappen –> Add –> Controller. Välj sedan att controllern ska heta DefaultController. Klicka även i checkboxen och tryck sedan på Add. Öppna sedan din nyskapade kontroller och i metoden som heter Index så skriver du in följande kod

// Detta bryter garanterat mot god MVC-sed men vi fångar upp datan här
// och skickar den till vår vy. Observera att BlogDataContext är namnet på min klass
// som DbLinq skapade åt mig.
using (BlogDataContext context = new BlogDataContext()) { // Hämta ut alla poster och sortera på DatePosted var posts = from p in context.BLogGPost orderby p.DatePosted descending select p; // Returnera vyn och skicka med posterna return View(posts); }

Högerklicka sedan på Index och välj Add View. Låt “View name” vara men klicka i “Create a strongly-typed view och välj din klass som heter något liknande som din tabell i databasen gjorde. Hittar du den inte så kan du pröva att köra en “Build” på projektet. Under “View content” ska du välja “List” då vi vill lista alla inlägg på förstasidan. Nu är det bara en sak kvar som vi behöver göra innan vi kan köra projektet för första gången, och det är att ändra i global.asax så standard-routen har controller=”Default” istället för controller=”Home”.

Detta var väl kanske inte allt för spännande tycker du att se en nästan blank sida, men det beror på att vi ännu inte har några inlägg i vår blogg. Gå tillbaka till din default-controller. Som du ser så finns det två stycken create-metoder. Den första returnerar bara vyn, och den understa som har attributet
[AcceptVerbs(HttpVerbs.Post)] anropas när det är en Post som sker. Gå in i denna Create-metod och skriv in följande kod.

using (BlogDataContext context = new BlogDataContext())
{
    // Skapa ett BlogGPost-objekt
    BLogGPost post = new BLogGPost();
    // Sedan fyller vi det med data från vår FormCollection
    post.PostTitle = collection["PostTitle"];
    post.PostBody = collection["PostBody"];
    post.DatePosted = DateTime.Now;
    // Lägg till det i databasen när det sker en submit
    context.BLogGPost.InsertOnSubmit(post);
    // Skicka ändringarna till databasen
    context.SubmitChanges();
    // Gå till vyn Index
    return RedirectToAction("Index");
}

Högerklicka sedan på Create och välj “Add View”. Även denna ska vara strongly-typed till samma typ som innan men under “View content” så väljer vi istället “Create”.

I vyn som sedan skapas så börjar vi med att ta bort DatePosted och ID. Ändra sedan så att PostBody istället anropar Html.TextArea så att det ser ut som nedan.

<p>
    <label for="PostBody">PostBody:</label>
    <%= Html.TextArea("PostBody") %>
    <%= Html.ValidationMessage("PostBody", "*") %>
</p>
<p>
    <label for="PostTitle">PostTitle:</label>
    <%= Html.TextBox("PostTitle") %>
    <%= Html.ValidationMessage("PostTitle", "*") %>
</p>
<p>
    <input type="submit" value="Create" />
</p>

Tryck sedan på F5 för att köra projektet och hejsan hoppsan så hade vi en blogg/gästbok som vi både kan skriva ut inläggen i och posta inlägg. För att posta inlägg går du till /default/create

Som en liten egen övning kan du snygga till det hela lite i Index.aspx och Create.aspx.

Hoppas du fått ut någonting av denna artikel.

Tags:

Objekt till JSON

by Reager 6. August 2009 14:43

Något som är väldigt praktiskt att använda ibland, speciellt då man bygger AJAX-applikationer är JSON.  JSON är text som representerar vanliga objekt. Läs mer här http://en.wikipedia.org/wiki/JSON

Ett vanligt förfarande vid utvecklandet av t.ex. AJAX-applikationer är att man via JavaScript anropar en webbsida som utför något och som sedan returnerar resultatet tillbaka till JavaScript-funktionen för att där behandlas, t.ex. kan man hämta gästboksinlägg, bloggposter eller vad man nu vill returnera.

När man utvecklar med .NET så finns det inbyggda klasser och funktioner i ramverket som gör att du istället för att skapa upp din JSON-sträng manuellt via t.ex. en loop gör detta automatiskt åt dig och hur detta går till tänkte jag visa nedan.

Börja med att skapa upp en ny webbplats i Visual Web Developer eller vilket verktyg du väljer att utveckla i. Sedan skapar vi en ny klass som vi kallar för Customer. För att kunna använda de inbyggda klasserna för att skapa vår JSON-sträng måste vi importera namnrymden System.Runtime.Serialization samt sätta attributet DataContract() på klassen och DataMember på alla egenskaper som klassen har. Vår klass kommer då att se ut i stil med

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;

[DataContract()]
public class Customer
{
    [DataMember]
    public string Firstname
    {
        get;
        set;
    }

    [DataMember]
    public string Lastname
    {
        get;
        set;
    }

    [DataMember]
    public int CustomerID
    {
        get;
        set;
    }

    public Customer(string firstname, string lastname, int custmerid)
    {
        this.Firstname = firstname;
        this.Lastname = lastname;
        this.CustomerID = custmerid;
    }
}

Personligen använder jag alltid web handlers/generic handlers när jag skapar sidor som skall anropas av JavaScript-funktioner då man slipper de event som triggas i en vanlig .aspx-sida samt annat som gör att det tar längre tid att anropa sidan.

Nästa steg är att skapa en handler. Döp denna till GetCustomers och gå till kodläget. Det vi ska göra är att importera namnrymden System.Runtime.Serialization.JSON samt skriva den kod som gör om en lista med Customer-objekt till motsvarigheten i JSON.

Jag har importerat dessa namnrymder

using System.Collections.Generic;
using System.Runtime.Serialization.Json;

samt lagt till denna kod i metoden ProcessRequest i min handler

// Vi ändrar ContentType till JSON
context.Response.ContentType = "text/JSON";

// Sedan skapar vi en lista med några Customer-objekt. För att kunna
// göra detta så importerar vi System.Collections.Generic.
List<Customer> cust = new List<Customer>();
cust.Add(new Customer("Kalle", "Anka", 1));
cust.Add(new Customer("Joakim", "von Anka", 2));
cust.Add(new Customer("Oppfinnar-Jocke", "Johansson", 3));

// Sedan skapar vi ett objekt av typen DataContractJsonSerializer
// och talar om vilken typ det är som ska bli serializerad
DataContractJsonSerializer ser = new DataContractJsonSerializer(cust.GetType());

// Sedan skriver vi ut vår lista i JSON-format till "Ut-strömmen"
ser.WriteObject(context.Response.OutputStream, cust);

Som du ser är det inte mycket kod som behövs för att på ett smidigt sätt omvandla vår lista med Customer-objekt till JSON-format. Om du vill testa och se att det fungerar kan du prova handlern genom att högerklicka på den i “Solution Explorer” och välja “View in Browser”.

Har du följt denna artikel hela vägen bör du få detta som resultat

[{"CustomerID":1,"Firstname":"Kalle","Lastname":"Anka"},{"CustomerID":2,"Firstname":"Joakim",
"Lastname":"von Anka"},{"CustomerID":3,"Firstname":"Oppfinnar-Jocke","Lastname":"Johansson"}]

Nu ska vi gå vidare och använda vår webbhandler. Börja med att skapa en .aspx-sida om du inte fick en sådan skapad när du skapade webbsidan. Då jag gillar jQuery kommer jag att nyttja detta och för att slippa hosta jQuery-biblioteket själv kommer jag att nyttja Google till det då de erbjuder detta som en tjänst. I head-taggen i ditt dokument skriver du

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">

// För att ladda in jquery från Google så används följande syntax. 1.3.2 
// talar om vilken version vi vill använda
google.load("jquery", "1.3.2");

// Normalt med jquery så använder man $(document).ready() men då vi anropar från 
// Google så får vi använda denna istället
google.setOnLoadCallback(function() {

    var listitem;
    // För att göra det så enkelt som möjligt finns det en inbyggd metod
    // i jquery för att hämta json vid namn getJSON.
    $.getJSON('GetCustomers.ashx', function(items, status) {
        $.each(items, function(index, item) {
            // För varje objekt lägger vi till vår Customer i en lista. 
            // Observera att vi i vårt javascript använder samma namn på
            // egenskaperna som de vi skapade i vår Customer-klass.
            listitem = document.createElement('li');
            listitem.innerHTML = item.Firstname + ' ' + item.Lastname;
            $('#customers').append(listitem);
        });
    });
});
</script>
Glöm inte att lägga till
<ul id="customers">

</ul>

inom body-taggarna.

När du nu kör sidan kommer du att se att alla de objekt som du sparade i listan kommer att skrivas ut på sidan.

Det var allt som behövdes, hoppas du har lärt dig något av detta.

På återseende.

Tags:

jQuery | Javascript | C# | ASP.NET | Artikel | JSON

Testa dina webbsidor i olika webbläsare

by Reager 12. July 2009 19:00

Ett stort gissel för oss webbutvecklare är alla de olika varianter av webbläsare som finns ute på marknaden och skillnaderna i renderingen av html-koden och exekveringen av javascript dem emellan. Detta gör att man oftast måste testa sina sidor i de vanligaste webbläsarna innan man publicerar sidan för att försäkra sig om att sidan ser likadan ut i alla webbläsare.

Problemet här är inte Firefox, Safari eller Chrome, utan att Internet Explorer finns i olika versioner och användarna av dessa inte brukar vara de snabbaste att uppdatera vilket gör att många tyvärr fortfarande sitter med IE6 trots att IE8 finns ute på marknaden. Svårigheten här är att testa i IE utan att ha flera datorer, då det inte går, i varje fall inte utan att hacka runt lite, att köra flera versioner av IE på en dator och det då inte går att garantera att sidorna renderas likadant i en ohackad IE6.

Lösningen på detta problem stavas VPC, Virtual PC, vilket är ett verktyg som tillåter oss att köra virtuella kopior av Windows med olika versioner av Internet Explorer på. Det bästa av allt är  att det är Microsoft som står för dessa så vi behöver inte dra ut på Piratebay för att hitta dessa, utan de kan laddas hem helt lagligt från Microsofts egna hemsida.

Programmet Virtual PC 2007 hittar du på länken nedan

Virtual PC 2007

och för att ladda ner filerna med IE6, IE7 samt IE8 på Windows XP och Windows Vista hittar du här

Internet Explorer Application Compatibility VPC Image

De övriga webbläsarena hittar du här

Firefox
Safari
Chrome
Opera

Lycka till med webbutvecklandet

Tags:

Allmänt | Tips&Trix

Skapa en gästbok med Linq 2 XML

by Reager 11. July 2009 20:26

I detta inlägg så ska vi skapa en gästbok där vi lagrar inläggen i ett XML-ark. Fördelen med XML-ark är att det inte krävs någon databas och är således väldigt lätt att installera, dock har det även sina nackdelar men de ska vi inte ta upp här.

Börja med att skapa en ny webbplats i Visual Studio. I mappen App_Data skapar du en xml-fil som heter posts.xml. I denna fil skapar du sedan ett rootelement vid namn posts så filen ser ut så här

<?xml version="1.0" encoding="utf-8"?>
<posts></posts>

När detta är klart ska vi skapa en klass som skall representera våra inlägg. Jag har valt att kalla denna för klass för Post. Först och främst måste du inkludera två “namespaces”.

using System.Xml.XPath;
using System.Xml.Linq;

Själva klassen ska se ut så här:

public string PostId
{
    get;
    set;
}

public string PostedBy
{
    get;
    set;
}

public DateTime DatePosted
{
    get;
    set;
}

public string PostBody
{
    get;
    set;
}

public Post(string postid, string postedby, DateTime dateposted, string post)
{
    this.PostId = postid;
    this.PostedBy = postedby;
    this.DatePosted = dateposted;
    this.PostBody = post;
}

Jag antar att det inte är några konstigheter med ovanstående stycke. Dock vill ju ha möjlighet att spara våra inlägg också och jag har därför skapat tre metoder i denna klass. Det är GetPosts – returnerar alla poster, AddPost – sparar en post samt EditPost vilken givetvis uppdaterar en post. Dessa metoder har jag gjort till static för enkelhetens skull och de ser ut på så här

// Denna metod är bara till lite hjälp så vi slipper skriva samma sak hela tiden
private static XDocument GetXDocument()
{
    return XDocument.Load(HttpContext.Current.Server.MapPath("") + @"/App_Data/posts.xml");
}

public static List<Post> GetPosts()
{
    List<Post> posts;
    
    // Ladda in xmldocumentet
    XDocument xdoc = GetXDocument();
    
    // Med hjälp av LINQ söker vi ut alla post-noder i XML-dokumentet och
    // gör om dem till Post-objekt som vi sedan skapar en lista av.
    posts = (from p in xdoc.Root.Descendants("post")
            select new Post((string)p.Element("PostId"), (string)p.Element("PostedBy"),
                (DateTime)p.Element("DatePosted"), 
(string)p.Element("PostBody"))).ToList<Post>(); return posts; } public static void AddPost(Post p) { // Ladda XML-Documentet XDocument xdoc = GetXDocument(); // Sedan lägger vi till ett nytt element först i dokumentet. // Det vi gör är att vi skapar i root-noden en ny nood vid namn post // som vi sedan fyller på med element samt dess värden. Bodyn skapar // vi som en CDATA-nod så vi kan ha t.ex. < och > i det fältet. // CDATA-elements innehåll parsas inte. xdoc.Root.AddFirst(new XElement("post", new XElement("PostId", p.PostId), new XElement("PostedBy", p.PostedBy), new XElement("DatePosted", p.DatePosted), new XElement("PostBody", new XCData(p.PostBody)))); // Sist men inte minst sparar vi vårt xml-dokument xdoc.Save(HttpContext.Current.Server.MapPath("") + @"/App_Data/posts.xml"); } // Denna metod uppdaterar en post public static void EditPost(string postid, string postbody) { // Ladda XML-dokumentet XDocument xdoc = GetXDocument(); // Hämtar den aktuella noden med hjälp av XPATH XElement node = xdoc.XPathSelectElement("posts/post[PostId='" + postid + "']"); // Uppdaterar den hämtade noden med en ny body node.Element("PostBody").Value = postbody; // Sedan sparar vi åter igen vårat dokument med den // nya informationen xdoc.Save(HttpContext.Current.Server.MapPath("") + @"/App_Data/posts.xml"); }

När detta är klart kan vi öppna upp Default.aspx och där dra ut två textboxar, en knapp samt en repeater. De objekt som jag drog ut namngav jag så här

<asp:TextBox ID="PostedBy" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="PostBody" runat="server" TextMode="MultiLine"></asp:TextBox>
<br />
<asp:Button ID="Save" runat="server" Text="Posta inlägg" OnClick="Save_Click" />
<br />

<asp:Repeater ID="rptrPosts" runat="server">
<ItemTemplate>
<ul>
<li>Postat av: <%#Eval("PostedBy") %></li>
<li>Datum: <%#Eval("DatePosted") %></li>
</ul>
<div class="Post">
<%#Eval("PostBody") %>
</div>

Det som är kvar att göra nu är att binda datan till repeatern samt skapa klick eventet. För att göra det enklare och mindre redundant kod rekommenderar jag att du skapar en privat metod vid namn BindData där du tar han om databindningen. Då kan du kalla på denna metod varje gång du vill binda om datan istället för att göra det manuellt.

private void BindData()
{
    // Hämtar posterna och binder till repeatern
    rptrPosts.DataSource = Post.GetPosts();
    rptrPosts.DataBind();
}

I Page_Load så binder vi datan om det inte är en postback

if (!IsPostBack)
{
    BindData();
}

och klick-eventet för vår knapp ser ut så här

protected void Save_Click(object sender, EventArgs e)
{
    // När vi klickar på Spara-knappen så lagrar vi informationen i XML-dokumentet
    Post.AddPost(new Post(Guid.NewGuid().ToString(), PostedBy.Text, DateTime.Now, 
PostBody.Text)); // Och binder om datan BindData(); }

Sedan har vi en gästbok som sparar all information i ett XML-dokument. Funktionaliteten för att uppdatera själva XML-arket har jag inte skapat, men det är inga större svårigheter då metoden för det redan är skapad.

Observera att denna gästbok inte har något skydd mot t.ex. XSS, men detta kan du enkelt implementera genom att html-koda den data som användaren har matat in när du hämtar ut datan i metoden GetPosts.

På återseende.

Ladda ner:

Tags: , , ,

Artikel | ASP.NET | C# | XML | Linq

Färga kod i dina blogginlägg

by Reager 11. July 2009 17:38

Om du liksom jag brukar posta inlägg med kod i så finns det många olika sätt för att få färg på denna kod. Efter att ha provat flera olika, t.ex. först posta koden på pastebin och sedan kopiera in koden i mitt blogginlägg, kopiera koden från Visual Studio m.fl. så började jag använda Windows Live Writer tillsammans med en plugin som heter "Insert Code for Windows Live Writer". Denna plugin gör det extremt enkelt att posta inlägg med färgad kod. Exempel på detta kan du se i senare inlägg på denna blogg.

Funktioner som denna plugin har är

Syntax highlighting för följande språk:

  • C#
  • Javascript
  • Html
  • TSQL
  • MSH
  • Visual Basic

Det går även att få kodraderna numrerade, dessvärre så går det inte att kopiera koden utan att radnumrerna följer med vilket jag anser är denna plugin:s största brist. Det går även att få kodraderna med alternerande bakgrund samt välja att inte infoga css:en direkt i koden utan lägga den i ett externt stylesheet istället.

Du hittar denna excellenta plugin på följande adress: http://gallery.live.com/liveItemDetail.aspx?li=1f57bd9b-a692-4593-9e9e-e2962d9c0eee&bt=9&pl=8

Denna rekommenderas verkligen för dig som postar kod på din blogg.

Tags: , , , , ,

Artikel | Tips&Trix | Allmänt

Skicka mail i en egen tråd

by Reager 5. July 2009 21:11

Ofta på våra webbplatser så vill vi skicka ut mail till våra användare, men vi vill inte sitta och vänta tills alla är skickade och sidan laddas om. Vad gör vi då? En lösning är att skicka
mailen i en egen tråd. Detta gör att mailutskicket hanteras i en egen tråd på servern och vi kan fortsätta surfa och låta mailutskicket sköta sig självt.

Att åstakomma detta är mycket enklare än vad man kan tro. Jag kommer i detta exempel att ha mina medlemmar som jag vill skicka mail till i ett xml-ark, men detta kan
givetvis anpassas så att du hämtar din information från databasen istället.

Det första jag gör är att skapa en ny webbplats i visual studio. Sedan skapar jag en xml-fil i mappen App_Data med en root-nod users, samt några user-element som innehåller namn samt epost-adress.

XML-filen ser ut på följande vis

<?xml version="1.0" encoding="utf-8" ?>
<users>
  <user>
    <name>
      Daniel      
    </name>
    <email>
      test@aspdotnet.nu      
    </email>
  </user>

  <user>
    <name>
      Kalle
    </name>
    <email>
      test1@aspdotnet.nu
    </email>
  </user>
</users>

I default.aspx som VS har skapat åt oss så drar vi ut två textboxar samt en knapp. Den ena textboxen ska vara "Multiline" och innehålla vårat mail och den andra ska innehålla vårat ämne för mailen. Knappen ska vi ha för att skicka mailet. Sätt lämpliga ID:n på alla tre element samt text och ett klick-event på knappen. Din kod bör se ut något i stil med

<asp:TextBox ID="Subject" runat="server"></asp:TextBox>
<asp:TextBox ID="Body" TextMode="MultiLine" runat="server"></asp:TextBox>
<asp:Button ID="SendMail" runat="server" Text="Skicka mail" OnClick="SendMail_Click"/>

För event så använder jag namnkonventionen elementID_event, men du kan namnge det hur du vill. När detta är klart går vi över till kodläget. Börja med att inkludera följande tre "namnrymderna".

using System.Net.Mail;
using System.Threading;
using System.Xml;

Nästa steg är att skapa själva klick-eventet för knappen samt koden som startar tråden.

protected void SendMail_Click(object sender, EventArgs e)
{
    // Det enda vi ska göra här är att säga åt programmet att vi
    // vill köra en metod i en egen tråd och det gör man genom följande rad. 
// Det vi skickar med är ämnet och meddelandet och delar det med | så att vi kan
// splitta det i tråden sen då det bara går att skicka med ett objekt. ThreadPool.QueueUserWorkItem(new WaitCallback(SendMailInThread),
Subject.Text + "|" + Body.Text); }

Som du ser skickar vi in ett objekt av typen WaitCallback med vårat metodnamn som argument till metoden QueueUserWorkItem. Det är i denna metod SendMailInThread som allt arbete kommer att ske. För att skicka själva mailen så måste vi givetvis skapa denna metod, och den ser ut på följande vis:

private void SendMailInThread(object o)
{
        // Vi skapar ett xdoc och laddar in våran xml-fil i denna
        XmlDocument xdoc = new XmlDocument();
        xdoc.Load(Server.MapPath("") + @"\App_Data\users.xml");
        // Sedan hämtar vi ut alla user-noder i vårat xmldoc med
        // hjälp av xpath
        XmlNodeList xlist = xdoc.SelectNodes("users/user");
        // Denna nodelist kommer att innehålla elementen som finns i user-elementen
        XmlNodeList xlistChildren;


        // Här har vi våra mail-inställningar
        string[] subbody = ((string)o).Split(new char[] { '|' });
        SmtpClient smtp = new SmtpClient("smtp.bahnhof.se");
        MailMessage mess = new MailMessage();
        mess.From = new MailAddress("info@aspdotnet.nu", "Webbmaster");
        mess.Subject = subbody[0];
        mess.Body = subbody[1];

        // Sedan loopar vi igen dem och hämtar våra element med namn 
        // samt epost samt skickar mail
        for (int i = 0; i < xlist.Count; i++)
        {
            xlistChildren = xlist[i].ChildNodes;
            // Först anger vi vem mailet ska till. Vi använder Trim() för att 
// vara säkra på att inga blanksteg åker med mess.To.Add(new MailAddress(xlistChildren[1].InnerText.Trim(),
xlistChildren[0].InnerText.Trim())); // Här skickar vi vårat mail smtp.Send(mess); // Då vi la till adressen till en collection så måste vi tömma
// denna så inte ovanstående person får mailet flera gånger mess.To.Clear(); } }

Det var det hela, jag hoppas du har fått ut något av denna lilla artikel. Om du vill kan du ladda hem den här: MailThread.zip (5,02 kb)

Tags:

Jcrop och ASP.NET

by Reager 29. June 2009 11:31

JCrop är ytterligare en väldigt trevlig plugin till det otroligt smidiga javascript-ramverket jQuery. Med JCrop kan du på ett snygg sätt beskära bilder, eller, du utför inte själva beskärningen med JCrop utan du får upp ett markeringsverktyg för att direkt på bilden markera ytan som du vill beskära.

Det är inte mycket som krävs för att få till detta, men det första vi måste göra är att ladda hem sjäva plugin:en. Du hittar denna plugin här

http://deepliquid.com/content/Jcrop.html

Ladda hem plugin:en och packa upp alla filerna. Sedan skapar du en ny webbplats i Visual studio och flyttar mappen js samt css till ditt nya projekt. Skapa även en mapp i projektet som heter thumbs som ska innehålla våra "croppade" bilder. I mitt exempel har jag en bild som heter flowers.jpg, denna finns i mappen demos/demo_files i zip-arkivet som du tidigare laddade hem. Öppna sedan Default.aspx och lägga till följande rader i head-taggen

<script src="js/jquery.min.js" type="text/javascript" language="javascript"></script>
<script src="js/jquery.Jcrop.min.js" type="text/javascript" language="javascript">
</
script>

Det enda dessa två rader gör är att dels ladda in jQuery samt plugin:en JCrop som finns i mappen js. Nästa steg är att lägga in bilden på sidan. Detta görs genom en simpel img-tagg. För att vi ska kunna hålla reda på koordinater som skall användas när vi beskär bilden så lägger vi in fyra stycken gömda fält som ska hålla dessa värden. Så inom form-taggarna i vår aspx-fil lägger vi in följande element

<img src="flowers.jpg" id="crop" alt="JCrop example" /> 
<asp:HiddenField runat="server" ID="X1" /> 
<asp:HiddenField runat="server" ID="Y1" /> 
<asp:HiddenField runat="server" ID="X2" /> 
<asp:HiddenField runat="server" ID="Y2" /> 

Nästa steg är att aktivera själva plugin:en, och detta görs genom följande kodrader som läggs in i head-taggen under de script-taggar som vi lade in tidigare

<script type="text/javascript"> 
$(document).ready(function() { 
$('#crop').Jcrop({ 
     onChange: setCoords, 
     onSelect: resizeImage 
     }); 
}); 
// Denna funtion sparar de valda koordinterna i dolda element 
// så vi kan använda dem sedan för att skala om "croppa" vår bild 
function setCoords(c) { 
     $('#<%=X1.ClientID %>').val(c.x); 
     $('#<%=Y1.ClientID %>').val(c.y); 
     $('#<%=X2.ClientID %>').val(c.x2); 
     $('#<%=Y2.ClientID %>').val(c.y2); 
}
// Denna metod postar formuläret, vill du inte att det skall postas automatiskt kan du 
// ändra till en knapp 
function resizeImage() { 
     $('#form1').submit(); 
} 
</script> 

Först så aktiverar vi plugin:en så att den fungerar på vår bild med id=crop, och tillsammans med detta så anger vi två metoder, en som körs hela tiden då vi håller på och markerar ytan på bilden där vi vill beskära och sparar ner dessa till våra dolda fält. Eftersom .NET skapar egna ID:n på sina element så måste vi använda elementid.ClientID för att få det genererade ID:t. Den andra metoden har jag kallat resizeImage och postar helt enkelt formuläret.

När detta är klart kan du testköra sidan och se att bilden visas samt att du kan markera ytor på bilden och att formuläret postas när du släpper muspekaren. Givetvis händer inget än då vi inte skapat denna funktionalitet än, men det är nästa steg.

Öppna kod-editorn för din aspx-fil och i page_load så talar vi om att vi endast vill utföra något om det är en postback som sker.

// Om det är en postback som sker så har formuläret postats och vi
"croppar" bilden
if (IsPostBack) { // Vi skickar med våra värden från våra gömda element CropImage(Convert.ToInt32(X1.Value), Convert.ToInt32(Y1.Value),
Convert.ToInt32(X2.Value), Convert.ToInt32(Y2.Value)); }

CropImage är en metod som jag har skapat, detta för att göra koden lite tydligare. Som jag sa tidigare så kollar vi om det är en postback och om så är fallet så anropar vi metoden CropImage och skickar med alla koordinater. Själva metoden CropImage är inte så avancerad den heller, utan ser ut som nedan. Det du måste göra för att det ska fungera är att importera System.Drawing. Då klassen Image finns i flera namespaces så har jag valt att sätta ett alias på System.Drawing och det gör man genom att skriva using SD = System.Drawing; när man importerar namespacet. På så vi kan jag skriva SD.Image istället för System.Drawing.Image överallt där jag vill använda det.

// Denna metod hanterar själva "croppningen" av bilden
private void CropImage(int x, int y, int x2, int y2)
{
    // Vi laddar in våran bild.
    using(SD.Image i = SD.Image.FromFile(Server.MapPath("") + @"\flowers.jpg"))
    {
        // Sedan skapar vi en bitmap som vi kan rita på
        using(SD.Bitmap b = new SD.Bitmap(x2-x, y2-y))
        {
            b.SetResolution(i.HorizontalResolution, i.VerticalResolution);
            // Sedan skapar vi ett graphics-objekt
            using(SD.Graphics g = SD.Graphics.FromImage(b))
            {
                g.DrawImage(i, new SD.Rectangle(0, 0, x2 - x, y2 - y), x, y, 
x2 - x, y2 - y, SD.GraphicsUnit.Pixel); b.Save(Server.MapPath("") + @"\thumbs\" + Guid.NewGuid().ToString()
+ "
.jpg", i.RawFormat); } } }

Detta visar hur du på ett väldigt enkelt sätta kan croppa bilder, och koden ovan är nästan enklast möjligast och öppen för förbättringar, men det är upp till den intresserade :)

Hela artikeln kan laddas hem här: jcrop.zip (48,35 kb)

Tags: , , ,

Artikel | ASP.NET | C# | jQuery

Uploadify och ASP.NET

by Reager 28. June 2009 19:28

Uploadify är en plugin till jQuery som gör det extremt enkelt att skapa ett fint uppladdningsformulär. Tekniken bygger på javascript, flash samt valfritt serverspråk. Här kommer vi givetvis att hålla oss till ASP.NET/C# för att åstadkomma själva sparandet av den uppladdade filen.

Det första vi måste göra är att ladda hem själva plugin:en. Detta gör du från nedanstående webbplats.

http://www.uploadify.com/download/

När du laddat hem pluginen så kan du packa upp alla filerna till din dator.

Nästa steg är att skapa en ny ASP.NET webbplats i Visual Studio. När webbplatsen är skapad så skapar vi några mappar för att hålla lite ordning på våra olika filer. De mappar jag har skapat är scripts, handler samt en kallad upload som kommer att vara den katalog som vi laddar upp våra filer till.

När detta är klart så kopierar vi filerna

jquery-1.3.2.min.js
jquery.uploadify.js

till mappen scripts samt lägger filerna

cancel.png
uploader.swf
uploadify.css

i root-katalogen för vår webbplats.

Om Visual studio inte skapa en aspx-fil åt dig så skapar du denna och öppnar upp den. Det första vi måste göra här är att inkludera javascript-filerna. Detta görs genom script-taggar i head-taggen.

<script src="scripts/jquery-1.3.2.min.js" type="text/javascript" language="javascript"></script>
<script src="scripts/jquery.uploadify.js" type="text/javascript" language="javascript"></script>

Skapa sedan upp ett valfritt element på din webbsida med valfritt ID. Jag skapade en div som jag valde att sätta ID=Uploader på. Detta ID ska vi sedan använda när vi skapar själva uppladdningsformuläret med hjälp av Uploadify. I body skriver vi alltså

<div id="Uploader">
    
</div>

I head-taggen ska vi sedan "aktivera" själva pluginen och göra om vår div-tagg till ett uppladdningsformulär. Detta görs genom följande enkla kodrader.

<script type="text/javascript">
        $(document).ready(function() {
            $('#Uploader').fileUpload({
            'script': 'handler/upload.ashx',
            'auto': true
            });
        });
</script>

Det vi gör här är att säga till att direkt som DOM:en är redo så tar vi vårat element med ID=Uploader och gör om det till ett uppladdningsformulär med hjälp av pluginen. När du kommit så här långt kan du kolla på din skapade webbsida i webbläsaren och se att det skapas en knapp med texten browse. Dock går det ännu inte att ladda upp något då vi inte skapat filen som tar emot filen och sparar den på hårddisken. Detta ska vi göra nu så nästa steg är att skapa en fil vid namn upload i mappen handler och denna fil ska vara en generic handler (ashx). Koden som krävs för att spara själva filen är väldigt liten och ser ut på följande sätt

// Ta emot filen
HttpPostedFile file = context.Request.Files["Filedata"];

// Först tar vi fram mappen som filen skall sparas i
string targetDirectory = Path.Combine(context.Request.PhysicalApplicationPath, "upload");
// och sedan lägger vi till den uppladdade filens namn till sökvägen
string targetFilePath = Path.Combine(targetDirectory, file.FileName);

// Sedan skriver vi filen till disk
file.SaveAs(targetFilePath);
// och skickar tillbaka 1
context.Response.Write("1");

Det var allt som krävdes för att ladda upp en fil med hjälp av Uploadify. Om du får problem så kontrollera att du har alla behörigheter som krävs för att få spara filer på disk. Givetvis finns det mängder med inställningar du kan göra för plugin:en, och dessa finns dokumenterade på Uploadify:s hemsida för den intresserade.

Vill du se alla filerna som hör till artikeln så kan du ladda ner alltihopa här bredvid. Uploadify.zip (45,91 kb)

Tags: , , ,

Artikel | ASP.NET | C#

Komma åt parent repater från nested repeater

by Reager 22. June 2009 14:19

Rubriken kanske inte blev helt vacker, det är svårt att få vissa saker att låta fint när man ska skriva på svenska. Det jag kommer att visa är i varje fall hur du från en nästlad repeater kommer åt värden från förälder-repeatern.

Det hela är egentligen väldigt enkelt, det enda du behöver göra är följande:

<%#DataBinder.Eval(DataBinder.Eval(Container,"Parent.Parent.DataItem"),"Ref")%> 

Ref är i mitt exempel en property i den collection som jag band till min föräldra-repeater.

Tags: , ,

ASP.NET | Tips&Trix

Regular Expressions

by Reager 19. October 2007 11:41

Regular Expressions används för att hitta vissa mönster i en textmassa och ta ut de delar som matchar detta mönster. T.ex. så kan du använda det i en när du skapar en gästbok eller forum för att skapa dina egna taggar vilket ger dig kontroll över vilken html som är tillåten. Du har säkert många gånger sett när du skrivit i ett forum att när du vill ha fet text så används [b]Text som skall bli fet[/b]. Denna text kan man sedan med hjälp av Regular Expressions hitta och ersätta med html-motsvarigheten så att den skriver ut <b>Text som skall bli fet</b> istället.

Jag ska börja med att visa hur du gör en sök och ersätt enligt ovan. Börja med att dra ut en literal-kontroll som du sätter ID=litResult på. Sedan så går vi över till kod-filen där vi börjar med att importera namespace:n som vi behöver

using System.Text.RegularExpressions;

och i Page_Load skriver vi in nedanstående kod.

// Här deklarerar vi vårat pattern, samt lägger vill så att vi inte bryr oss om 
// användaren använder stora eller små bokstäver. 
Regex rxPattern = new Regex(@"\[b\](.*)?\[/b\]", RegexOptions.IgnoreCase); 
// Här säger vi att vi vill använda vårat Regex-mönster och göra en replace. 
// Texten som vi ska söka
igenom är den första strängen och den andra strängen är vad vi ska
// ersätta med. $1 betyder att den s
ka ta den första träffen vårat mönster får och ersätta med. litResult.Text = rxPattern.Replace("[b]Text som skall bli fet[/b]", "<b>$1</b>");

Om du nu kontrollerar källkoden så kommer du att se att <b>Text som skall bli fet</b> har skrivits ut, detta tack vare vårat mönster som hittade texten vi var ute efter och ersatte den med våran valda text.

Nästa exempel ska visa hur du tar ut valda delar ur en text och skriver ut dessa. Exemplet jag ska visa här tar antalet inloggade på http://www.ASPSidan.se.
Liksom föregående exempel så drar vi ut en literal-kontroll som vi ger ID:t litResult samt importerar namespacet, sedan i Page_Load skriver vi följande kodsnutt.

// För att göra det lite roligare så kommer vi att använda en metod i klassen WebClient för 
// att hämta hem den text vi ska använda för våran utsökning från ASPSidan. 
// Metoden vi ska använda
heter DownloadString WebClient wcClient = new WebClient(); // Det första vi gör är att deklarerar vårat mönster som vi kommer att använda för // att få fram antalet inloggade Regex rxPattern = new Regex(@"inloggade:\s(\d*)?"); // Vi sparar sedan vårat resultat i ett Match-objekt Match mCount = rxPattern.Match(wcClient.DownloadString("http://www.aspsidan.se")); // Vi skriver sedan ut vårat resultat litResult.Text = mCount.Groups[1].Value; wcClient.Dispose();

Gör du utsökningar som får mer än ett resultat så använder du MatchCollection istället samt metoden Matches. Ett exempel visas nedan

MatchCollection mcMatches = rxPattern.Matches("text här som mönstret skall testas emot");

Du har här fått en liten kort introduktion till vad du kan använda Regular Expressions och de är ett mycket kraftfullt verktyg när du behöver hitta valda delar ur en textmassa. Då jag själv inte är nån stjärna på att knåpa ihop dessa Regular Expressions så har jag valt att inte försöka förklara hur man gör detta, men du kan läsa mer om det samt hitta många färdiga RegExp:s på

http://regexlib.com/ samt  http://www.regular-expressions.info/

Om tiden tillåter ska jag försöka vara lite mer aktiv på sidan än jag varit på sistone.

Tags: , ,

ASP.NET | C# | Regular Expressions | Artikel

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

RecentComments

Comment RSS