132/2009
Har programmerat om kommentars-funktionen på bloggen och den följer nu designmönstret Post/Redirect/Get (PRG Pattern). Det innebär att när en kommentar postas så görs det till en specifik url som bara accepterar Http-verbet "Post". Sen skickas besökaren tillbaks till inläggets vanliga url med en ankarlänk till den nyligen postade kommentaren tillagd på slutet.
Innan denna förändring så postades kommentaren direkt till samma vy/url som även används till att visa inlägget.
Fördelar med PRG-mönstret
Fördelen med att följa PRG-mönstret är att kommentaren inte dubbelpostas ifall användaren klickar på tillbaka-knappen i sin webbläsare. Nuförtiden så varnar ju dock de flesta moderna webbläsare att en ompostning kommer ske, men det är ofta man inte tänker på att det inte går att backa och det är ett rätt störande meddelande som man slipper med PRG-mönstret.
Läs mer hos Stephen Walter som också beskriver samma mönster med ASP.NET MVC i artikeln "Call RedirectToAction after Submitting a Form".
Hur man gör för att redirecta till en länk med ankare på slutet hittade jag på en japansk blogg.
Hur det är implementerat här på bloggen
Tänkte visa lite exempelkod som är ungefär den kod som körs på bloggen just nu.
Först de routes som har med att visa inläggen och posta kommentarer:
routes.MapRoute(
"BlogPostAddComment",
archiveRoute + "/{year}/{month}/{day}/{slug}/add-comment", //arkiv/2008/05/29/radonförgiftning#ankar-länk
new { controller = "Blog", action = "AddComment" }
);
routes.MapRoute(
"BlogPostWithAnchor",
archiveRoute + "/{year}/{month}/{day}/{slug}#{anchor}", //arkiv/2008/05/29/radonförgiftning#ankar-länk
new { controller = "Blog", action = "ArchiveBySlug" }
);
routes.MapRoute(
"BlogPost",
archiveRoute + "/{year}/{month}/{day}/{slug}", //arkiv/2008/05/29/radonförgiftning
new { controller = "Blog", action = "ArchiveBySlug" }
);
}
Sen det Action i Controllern som sätter in kommentarern i databasen och redirectar användaren till rätt vy igen. Det sker lite mer blanda annat har vi ett anti-spam-skydd och kommentarern mailas även till mig (nytt för idag så nu kommer jag vara mer alert på nya kommentarer).
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddComment(int year, int month, int day, string slug)
{
var url = Request.Form["url"];
int postid = Convert.ToInt32(Request.Form["postid"]);
var name = Request.Form["name"];
var body = Request.Form["body"];
var email = Request.Form["mail"];
int addedCommentId = blogService.AddComment(postid, name, body, email, url);
return RedirectToRoute("BlogPostWithAnchor", new { action = "ArchiveBySlug", year = year, month = month, day = day, slug = slug, anchor = "comment-"+addedCommentId });
}
Av Jesper Lind
42/2009
Japp nu är det dag att stäppa upp the Adsense-game en nivå och så kanske vi kan tjäna några extra korvören. Problemet är ju bara det att du vår vanliga läsare är en tech geek som slutade att klicka på annonser nån gång runt 2001. Så det är ju inte så stor idé att visa mer reklam än det lilla vi haft i högerspalten.
Istället gör vi nu så att vi bara vi visar en stor banner längst upp på de som söker via Google. Så vi får nån nytta av förstaplasten vi har på "vinterkläder", alla som ska in och förstå hur de använder visningsprogram för bilder och fax eller hitta sina lösenord till Geni.com. Dessa tre sökningar utgör den större delen av trafiken på sajten vilket är rätt sjukt när det inte direkt är huvudämnen vi skriver om. Eftersom dessa besökare bara stannar här i genomsnitt 40 sekunder så känns det som man lika gärna kan blaffa upp en banner.
Här under är min väldigt enkla kodrad för att genomföra detta. Den är inte så speciellt genomtänkt så går säkert att förbättra. Bara kollar ifall referer innehåller "google." och att den inte kommer från Google Reader. Vill du läsa något mer avancerat så kolla in Parse Google Search Query på Dot Net Peris som visar hur man kan få fram söktermer.
<%string referrer = (HttpContext.Current.Request.UrlReferrer != null) ? HttpContext.Current.Request.UrlReferrer.ToString():string.Empty;
if (referrer.IndexOf("google.") != -1 && referrer.IndexOf("reader") == -1){%>
<!--Your Adsense Code here-->
<%}%>
Gör du nåt likande på din blogg? Skulle vara intressant att höra om andra tips på ämnet.
Av Jesper Lind
32/2009
Som standardinställning visar IIS7 rätt tråkiga felmeddelande när en sida inte kan hittas och ser ut som på bilden här under. Just nu ser denna bloggens 404-sidor ut precis så där, så vi ska försöka fixa något roligare. Detta inlägg kommer visa hur man gör för att ställa in servern så att man ska kunna visa en egen design istället.

