Mer om det dåliga stödet för URL-omskrivning i Asp.Net

Jag älskar att utveckla i Asp.Net C# och kommer definitivt fortsätta att satsa på denna teknik. Men allt kan ju inte vara perfekt. Den största bristen i ramverket är enligt mig att det inte finns något inbyggt stöd för URL-omskrivning. Har skrivit lite om det tidigare.

Det är framför allt i IIS 6 som bristerna finns. I den nyare IIS 7 som kommer lanseras med Longhorn server kommer det finnas bättre möjligheter till att lägga in regler för URL-omskrivning. Det är ju dock en tag kvar tills det nya operativsystemet finns på marknaden så det hjälper oss inte just nu.

Det man kan göra i dagsläget är att använda ASAPI-filter men då förutsätts att du har en egen dedikerad server eller ligger på ett webbhotell som vill installera det åt dig. Jeff Atwood på Coding Horror skriver mer om de två vanligaste ASAPI-lösningarna för IIS.

En av de främsta kritikerna av situationen är nog Mike Schinkel. Detta är killen som ligger bakom initiativet wiki.welldesignedurls.org och den medföljande bloggen där man kan läsa mycket intressant på ämnet.

På sin personliga blogg sparar inte Mike på krutet. I en post nyligen med rubriken "IIS 7.0: Too Little, Too Late?" hoppar även en annan Mike (Program Manager för Microsoft’s IIS team) in i diskussionen och beklagar situationen.

Den första Mike fortätter i ett annat inlägg att lista upp alla alternativa server-tekniker och frågar sina läsare vilken han ska börja använda istället för Asp.Net. Han verkar ha tröttnat och det är lite tråkigt tycker jag.

Men bra att många uppmärksammar problemet. Microsoft har dock meddelat att IIS 7 kommer inte finnas tillgänglig för Windows 2003 och det är riktigt synd. De nya teknikerna är för djupt förankrade i Longhorns nya ramverk, menar man.

Men vem vet, efter alla böner från utvecklare kanske Microsoft kan avsätta lite resurser på det. Det skulle vara helt underbart. Mitt tips är att göra en lättare uppgradering till IIS 6 och försöka få till samma implementering av URL-omskrivning som i den kommande webbservern. Kalla den typ IIS 6.5.

By Jesper Lind

Stor utförsäljning av snowboards och vinterkläder

http://www.codeodyssey.se/upload/resource/blog/junkyard-vinter-sale-2007.gif

Brrr. Nu har kylan kommit tillbaks och det snöar här i Göteborg. Läste precis att det förväntas att bli snökaos till och med i södra delarna av landet. Om du sen av dig som jag och inte köpt någon vinterjacka i år, så kan jag rekommendera att kolla in super-rean på Junkyard.se.

Rean som har hållt på ett tag ökar med 2% varje dag. Just nu ligger den på 32% och med redan nedsatta priser kan man hitta fynd på upp till 75% rabatt. Men det gäller att vara snabb om du vill hitta ett fynd. Rean håller bara på tills på söndag och prylarna försvinner nu i ett rasande tempo.

Ska du upp till fjällen kan detta också vara ett ypperligt tillfälle att införskaffa den grymmaste utrustningen. Massor av snowboards, bindningar och boots från märken som Bataleon, Burton, Capita, Forum, Lib Tech, Rome m fl.

Hoppas ni får en riktigt skön vintersemester. Vi som jobbar med att utveckla sidan får tyvärr stanna hemma. Nu kommer vi jobba med att hålla sidan vid liv under reans sista dagar, och ber vi till servergudarna att sidan ska palla trycket in i det sista.

Natten kl 24 på söndagen den 25 stängs alltså shoppen i en vecka för underhåll.

Sen kan jag avslöja att vi har jobbat hårt på en liten nyhet till sidan. Förhoppningsvis ska denna vara klar inom några veckor.

Missa inte heller vår nyhetsdel som har fått en liten nytändning. Massor av coola actionsportklipp, reportage och vinterns händelser i kalendern.

By Jesper Lind

Sortera och selektera DataTable

Här är en liten kort lösning på hur man väljer ut ett visst antal rader ur en DataTable och efter en definerad sortering. Ungefär som man gör i SQL-uttrycket (SELECT TOP).

Detta hade jag haft en del problem med tidigare i samband med hantering av ett DataSet. Idag lyckades jag genom att forska i det på bland annat DeveloperFusion, TheScripts och MSDN - DataTable.Select().

