Posted Monday, July 5, 2010 6:54 PM by Frozzare | with no comments
Filed under:

 Tyvärr så kommer det vara dåligt med inlägg en längre tid då det är mycket annat på g. Jag får helt enkelt se när jag får tid att skriva igen!

Det börjar bli en djungel med podcaster, man kan inte följa all man skulle vilja. Men jag tänkte skriva vilka podcaster jag följer.

Det var nog dom podcaster jag följer aktivt nu, eller så ofta jag hinner. Lite jobbigt att hinna med en 1 timmes podcast på väg till plugget när det tar ca 30 min ;)

Uppdatera din rss länk till bloggen,  den nya till rss länken är http://feeds.feedburner.com/FredrikNetCsharp

I det tidigare inlägget skrev jag om hur man kunde skapa en HtmlHelper för att kunna visa senaste Twitter statusen för en användaren. I denna del tänkte jag ta upp hur man kan hantera flera användare och styra layouten lite lättare.

Vi utgår från tidigare inlägg, där vi har “TwitterStatus”, “FetchTwitterStatus” funktionerna. Vi börjar med att prata om hur vi kan hantera flera användare, till exempel att den skriver ut den första Twitter statusen från två olika användare.

I mappen “Models” så skapar vi en klass som heter “Users.cs”, i den skapar vi två klasser, “Users” och “Twitter”. Där “Twitter” ärver av “IEnumerable” som finns i namespacet “System.Collections”. “Users” klassen är väldigt simpel, ser ut såhär.

public class Users
{
public string TwitterAccount { get; set; }
}

Det är allt vi behöver “Users” klassen till. I klassen “Twitter” så skapar vi en privat ArrayList med namnet “twitterAccounts”.

public class Twitter : IEnumerable
{
private ArrayList twitterAccounts;

public Twitter()
{
twitterAccounts = new ArrayList();

twitterAccounts.Add(new Users { TwitterAccount = "Frozzare" });
twitterAccounts.Add(new Users { TwitterAccount = "Vimpyboy" });
}

public IEnumerator GetEnumerator()
{
return (twitterAccounts as IEnumerable).GetEnumerator();
}

}

Våran publika “Twitter” använder vi för att lägga till våra Twitter konton in i ArrayList “twitterAccounts” som vi skapade. “IEnumerator GetEnumerator()” samlar ihop all data, i detta fall twitterAccounts till en collection och returnerar allt som IEnumerable som används för att skriva ut saker till en View i ASP.NET MVC.

För att skriva ut våra användare med Html.TwitterStatus(int, string, bool), så går vi till en Controller klass, jag väljer “HomeController.cs”. Då lägger vi till “using DittProjekt.Models”, då får vi tillgång till våran Twitter klass.

public ActionResult Page()
{
return View(new Twitter());
}

Nu så behöver vi bara skriva “new Twitter()” inom “View” sedan högerklickar vi på våran kod och väljer “Add View”, då får vi upp denna ruta.

add-view-page

Där vi väljer vi våran “Twitter” klass som “View data class” sen så skapar vi sidan. Nu behöver vi importera två namespaces, “DittProjekt.Helpers” för att få fram våran TwitterStatus HtmlHelper från tidigare och “DittProjekt.Models” för att få fram “Users” klassen.

<% foreach (Users u in Model)
{%>
<%= Html.TwitterStatus(1, u.TwitterAccount, false) %>
<% } %>

Nu så skriver vi bara “foreache (Users u in Model)” som betyder för varje “u” användare i “Model” som är våran Twitter klass. Sedan är det bara att skriva “u.TwitterAccounts” som användarnamn i våran TwitterStatus HtmlHelper.

Nu ser vi att det kommer Twitter statusar från två olika användare. Nu tänkte jag prata vidare om hur vi kan hantera layouten lättare. Vi skapar en ny funktion, “TwitterStatusLink” som ser ut såhär

public static string TwitterStatusLink(this HtmlHelper helper, int numberOfMessages, string username, bool splitUserNameAndLink)
{
return TwitterHtml(FetchTwitterStatus(username, numberOfMessages).AsQueryable<Twitter>(), splitUserNameAndLink);
}

Det inte så konstigt ut? Vi kommer skapa funktionen “TwitterHtml” straxs. I klassen “Twitter” har jag lagt till en sträng för “Username”.

public string UserName { get; set; }

