Codepolice

Random posts from Ola in English. Mainly about programming and the web.

Meek: The Reversed CMS for ASP.NET MVC

I have a totally custom made website called AlternativeTo. For a long time i’ve been looking for some kind of CMS that you can hook up to just small blocks on the site and just get those small blocks editable with some kind of CMS. I don’t know how common this need is but i would think it is. I have thought about buildning something myself but i was pretty sure that there must be someone out there that had the same problem before me, and why invent the wheel and so on.

Anyway, some days ago i finally found the solution and it’s called Meek. Meek was exactly what i described above. Extremely simple and it’s installed by just referencing a DLL and about 3-4 lines in web.Config. Well you can read all about it at their homepage.

I can also mention i had a small issue mostly because i have kind of a strange setup. I had to add the custom route because i didn’t have the default route in my Web.Config.

routes.MapRoute(
 "Meek", // Route name
 "Meek/{action}/{id}", // URL with parameters
 new { controller = "Meek", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

I also had to add the init line manually to my Application_Start method. I recorded a short video how it works on YouTube.

Link: Meek

Make the Git GUI appear after you publish a Web Project in Visual Studio 2010

A couple of moths ago i started to use GIT as my primary Source Control. To be honest I hadn’t use any “real” source control at all before for this project. I only used a online backup service that had some basic version control on a file to file basis.

But i love GIT. It’s really simple and everything works more or less exactly as you expect it to do. But there isn’t much tools out there that integrates well with Visual Studio. There is Git Extensions for Windows and there is a project called Git Source Control Provider. The problem with Git Extensions is that it doesn’t do that much. It only ads a menu in Visual Studio where you can execute some command. Git Source Control Provider on the other hand looked like the perfect tool for me. But for some reason it didn’t sync correctly with my Git Repository and i got the feeling the project was a bit to immature to be trusted.

I always forget to commit

So, my biggest problem is that I always forget to fire up the command line / GUI and actually commit the changes i do the code. When you use SVN, TFS you get those nice little icons on all the files in Visual Studio so you are constantly reminded of your changes. This was what Git Source Control Provider promised but as i said, didn’t work for me.

I would be happy just to be reminded every time i publish my website to the ftp that “Hey! Don’t forget to commit your changes!”. And just to be clear. This is a solution for a one man shop that don’t really need “continuous integration” and loads of complicated stuff. I like my super simple solution where i just publish my project to my ftp and boom done!

My stupid hack

I found this post on Stack Overflow that explains how to run a MS Build target after you do a publish from Visual Studio. You just have to add this target at the end of your .csproj file. Your publish method must be a “WebDeploy”. I tried with “File System” but that didn’t work. The “WebDeploy” method was much faster anyway.

<Target Name="CustomPostPublishActions" AfterTargets="MSDeployPublish" >
    <Exec Command="&quot;C:\Program Files (x86)\Git\bin\wish.exe&quot; &quot;C:\Program Files (x86)\Git\libexec\git-core\git-gui&quot;" />
</Target>

That’s more or less all there is to it. This will fire up the GIT GUI and your Publish task won’t finish until you close that program. Of course you could probably just run the console instead if you prefer that.

Signing a request to setup a custom Amazon CloudFront Distrubution with C#

I love most of Amazons Web Services (AWS). CloudFront is their CDN service and they have a awesome feature that lets you host your files on your own server and then Amazon automatically grabs the files from your server and put them on their CDN. This makes it possible to easily modify your files without having to download them from some S3 bucket or something to make changes.

Unfortunatley Amazon doesn’t provide a UI to set up a “Custom Distribution” so you have to do a post request to a URL and send them some XML. It’s maybe not that hard but i really think they could provide us with some simple page where you just paste some XML and sent the request. But you have to do it yourself. The only thing i had issues with was to sign the request and get your “encrypted” secret.

I found some code on Stack Overflow (as usually) and just made some small modification to it for doing a Cloud Front setup request.

public static void InvalidateContent() {
    string httpDate = Helper.GetHttpDate();
 
    string AWSSecret = "YOUR SECRET";
    string AWSAccessKeyId = "YOUR ACCESS KEY";
 
    ASCIIEncoding encoding = new ASCIIEncoding();
    string postData = @"<DistributionConfig xmlns='http://cloudfront.amazonaws.com/doc/2010-11-01/'>
        <CustomOrigin>
            <DNSName>dist.alternativeto.net</DNSName>
            <HTTPPort>80</HTTPPort>
            <HTTPSPort>443</HTTPSPort>
            <OriginProtocolPolicy>match-viewer</OriginProtocolPolicy>
        </CustomOrigin>
        <CallerReference>" + httpDate + @"</CallerReference>
        <CNAME>static.alternativeto.net</CNAME>
        <Comment>My comments</Comment>
        <Enabled>true</Enabled>
        <Logging>
            <Bucket>mylogs.s3.amazonaws.com</Bucket>
            <Prefix>myprefix/</Prefix>
        </Logging>
    </DistributionConfig>";
    byte[] data = encoding.GetBytes(postData);
 
    // Prepare web request...
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://cloudfront.amazonaws.com/2010-11-01/distribution");
    webRequest.Method = "POST";
    webRequest.ContentType = "text/xml";
    webRequest.Headers.Add("x-amz-date", httpDate);
 
    Encoding ae = new UTF8Encoding();
    HMACSHA1 signature = new HMACSHA1(ae.GetBytes(AWSSecret.ToCharArray()));
 
    string b64 = Convert.ToBase64String(signature.ComputeHash(ae.GetBytes(webRequest.Headers["x-amz-date"].ToCharArray())));
 
    webRequest.Headers.Add(HttpRequestHeader.Authorization, "AWS" + " " + AWSAccessKeyId + ":" + b64);
 
    webRequest.ContentLength = data.Length;
 
    Stream newStream = webRequest.GetRequestStream();
    // Send the data.
    newStream.Write(data, 0, data.Length);
    newStream.Close();
}
 
/// <summary>
/// Gets a proper HTTP date
/// </summary>
public static string GetHttpDate() {
    // Setting the Culture will ensure we get a proper HTTP Date.
    string date = System.DateTime.UtcNow.ToString("ddd, dd MMM yyyy HH:mm:ss ", System.Globalization.CultureInfo.InvariantCulture) + "GMT";
    return date;
}

 

IsolatedStorage on Windows Phone 7 error

I’m playing around with the new Windows Phone 7 SDK and today i run into an issue with the “IsolatedStorage” thing that is used to store some data like settings and stuff.

Anyways my designer in Visual Studio complained that it could not render my User Control that used an instance of the Isolatedstorage object.

Unable to determine application identity of the caller.

I found some forum thread and it turned out i just had to add this and it seems to work fine again.

if (!System.ComponentModel.DesignerProperties.IsInDesignTool) {
.. your isolatedstoragecode
}

I should add that i never had any issues while running the app in the emulator.

Refresh a Updatepanel from Javascript causing a full refresh

One big advantage of using ASP.NET Webforms is features such as  the updatepanel. The updatepanel is awesome for admin UIs and things like that where you doesn’t care about performance or pretty markup.

Today i wanted to refresh a updatepanel via JavaScript and after a quick session on Google i found this article by Encosia (Encosia is the no1 resource for asp.net developers who wants to use jQuery and JavaScript in thier webforms apps btw). This article explained how to easily refresh a updatepanel via JavaScript by just calling.

__doPostBack('updYourUpdatePanel', '');

From your .js file. But when i tried this it simply didn’t work. The page did a full refresh and i was confused. Then i realized that my Updatepanel wasn’t named ‘updYourUpdatePanel’ anymore since Webforms renamed it with a generated ID. Since i use Webforms 4.0 i could just add the new ClientIDMode attribute.


And it worked. If you have no control of the ID you have to view source or use <%= updYourUpdatePanel.UniqueID %>.

IN queries with LINQ to SQL

This is another awesome feature in LINQ to SQL that i always forget about. Sometimes you have an array of strings or any other type and want to query the database for all values that have one of the values in the array.

string platform = "windows|linux";
string[] platformList = platform.Split('|');
itemQuery = from m in itemQuery
from p in m.PlattformItemRelations
where platformList.Contains(p.Plattform.Text.ToLower())
select m;

Ain’t that a beauty? I got this tip from Ron Connery so all the kudos to him.

Create a comma separated list with LINQ in C#

For some reason I always forget that you do not do .Join on your actual string array. So i might as well write it down here so i never forget about this again.

string mycommalist = string.Join(",", alternatives.Select(x=>x.Item.Name).ToArray())

Convert String Array to Int Array and vice versa in C#

Sometimes you want to convert arrays back and forth. This is to nice extension methods to convert a int array into a string array and vice versa.

public static class ExtensionMethods {
 
  public static string[] ToStringArray(this int[] intArray) {
   return Array.ConvertAll&lt;int, string&gt;(intArray, delegate(int intParameter) { return intParameter.ToString(); });
  }
 
  public static int[] ToIntArray(this string[] strArray) {
   return Array.ConvertAll&lt;string, int&gt;(strArray, delegate(string intParameter) { return int.Parse(intParameter.ToString()); });
  }
}

file_get_contents() in asp.net/C#

The URL shortening service http://bit.ly has a really simple and convient API that lets just get a short url like this.

http://bit.ly/api?url=http://www.myreallylong.com/url/with/lots?of=crap

I’ve used this in a wordpress installation with PHP before and there i could just do.

$twitter_url .= file_get_contents('http://bit.ly/api?url=' . get_permalink());

Simple and clean. But today i wanted to do the same thing with asp.net and found myself kind of lost. At last i came up with this, not as simple solution. But it works.

string shortUrl = new StreamReader(WebRequest.Create("http://bit.ly/api?url=http://fragor.ohsohightech.se" + Url.Action("Question", new { number = question.Number, title = question.Title.ConvertTextToUrl() })).GetResponse().GetResponseStream()).ReadToEnd();

ASP.NET membership: System.Web.Security. SqlRoleProvider problems

I had this really weird problem just now. I have done some work with the ASP.NET Membership provider and everything has been working great. But when i tried to deploy my application to the server i got this:

The ‘System.Web.Security.SqlRoleProvider’ requires a database schema compatible with schema version ’1′. However, the current database schema is not compatible with this version. You may need to either install a compatible schema with aspnet_reqsql.exe (available in the framework installation directory), or upgrade the provider to a newer version.

Alright, my database was exactly the same and everything looked fine. I tried to recreate my database with the aspnet_regsql.exe tool but nothing worked. Then i finally found this thread on the MSDN messageboard and one guy said that he gave his application a name in the aspnet_Applications table and put that name in the web.config like this.


And that solved it. Really really strange and i have no idea if this is a bug or whatever. On my local machine (Vista with IIS7) it worked great to have a application named “/” but on my production machin (a Server 2003 with IIS6) it did not.

Now i should stop working for today.