Jag hade satt ihop ett antal DataSet till ett kombinerat DataSet. När jag försökte iterera igenom detta sammasatta DataTable, kom alltid de rader jag hade lagt till först, överst i utskriften. Jag behövde ha sorteringen efter en specifik parameter som var gemensam för hela den nya datasamlingen, i mitt fall en datum-kolumn.

Här är lösningen som jag kom fram till. Den använder DataTable.Select() och lämnar första parametern tom. Den andra anges för att få rätt sortering. En array av DataTable-rader returneras. Dessa importerar jag en efter en till en klonad modell av DataTablen. Jag begränsar detta till 10 omgångar. Slutligen returneras en DataView.

DataView SelectTopSortedFromDataTable(DataTable objTable)
{
DataTable outputTable = objTable.Clone();

DataRow[] foundRows = objTable.Select("","PublishDate DESC");

for(int i=0;i<10;i++)
{
DataRow objDataRow = foundRows[i];
outputTable.ImportRow(objDataRow);
}

DataView dataView = outputTable.DefaultView;
return dataView;
}

By Jesper Lind

Twinglys skärmsläckare visualiserar bloggosfären

http://www.codeodyssey.se/upload/resource/blog/saverbanner.png

Om du själv är bloggare så tror jag inte du har missat ankomsten av Twingly som är en bloggsökmotor och pingtjänst. Nu släpper Primelabs även en skärmsläckare som är baserad på deras bloggindex.

Måste säga att Primelabs verkligen har importerat stort med sina lanseringar och framtoning som företag. Allt de gjort hittills har varit exemplariskt och jag har en känsla av att de har fler äss i ärmen.

Ta till exempel den nya skärmsläckaren som nyligen lanserades, hur cool är inte den? Nu kanske jag är överdrivet intresserad av just såna här grafiska överblickar men endå. När den lanserades såg man även till att lägga ut en film på YouTube och fixa en länk på Digg. Helt rätt.

Angående skärmläsaren så tycker jag du ska kolla in den om du har något intresse för bloggosfären. Programmet visar en 3D-modell av jorden och en lista med rubriker för nya inlägg till vänster. På platser med många inlägg byggs det upp små staplar. Man kan zooma in och vrida på modellen.

Förutom att använda den som skärmsläckare kan man även köra den som ett vanligt program. Det enda som är lite synd är att den är så resurskrävande. Hoppas de får till en mer optimerad version senare, den är ännu bara i beta-stadium.

Ladda ner Twingly Screensaver

By Jesper Lind

Ladda upp och förminska bilder med ASP.NET

Vi kör ett litet torsdagstema med bildbehandling. Skrev för ett tag sen lite kortfattat om hur man kan ladda upp filer med ASP.NET. Ser att det ramlar in en hel del folk genom sökningar så tänkte gå vidare på ämnet.

Nu tänkte jag bjuda på en till mesta del hemmasnickrad klass för att ladda upp och förminska bilder till servern. Kvaliteten blir ibland inte perfekt så denna funktion passar bäst till att skapa mindre tumnaglar.

Sen har jag även märkt att röda nyanser blir något flammiga ibland. Själva funktionen "CreateThumbnail" har inte jag skrivit men har haft den så länge att jag glömt bort var den kommer från. Om någon har en bättre lösning som ger bättre resultat är jag mycket intresserad. Annars kanske det få bli en djupdykning i källkoden för gratisprogrammet Paint.NET i jakt på bätte förminskningsfunktioner.

Men nu till exemplet. Ber om ursäkt för dålig dokumentation och en blandad kompott på svenska och engelska. Använd den precis som du vill. Jag uppskattar länkar tillbaks och även om du gör några framsteg på bildkvaliteten.

Så här anropar man klassen:

if (fu.HasFile)
{
Trace.Write("We found a image to upload");
HttpPostedFile userPostedFile = fu.PostedFile;
ImageUploader imageUploader = new ImageUploader("C:/sökväg/på/server/", userPostedFile, "Namnpåbild.jpg");
//Utlämna mått för att behålla orginalstorlek på bilden
imageUploader.IntMaxWidth = 150;
imageUploader.IntMaxHeight = 50;
bool boolStatus = imageUploader.UploadImage();
if(boolStatus)
Trace.Write("Image uploaded!");
}

Och här är själva klassen:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
using System.Drawing.Imaging;