I funktionen “FetchTwitterStatus” har jag ändrat om lite i våran “foreache” loop som ser ut såhär nu

   foreach (XElement elm in children)
{
Twitter tw = new Twitter();
tw.Status = elm.Element("description").Value;
tw.DateDiff = DateTime.Parse(elm.Element("pubDate").Value).ToLongDateString();
tw.Link = elm.Element("link").Value;
string splitStatus = tw.Status.Remove(0, user.Length + 1);
        tw.UserName = tw.Status.Remove(user.Length + 1, splitStatus.Length);
        tw.Status = splitStatus; 
messages.Add(tw);
}

Det jag ändrat i “foreache” loopen är att vi delar på strängen och får ut användarnamnet den vägen så vi kan lägga till det i våran “IList<Twitter>”. Sedan ärver “tw.Status” den strängen vi delat på så vi får bort användarnament från statusen.  Notera att jag sätter “tw.Status” under “tw.UserName”.

public static string TwitterHtml(IQueryable<Twitter> source, bool splitUserNameAndLink)
{
foreach (var item in source)
{
if (splitUserNameAndLink)
return String.Format("{0} <a href=\"{1}\">{2}</a> - {3}", item.UserName, item.Link, item.Status, item.DateDiff);
else
return String.Format("<a href=\"{0}\">{1}</a> - {2}", item.Link, item.UserName + item.Status, item.DateDiff); ;
}

return string.Empty;
}

Inga konstigheter? Vi skickar in våran source, som är “FetchTwitterStatus”. Man behöver inte göra om den till “IQueryable” fungerar utmärkt att skriva “IList<Twitter> source” men jag tycker det är trevligare. Ni minns kanske “foreache” loopen från “TwitterStatus” funktionen, det är nästan samma. Skillnaden är att vi tagit bort “StringBuilder” då vi bara ska returnera en sträng. Vi har tagit bort “<ul>” listan då vi kommer lösa det på annat sätt. Vi behöver ha “return” som returnerar en tom sträng om inget i “foreach” loopen inte skulle returnera något.

Det kommer bli en liten skillnad på hur vi skriver ut detta nu.

<% foreach (Users u in Model)
{ %>
<%= Html.TwitterStatusLink(1, u.TwitterAccount, true) %>
<% } %>

twitter-5

Som ni ser på bilden så får vi ingen list formatering. Skulle vi vilja ha en “<ul>” lista så skriver vi det såhär

<ul>    
<% foreach (Users u in Model)
{ %>
<li><%= Html.TwitterStatusLink(1, u.TwitterAccount, true) %></li>
<% } %>
</ul>

twitter-4

På det här sättet kan vi styra layouten bättre.

ASP.NET MVC 2 RC2 släpptes igår och finns nu att ladda ner för Visual Studio 2008 hos Microsoft
Det verkar inte finnas något stöd för Visual Studio 2010 Beta 2 än.

ScottGu's blogg finns en bra beskrivning om ASP.NET MVC RC2 nyheter.

Detta är del ett av två inlägg.

Jag upptäckte i mitt tidigare inlägg hur användbart Htmlhelper var och därför bestämde jag mig för att göra en till. Nämligen en som hämtar det senaste Twitter status(ar) från din Twitter. Vi börjar med att skapa ett nytt ASP.NET 1 (2 Beta) projekt, skapar sedan en mapp som heter “Helpers” och där skapar vi en klass som vi döper till “Html.cs”.Varför vi inte döper den till “HtmlHelper.cs” är för att då kommer det krocka med “HtmlHelper.cs” som redan finns och som vi kommer använda oss av.

Vi får ändra våran Html klass till statisk, “public static class Html”. Vi skapar en statisk sträng som vi döper till “TwitterStatus”. Början av kodstycket ser ut såhär.