Gå in på den webbplats som ska konfigureras och klicka på Error Pages. Följ sedan instruktioner på följande bild. Klicka Edit Feature settings... och välj Detailed Errors.

Så nu ska jag bara skicka iväg denna post till vårt webbhotell så fixar de nog de inom kort.
Sen var det där med egen design. Kommer nog inte hinna få till med något jättespännande. Om du vill se exempel på riktigt snygga och roliga 404-fel-sidor kolla in Smashing Magazine som har några riktigt fina samlingar.
Av Jesper Lind
241/2009
Har precis fixat så att kodexempel i denna blogg får syntaxen framhävd med färger så den förhoppningsvis ska bli mer lättläst. Det engelska uttrycket är ju "syntax higlighting" men jag hade lite svårt att hitta en svensk motsvarighet först. Kristoffer på Bloggy hjälpte mig och tipsade om "syntaxmarkering", som fick blir titel på detta inlägg.
När jag sökte efter en metod att få till detta hittade jag några olika alternativ, i en tråd på Stack Overflow går man igenom några av dem.
Vissa tycker att det är en bra ide att märka upp koden med html och css i förhand, och spara den färdigformatterad i databasen. Detta kan man bland annat göra med ett plugin till Visual Studio som heter CopySourceASHtml. Jag dock att jag inte ville ha in detta i databasen utan att koden skulel sparas helt utan extra HTML och CSS. För om man vill ändra på det i efterhand så är det ju omständigt att behöva ändra alla gamla exempel.
Istället beslutade jag mig för att använda Javascript och att formatteringen ska ske i besökarens webbläsare. Uppritningen blir ju något långsammare, men de andra fördelarena var tillräckligt stora för att jag skulle gå på detta spåret.
Ett sådant javascript är google-code-prettify men eftersom det inte verkar ha stöd för C# så var det inget alternativ för denna blogg som har större delen av kodexemplen på det programmeringsspråket.
Istället valde jag samma som Scott Hanselman och bloggplattformen Wordpress använder sig av. Det heter SyntaxHighlighter och är utvecklat av Alex Gorbatchev.
Ett litet problem är dock att koden ska märkas upp på följande sätt och name inte är godkänt attribut på <pre>-taggen enligt XHTML-standarderna.
<pre name="code" class="javascript">
// the code
</pre>
Lars Corneliussen har dock fixat ett jQuery-plugin beautyOfCode som ändrar beteendet i SyntaxHighlighter så man istället kan använda följande struktur:
<pre class="code">
<code class="javascript">
// the code
</code>
</pre>
Det senare alternativet är alltså godkänd XHTML och det är detta som jag använder här. Läs gärna om hur jag fixade så att TinyMCE-editorn kan skapa denna kod med hjälp av ett plugin.
Än så länge har jag bara gjort om kodexemplena på förstasidan i bloggen till att använda syntaxmarkeringen. Ska fundera lite på hur jag ska ändra alla gamla exempel som fortfarande bara visas med en grå ruta.
Av Jesper Lind
241/2009
När jag postade mitt förra inlägg så märkte jag att källkoden kunde formateras bättre. HTML-editorn TinyMCE som vi använder till att redigera inläggen stoppar som default in <br /> på alla radbryt och omger stycken med paragrafer. Bra när man skriver brödtext, men onödigt när man vill posta källkod. Jag ville hellre att kodexemplena skulle vara förformatterade utan någon extra HTML-uppmärkning.
Eftersom jag har tagit bort breaks i det förra inlägget kommer här en bild på hur det såg ut innan.

Samtidigt ville jag prova med att fixa syntax-formattering där nyckelorden får färger för bättre läsbarhet. Ska skriva mer om hur jag gjorde själva syntax-uppmärkningen i ett senare blogginlägg, men kan nämna att jag gjort detta med javascript hos besökaren. Uppdatering: Nu har jag skrivit klart bloggposten om javascript-biblioteket syntaxhl som jag avänder till att visa formatteringen i själva blogginläggen.
Nu till TinyMCE-pluggen som märker upp kodstyckena i databasen. Det heter syntaxhl finns att ladda hem på GitHub och går att läsa mer om hos skaparen Richard Grundy. Vid redigering ser det ut så här:

Som standard så omges koden med en textarea, något jag inte ville utan jag behövde en speciell uppmärkning för att fungera med den syntax-formatteraren jag valt. Hos Spencer Kellis hittade jag förklaring hur han hade gjort för att konfigurera TinyMCE med syntaxhl.
Först la jag syntaxhl i mappen plugin i TinyMCE. Sen modifierade jag syntax/js/dialog.js enligt följande för att få den uppmärkning jag efersträvade och inte textarea som den använder sig av som standard.
textarea_output = '<pre class="code">';
textarea_output += '<code class="' + f.syntaxhl_language.value + options + '">';
textarea_output += f.syntaxhl_code.value;
textarea_output += '</code></pre> ';
I databasen vill jag alltså att det ska sparas så här:
<pre class="code">
<code class="xhtml">
Testing the syntaxhl plugin for TinyMCE
</code>
</pre>
Så här ser mina inställningar nu:
<TinyMce:TextArea id="tbBody"
theme="advanced"
plugins="spellchecker,safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,pagebreak,syntaxhl"
theme_advanced_buttons1="spellchecker,save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,fontsizeselect|,forecolor,backcolor"
theme_advanced_buttons2="cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,preview,pagebreak,syntaxhl"
theme_advanced_toolbar_location="bottom"
theme_advanced_toolbar_align="left"
theme_advanced_path_location="bottom"
theme_advanced_resizing="false"
extended_valid_elements="pre[class]"
pagebreak_separator="<!--more-->"
force_br_newlines="false"
convert_newlines_to_brs="false"
preformatted="true"
apply_source_formatting="false"
remove_linebreaks="false"
Value='<%# Bind("Body") %>'
Rows="20"
runat="server" />
Ändingar jag gjort sen min förra konfiguration är dessa:
- Lagt till knappen för syntaxhl i plugin och i theme_advanced_button2.
- Lagt till pre[class] i extended_valid_elements för att editorn ska godkänna attributet.
- Satt force_br_newline och converty_newlines_to_brs till false.
- Satt preformatted till true.
TinyMCE har många konfigurationmöjligheter så det finns säkert mer saker att tweaka för ännu bättre resultat. Kolla även Spenser Kellis visar upp hur han har gjort sina inställningar.
Av Jesper Lind
191/2009
Något som jag måste bli bättre på är att markera oanvända kodstycken som Obsolete. Det innebär alltså att klassen helst inte ska användas längre och har tagit ett steg vidare mot avveckling. Man kan skriva ett meddelande också som kommer upp i kompilern som påminnelse för att man ska ta bort dem.
Exempel från MSDN.
[Obsolete("This class is obsolete; use class B instead")]
class A{
public void F() {}
}
Av Jesper Lind
151/2009
Ja då kör vi igång igen och nu på ny bloggmotor och ny fin design. Borde skriva ett långt och bra inlägg om bloggens utveckling hittills och allt det där, men orkar inte nu. Det har vart en lång natt med att brottas med de sista detaljerna inför lanseringen.
Vill passa på att tacka alla som vart inblandade i utveckligen av bloggmotorn. Erik, Johan (Har gjort designen ni ser nu), Glenn, Carl och Andreas. Kul att man har några galningar med sig som fortfarande känner för att bygga sin egen bloggmotor i dessa dagar då Wordpress regerar. Om ni är intresserade att använda bloggmotorn så ber vi er att kontakta oss genom Nodestar, där vi tar emot beställningar. Våren börjar bli fullbokad med för oss men vi kanske vi kan klämma in något projekt till om du är riktigt sugen.
För bloggen Code Odyssey så kommer vi fortsätta i samma spår och skriva om allt möjligt som är relaterat till webbutveckling, användarvänlighet, design, css, asp.net, c#, skriptbibliotek som jQuery med mera.
Det kommer nog även bli en hel del ASP.NET MVC också eftersom vi har jobbat med den plattformen under cirka sex månader och börjar få grepp på den. Den nya bloggmotorn är byggd på detta ramverk och det har varit en fröjd. Äntligen har vi användarvänliga url:er, snygg html-kod utan massa viewstate-bös och konstiga server-id. Bara ren html-kärlek.
Bloggen tänker vi förbättra successivt och lägga på nya funktioner. Bland annat göra om etiketterna till ett moln, lägga till Open-ID för kommentarerna, formattera kodexempel med färger för syntax och andra finesser. Givetvis kommer vi blogga om det under tiden så ni också kan få hjälp med hur man gör.
Så nu får det räcka på detta inlägget. Måste bara se hur RSS:en blir när jag postar. Den finns förresten på en ny adress, så prenumenera gärna på den. Den gamla ska fortfarande fungera.
Kommentera gärna så vi ser hur det fungerar och kom med input om vad ni tycker om förändringarna.
Av Jesper Lind
21/2009