/// <summary>
/// Summary description for ImageUploader
/// </summary>
public class ImageUploader : Page
{

//Lokala variabler
private HttpPostedFile userPostedFile = null;
private string strWhereStatement = null;
private string strRootPath = string.Empty;
private string strImageName = string.Empty;
private int intMaxWidth;
private int intMaxHeight;

//Properties
public string StrRootPath
{
get { return strRootPath; }
set { strRootPath = value; }
}
public string StrImageName
{
get { return strImageName; }
set { strImageName = value; }
}
public int IntMaxWidth
{
get { return intMaxWidth; }
set { intMaxWidth = value; }
}
public int IntMaxHeight
{
get { return intMaxHeight; }
set { intMaxHeight = value; }
}


//I första konstruktorn använder vi filens orginalnamn
public ImageUploader(string StrRootPath,HttpPostedFile UserPostedFile)
{
strRootPath = StrRootPath;
userPostedFile = UserPostedFile;
//Ta bort eventuell filändelse
strImageName = userPostedFile.FileName.Remove(userPostedFile.FileName.LastIndexOf("."));
//UploadImage(userPostedFile);
}
//I den utökade så skickar vi med ett eget filnamn
public ImageUploader(string StrRootPath,HttpPostedFile UserPostedFile,string StrImageName)
{
strRootPath = StrRootPath;
userPostedFile = UserPostedFile;

strImageName = StrImageName;
}



public bool UploadImage()
{
bool tooHigh = false;
bool tooWide = false;
bool doUpload = false;
bool uploaded = false;
string strFileExt = string.Empty;

try
{

//Kontrollera att filen är större än 0KB
if (userPostedFile.ContentLength > 0)
{

//Check på filändelse och om man ska tillåta uppladdning

//Jpg och Jpeg
if (userPostedFile.ContentType.Equals("image/jpeg") || userPostedFile.ContentType.Equals("image/pjpeg"))
{
doUpload = true;
strImageName += ".jpg";
}
//Gif
if (userPostedFile.ContentType.Equals("image/gif"))
{
doUpload = true;
strImageName += ".gif";
}
//Bmp
if (userPostedFile.ContentType.Equals("image/bmp"))
{
doUpload = true;
strImageName += ".bmp";
}
//Png
if (userPostedFile.ContentType.Equals("image/png"))
{
doUpload = true;
strImageName += ".png";
}

System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(userPostedFile.InputStream, false);

//Kolla höjd
if (intMaxHeight != null)
{
if (bitmap.Height > intMaxHeight)
{
doUpload = true;
tooHigh = true;
}
}

//Kolla bredd
if (intMaxWidth != null)
{
if (bitmap.Width > intMaxWidth)
{
doUpload = true;
tooWide = true;
}
}

Trace.Write(strRootPath + strImageName);
if (doUpload && bitmap != null)
{
Trace.Write("doUpload!!");

//Förminska om den är för stor, och ladda upp
if (tooHigh || tooWide)
{
Trace.Write("tooBig!!");
//Skapa liten automagiskt
double photoWidth, photoHeight;
double percentageDifference = 0;

photoWidth = intMaxWidth;


//Nya mått på bilden.
percentageDifference = bitmap.Width / photoWidth;
photoHeight = bitmap.Height / percentageDifference;

//Kolla även höjden
if (photoHeight > intMaxHeight)
{
photoHeight = intMaxHeight;
percentageDifference = bitmap.Height / photoHeight;
photoWidth = bitmap.Height / percentageDifference;
}

Bitmap outputBitMap = CreateThumbnail(bitmap, Convert.ToInt32(photoWidth), Convert.ToInt32(photoHeight));

//Kolla vad det är för format
ImageFormat imageFormat = outputBitMap.RawFormat;

//Spara bilden
outputBitMap.Save(@"" + strRootPath + strImageName, imageFormat);
uploaded = true;
}
//Ladda upp orginalbilden om den är inom måtten
else
{
Trace.Write("Rätt storlek eller mindre.");


userPostedFile.SaveAs(@"" + strRootPath + strImageName);
uploaded = true;
}

}

}
}
catch(Exception objException)
{
Trace.Write("Upload fel!", objException.Message);
uploaded=false;
}
return uploaded;
}

//Tar emot en BitMap och gör den mindre
public static Bitmap CreateThumbnail(Bitmap loBMP, int lnWidth, int lnHeight)
{
System.Drawing.Bitmap bmpOut = null;

try
{

ImageFormat loFormat = loBMP.RawFormat;
decimal lnRatio;
int lnNewWidth = 0;
int lnNewHeight = 0;

//Om bilden är större än en thumbnail, returnera den.
if (loBMP.Width < lnWidth && loBMP.Height < lnHeight)
return loBMP;

if (loBMP.Width > loBMP.Height)
{
lnRatio = (decimal)lnWidth / loBMP.Width;
lnNewWidth = lnWidth;
decimal lnTemp = loBMP.Height * lnRatio;
lnNewHeight = (int)lnTemp;
}
else
{
lnRatio = (decimal)lnHeight / loBMP.Height;
lnNewHeight = lnHeight;
decimal lnTemp = loBMP.Width * lnRatio;
lnNewWidth = (int)lnTemp;
}

bmpOut = new Bitmap(lnNewWidth, lnNewHeight);
Graphics g = Graphics.FromImage(bmpOut);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight);
g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight);
loBMP.Dispose();
}
catch
{
return null;
}
return bmpOut;
}
}