public static string TwitterStatus(this HtmlHelper helper, int numberOfMessages, string username, bool splitUserNameAndLink)
{
      StringBuilder sb = new StringBuilder();

sb.AppendLine("<ul>");
username = username.ToLower();

“numberOfMessages” är antal Twitter statusar vi vill visa, det går att visa mellan 0-20 stycken. “username” är alltså vårat användarnamn på Twitter. “splitUserNameAndLink” kommer jag till längre ner. Vi behöver inkludera namespacet “System.Xml.Linq” för att funktionen nedan ska fungera.

public static List<Twitter> FetchTwitterStatus(string username, int numberOfMessages)
{

string user = username;
var messages = new List<Twitter>();
string url = "http://twitter.com/statuses/user_timeline/" + user + ".rss";
try
{
var doc = XElement.Load(url);
var children = (from item in doc.Element("channel").Elements("item") select item).Take(numberOfMessages);

foreach (XElement elm in children)
{
Twitter tw = new Twitter();
tw.Status = elm.Element("description").Value;
tw.DateDiff = DateTime.Parse(elm.Element("pubDate").Value).ToLongDateString();
tw.Link = elm.Element("link").Value;
messages.Add(tw);
}
}
catch (Exception)
{
throw new ArgumentException("No twitter rss");
}
return messages;
}
public class Twitter
{
      public string Status { get; set; }
public string Link { get; set; }
public string DateDiff { get; set; }
}

Nu blev det mycket kod. Vi har alltså skapat en List<T> funktion, där <T> är klassen Twitter. Vi har våran “username” sträng från tidigare och “numberOfMessages”. Längre ner i kodstycket har vi en try {…}. Där vi laddar in våran xml fil, alltså Twitter rss. Med hjälp av Linq to XML så tar vi oss in en bit i xml upplägget och sen kan vi börja plocka ut det vi vill ha. I “foreache” loopen så plockar vi ut statusen, datumet och länken och lägger sedan till i våran “messages” lista som skapades tidigare.

Skulle den inte finna användaren eller något annat dyker upp. Så får vi ett fel “No twitter rss”. Då brukar det vara något fel på användarnamnet eller så är det något problem hos Twitter (vilket inte händer så ofta). Men skulle vi inte få något fel så returnar vi “messages” och får alltså ut det antal statusar vi vill.

Nu kan vi bygga klart våran funktion som vi höll på med.

     foreach (var item in FetchTwitterStatus(username, numberOfMessages))
{
if (splitUserNameAndLink)
{
string splitStatus = item.Status.Remove(0, username.Length + 1);
string userName = item.Status.Remove(username.Length + 1, splitStatus.Length);

sb.AppendLine(String.Format("<li>{0} <a href=\"{1}\">{2}</a> - {3}</li>", userName, item.Link, splitStatus, item.DateDiff));
}
else
{
sb.AppendLine(String.Format("<li><a href=\"{0}\">{1}</a> - {2}</li>", item.Link, item.Status, item.DateDiff));
}
}

sb.AppendLine("</ul>");

return sb.ToString();
}

Nu så kan vi komma tillbaks till “splitUserNameLink”, om den sätts till “true” så har jag gjort så att den tar bort användarnamnet från länken och skriver det före länken, Användarnamn: Länken till min status – datumet. Annars om den sätts till “false” så blir allt förutom datumet en länk till den statusen. När vi sedan har plockat ut allt från “FetchTwitterStatus” så kan vi returnar våran TwitterStatus HtmlHelper.

För att visa detta nu så lägger vi till “Import Namespace=”DittProjekt.Helpers””. För att sedan kunna skriva ut detta.

<%= Html.TwitterStatus(5, "användarnamn", true) %>

Där 5 är ett nummer mellan 0-20. Nu bör vi få ett resultat liknande detta:

Med “splitUserNameAndLink” satt till “true”

twitter-1-20100113

Med “splitUserNameAndLink” satt till “false”

twitter-2-20100113

Jag kommer göra en efterföljare på detta inlägg, där jag kommer ta upp mer om hur man kan arbeta med flera användarkonton och hur man gör det lättare att styra layouten.

För er som inte vet vad Gravatar är så är det en tjänst som sparar din “avatar” bild åt dig och en del bloggsystem har just Gravatar som tjänst för att visa “avatar” bilder.

Jag tänkte visa hur lätt det är att skapa en egen HtmlHelper funktion. Vi väljer att skapa ett nytt ASP.NET MVC 1 (2 Beta) projekt där vi sedan lägger till en mapp som heter “Helpers”. Där så skapar vi en ny klass som heter ”Html.cs” då HtmlHelper redan är en klass som vi kommer använda oss av så är det inge smart att döpa den till samma sak. Vi måste sätta dit “static” på våran klass, alltså “public static class Html”. Vi skapar lägger till denna kod snutt.

public static string Gravatar(this HtmlHelper helper, string email)
{
return GravatarImageHtml(gravatarUrl + getMd5Hash(email.ToLower()));
}

Detta är alltså våran HtmlHelper funktion, så när vi skriver <%= Html.Gravatar(“hej@dinadress.se”) %> kommer din Gravatar bild att renderas. GravatarImageHtml(url) är en public static string som retunerar en img html tag, där url:en är länken till Gravatar bilden som ska visas. “ToLower” betyder att vi gör alla bokstäver till små bokstäver, så ifall en e-postadress ser utsåhär: hej@DInAdResS.se så blir den hej@dinadress.se.

public static string GravatarImageHtml(string url)
{
return String.Format("<img src=\"{0}\" class=\"gravatar-image\" />", url);
}