Här på Code Odyssey har det inte hänt så mycket den senaste tiden p g a av några olika skäl. Framförall så har min egenutvecklade bloggmotor blivit något föråldrad och det är därför inte så kul att blogga här som det borde vara. Helt galet att den fortfarande körs på en Access-databas för att nämna en teknisk detalj.
Men nu är det dags att göra något åt detta och jag kommer under början av år 2009 försöka att importera all data till ett nyare system som vi har jobbat med. Vi kör en första version av detta på Nodestar om någon vill ha en förhandsgranskning.
Vi kommer även att använda det nya ramverket ASP.NET MVC som enligt Scott Guthrie kommer att släppas som release candidate i januari. Fördelarna är många och jag gillar verkligen att man får total kontroll över hur html rendereras. En bra routingmodell finnns inbyggd och äntligen kommer det bli användarvänliga url:er. Något jag viljat ha länge.
Vi har även fått en sponsringspartner som kommer stå för driften av bloggen, så det är riktigt roligt. Mer info om detta längre fram.
Nu ska jag läsa artikeln How to Restart a Dead or Dormant Blog för att få lite inspiration till om hur man kickar igång en blogg i dvala.
Så länge kan jag tipsa om ett besök på Martin Söderlunds blogg där det skrivs mycket flitigare.
Gott nytt år!
Bliden ovan på den sovanade statyn är lånad av användaren Trapac på Flickr.
Av Jesper Lind
411/2008
Något av det värsta som finns är att debugga Ajax-funktioner. AJAX Control Toolkit kan slänga ur sig en del väldigt konstiga felmeddelanden och de är inte lätta att lösa. Tänkte nu börjar dokumentera dem innan jag blir allt för galen.
Nyss fick jag detta i IE7:
Error: Sys.ArgumentNullException: Value cannot be null. Parameter name: element
På Firefox visas ett ändå mer förbryllande meddelande:
Sys.ArgumentNullException: Value cannot be null. Parameter name: element Sys$CultureInfo$_getAbbrMonthIndex("")ScriptRe...=15a6fa0c (line 6391) ScriptResource.axd?d=Mp3wOTv2U48tSwOzRbx9I5sb41bR8P9ogeRdPKRzZ5RBTNpXVRJNcEL9psPGosr4vyEbYVFfS05BUAtE2hlW2Q2&t=3004b210()()ScriptRe...=3004b210 (line 499) [Break on this error] this._upperAbbrMonths = this...s.dateTimeFormat.AbbreviatedMonthNames);
Googlade och började förstå att det hade med ModalPopupExtender att göra.
Min såg ut så här:
<ajaxToolkit:ModalPopupExtender ID="uxAddToProductModalPopupExtender" runat="server" TargetControlID="modaldummy" PopupControlID="uxAddToProductPanel" BackgroundCssClass="modalBackground" CancelControlID="uxCancelAddToProduct">
</ajaxToolkit:ModalPopupExtender>
Lite längre ner på sidan ligger knappen som visade sig vara boven i dramat.
<asp:Button runat="server" ID="uxCancelAddToProduct" Text="Stäng" Visible="false" />
Den var gömd med Visible="false" och skapade alltså null-exception i extendern. Sätter jag Visible till true få försvinner felet.
Av Jesper Lind
311/2008
Ja även fast det är spännande att jobba med nya databas-tekniker som LinqToSQL och Subsonic, så kan det vara bra att kunna lite hederliga DataSet-operationer.
Just nu så hade jag ett problem med Subsonics Paging-funktioner, där en Where-sats inte kom med. Jag fick dubbla poster hur jag än gjorde. Då kom jag på att jag kunde filtrera DataSet:et i efterhand och skrev följande lilla funktion.
private static DataSet FilterDataSet(DataSet ds,string filter)
{
DataSet clone = ds.Clone();
DataRow[] foundRows = ds.Tables[0].Select(filter);
for (int i = 0; i < foundRows.Length; i++)
{
DataRow row = foundRows[i];
clone.Tables[0].ImportRow(row);
}
return clone;
}
Anropar den sedan på följande vis. I detta fallet ville jag ha ut texter på en visst språk, och inte alla språk i databas-tabellen som Subsonic envisade sig med att returnera.
return FilterDataSet(q.ExecuteDataSet(),"Culture='sv-SE'");
Är du sugen på liknade exempel, så kan jag rekommendera tidigare inlägg där vi skrivit om hur man sorterar ett DataTable eller hur man skapar nya kolumner i DataSet och sparar det i Cacheminne.
Av Jesper Lind
<<Föregående
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Nästa>>