By Jesper Lind

Paint.NET - gratis program för bildbehandling

http://www.codeodyssey.se/upload/resource/blog/paint-net.png

Laddade just hem Paint.NET och har provkört det lite snabbt. Verkar vara kanonbra. Det startar upp på typ en sekund och har en hel del funktionalitet när det gäller bildbehandling.

Jag har länge letat efter ett sådant här program för att använda till snabbare ändringar på bilder, och nu har jag funnit det. Tidigare har jag gjort all bildbehandling i Photoshop och det vet ju de flesta användare att det är ganska så segstartat.

Att programmet är helt gratis skadar ju inte heller. Det är släppt under Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Licens och C# kod på 133000 rader finns att ladda hem för den som är sugen.

(Tack Sovrat)

By Jesper Lind

Webbutveckling - tidsfördelning

http://www.codeodyssey.se/upload/resource/blog/web-design-time.gif

Här är en klockren bild över hur en webbutvecklares vardag kan se ut. Som ni ser på den något ironiska bilden brottas vi ca 45% av tiden med att försöka få designen att bra ut i den mest använda webbläsaren IE6. Jag vet att just den versionen inte står inskriven på bilden, men det är min egen tolkning.

Som tur är har jag lagt ner all fokus på att försöka få den här webbplatsen att de bra ut i den föråldrade läsaren, och alltså sparat in nästan hälften av utvecklingstiden. Att denna sidan ser helt kass ut med IE6 (konstiga mellanrum och kantiga ramar) bryr jag mig helt enkelt inte om.

Jag ser dock fortfarande att många av er som besöker den här sidan använder IE6. Varför har ni inte uppdaterat ännu? Se nu till att ladda hem IE7 så fort som möjligt – den finns ju på svenska så det är väl inget att vänta på? Mycket säkrare, fina fliksystem och RSS-läsare. Precis allt det som en modern surfare som du behöver.

(via swEcommerce)

By Jesper Lind

Lärare blev infekterad av trojan - riskerar nu 40 års fängelse

Det här blir man ju bara förbannad på. En lärare lämnade eleverna med en dator i några minuter. Barnen surfade själva in på en hemsida för hårvård. På hemsida råkade det finnas en länk till en sida med pornografiskt innehåll.

Nu infekterades datorn med en så kallad trojan och mängder av nya fönster poppade upp med sexuellt innehåll. Den stackars läraren försökte febrilt stänga ner fönstren allt eftersom de kom upp nya. Många av er som läser detta har nog råkat ut för ungefär samma sak. I alla fall för några år sen innan webbläsarna började införa popup-blockerare.

Nu åtalas hon och riskerar ett maximalt straff på 40 års fängelse. Åtalar sidan menar att hon kunde ha slängt ett skynke över datorn och på så sätt skyddat barnen. Inte så lätt att tänka över detta om man inte är så datorkunnig och kämpar med att få bort elaka fönster, säger jag.

Så om du är lärare och bor i Eastern Connecticut, så rekommenderar jag dig att slå sönder monitorn så fort något liknande händer. Om du inte råkar ha ett skynke i närheten menar jag. Det blir bra mycket lindrigare att betala den räkningen än att riskera fängelse. Var det nån som nämde att det finns galningar i USA?

(Via ha.ckers.org)

 

By Jesper Lind