Gravatar har md5hash som sitt filnamn till en bild, alltså hej@dinadress.se blir massor utav bokstäver och siffror. Därför behöver vi skapa en funktion som gör om e-postadressen till just detta.

 

public static string getMd5Hash(string input)
{
MD5 md5Hasher = MD5.Create();

byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

StringBuilder sb = new StringBuilder();

for (int i = 0; i < data.Length; i++)
{
sb.Append(data[i].ToString("x2"));
}

return sb.ToString();
}

För dom som vill läsa på om vad md5hash så finns det en bra länk här: http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx Vår “gravatarUrl” ser helt enkelt ut såhär.

private static string gravatarUrl = "http://www.gravatar.com/avatar.php?gravatar_id=";

Där “gravatar_id” är md5hash av våran e-postadress. Nu så går vi till våran View sida vi använda och lägger till “Import Namespace=”DittProjekt.Helpers”” sen kan vi bara skriva

<%= Html.Gravatar("hej@dinadress.se") %>

Nu så bör vi få ett resultat liknande detta.

gravatar_20100113

Jag tänkte hur man kommer igång med Bing kartor och Silverlight. Vi börjar med att hämta Silverlight 3 SDK (det går lika bra att använda Silverlight 4 SDK Beta) och Bing Maps Silverlight Control SDK. Vi behöver också besöka Microsofts webbplats, Bing Maps Account Center för att få en hemlig nyckel.

Vi väljer att skapa en ny Silverlight applikation. Man får en fråga om man vill lägga till en webbapplikation till våran Silverlight applikation, det är inget måste. Det går lika bra utan att lägga till en webbapplikation, då kommer programmet generera en .html sida när vi test kör våran applikation.

När vi skapat Silverlight applikationen så lägger vi till referenser till Microsoft.Maps.MapControl.dll som vi finner i “C:\Program\Bing Maps Silverlight Control\V1\Libraries\” (Program (x86) ifall du kör 64-bitar).

Nu när detta är gjort så kan vi lägga till en namespace i våran MainPage.xaml.

xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"

Nu börjar arbetet med att utforma koden för kartan. I våran Grid tagg så kan vi lägga till en m:Map för att visa kartan .

<m:Map CredentialsProvider="Din egna nyckel" </m:Map> 

Detta kommer nu visa Bing kart i din Silverlight applikation. Man kan lägga till Zoomlevel=”x” där x är så mycket du vill att kartan ska vara inzoomat.

Center=”x,x” ställer in vilken plats på kartan som ska visas när applikationen startas. Till exempel: Center="61.71816218644379, 17.33600065112114" som visar Sverige. Koordinaterna kan man hämta på Bing Maps och klicka på “Share your map”, ikonen ser ut som ett brev.

Det finns två lägen att visa kartan i. Det enda läget är “Road” och det andra är “Aerial”. Genom att skriva Mode=”Road” så kommer “Road” kartan visas när applikationen körs igång.

<m:Map CredentialsProvider="Din nyckel här" Mode="Road" ZoomLevel="5" Center="61.71816218644379, 17.33600065112114"> </m:Map> 

För att lägga till en kartnål så kan man skriva m:Pushpin inom m:Map taggen.

<m:Map ...>
<m:Pushpin Location="59.331959746778026, 18.062450140714645" />
</m:Map>

Där “59.331959746778026, 18.062450140714645” pekar på Stockholm. Den slutliga xamlkoden ser ut såhär.

<UserControl x:Class="SilverlightBingMapDemo1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="500" Width="700"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl">
<Grid x:Name="LayoutRoot" Background="White">
<m:Map CredentialsProvider="Din kod här" Mode="Road" ZoomLevel="5" Center="61.71816218644379, 17.33600065112114">
<m:Pushpin Location="59.331959746778026, 18.062450140714645" />
</m:Map>
</Grid>
</UserControl>

Det slutliga resultatet:

SilverlightBingMapDemo1

 

Lägger man till detta namespace så kan man aktivera så att den ska ignorera design höjden och bredden så man får kartan på hela fönstret.

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

Sen är det bara att lägga till mc:Ignorable=”d” i UserControl taggen.

Nu har årets första Msdn radio avsnitt släppts. Jag medverkade i en intervju som finns i det första Msdn radio avsnittet. Texten nedan har jag kopierat från Channel9 hemsida.

Välkommen till ett nytt år och till ett nytt fräscht avsnitt av MSDN Radio. Idag med Dag König och Danwei Tran.

Nedladdningar

Tess Corner

Länkar

Msdn radio avsnittet finner du på denna länk

More Posts Next page »