No Free Time

Because my therapist says I need to let things out

Archive for the ‘.net’ Category

Naming Your Action Methods in ASP.Net MVC

Posted by andrewmyhre on November 24, 2009

Something that I always do now and might in fact be quite obvious to regular people but I’m quite slow so it took me a little while to realise this was a good practise.

Let’s say I have a page for editing a blog post. I want the form to be at /BlogManagement/Edit/postId.

So I write my first action method:

[Authorize(Roles = "administrator")]

 

public ActionResult Edit(int ID)

And here’s what the URL looks like in my browser:

Cool. Now I write the method for the edit form view to post to:

public ActionResult UpdateBlogPost(FormCollection formData)

{

}

This will work of course. But what happens if validation fails? We get send back to the edit form. But we don’t want to redirect, we’ll just return the appropriate view and viewdata. So what will the URL be now?

Oh dear. That’s no good at all. Now our visitors have this erroneous entry in their history. No, this will not do.

To tidy this up we’ll make use of method overloading and the AcceptVerbs action method attribute. Here’s the signature of the GET action method which displays the edit form view:

[AcceptVerbs(HttpVerbs.Get)]

[Authorize(Roles = "administrator")]

public ActionResult Edit(int ID)

{

and here’s the signature of the POST action method that validates, updates and redirects:

[ValidateInput(false)]

[AcceptVerbs(HttpVerbs.Post)]

[Authorize(Roles = "administrator")]

public ActionResult Edit(FormCollection formData)

{

This works because the ASP.Net MVC routing engine understands method overloading and, providing you are using the AcceptVerbs attribute, it will route each request to the appropriate method.

Doing this will make sure that the URL in the browser stays the same during the whole process. Much neater, no?

Posted in .net, mvc | Tagged: , , | 1 Comment »

My Current log4net Setup

Posted by andrewmyhre on November 24, 2009

Because I’m waaaaay interested in logging, tracing, diagnostics, analytics – basically, what’s going on with my shit – I spent some time today tweaking our log4net configuration here at work. The actual motivation for sitting down and doing this was that I wasn’t getting any notification from uncaught exceptions in our sites, and I saw a couple in the event log on our live box. Naturally I flew into a blind rage and immediately set up an SmtpAppender for the existing log4net config for that site. After an hour or so I have a configuration that I like, so here it is.

I added two things:

  • Split configuration files so we can drop a new log4net configuration into a site without worrying too much about the main web.config
  • SmtpAppender for any log messages at WARN level or above

Here’s the template web.config file with the log4net configSource attribute:

<?xml version=1.0?>

<!–

Note: As an alternative to hand editing this file you can use the

web admin tool to configure settings for your application. Use

the Website->Asp.Net Configuration option in Visual Studio.

A full list of settings and comments can be found in

machine.config.comments usually located in

\Windows\Microsoft.Net\Framework\v2.x\Config

–>

<configuration>

<configSections>

<section name=log4net type=log4net.Config.Log4NetConfigurationSectionHandler,Log4net/>

</configSections>

<log4net configSource=log4net_debug.config />

<!–

log4net debugging

if debugging log4net uncomment this line to specify a file output for trace messages

<system.diagnostics>

<trace autoflush=”true”>

<listeners>

<add

name=”textWriterTraceListener”

type=”System.Diagnostics.TextWriterTraceListener”

initializeData=”log4net.txt” />

</listeners>

</trace>

</system.diagnostics>

–>

</configuration>

The debug log4net config file:

<log4net debug=true>

<logger name=default>

<level value=INFO/>

<appender-ref ref=LogFileAppender/>

</logger>

<appender name=LogFileAppender type=log4net.Appender.RollingFileAppender>

<param name=File value=log.txt/>

<param name=AppendToFile value=true/>

<rollingStyle value=Size/>

<maxSizeRollBackups value=10/>

<maximumFileSize value=1KB/>

<layout type=log4net.Layout.PatternLayout>

<conversionPattern value=%-5p %logger %d{yyyy-MM-dd hh:mm:ss} – %m%n/>

</layout>

</appender>

<!–

<appender name=”SmtpAppender” type=”log4net.Appender.SmtpAppender”>

<to value=”[admin email address]” />

<!– noreply@websiteurl –>

<from value=noreply@websiteurl />

<!– EXCEPTION:[environment]:[Website name] –>

<subject value=EXCEPTION:[environment]:[Website name] />

<!–

smtp servers

live: localhost

staging: TEQ-STG01

–>

<smtpHost value=[smtp server] />

<bufferSize value=512 />

<lossy value=true />

<evaluator type=log4net.Core.LevelEvaluator>

<threshold value=WARN/>

</evaluator>

<layout type=log4net.Layout.PatternLayout>

<conversionPattern value=%newline%date [%thread] %-5level %logger [%property{NDC}] – %message%newline%newline%newline />

</layout>

</appender>

–>

<root>

<level value=ALL/>

<appender-ref ref=LogFileAppender />

<!–

<appender-ref ref=”SmtpAppender”/>

–>

</root>

</log4net>

And the release log4net config file:

<log4net debug=false>

<logger name=default>

<level value=WARN/>

<appender-ref ref=LogFileAppender/>

</logger>

<appender name=LogFileAppender type=log4net.Appender.RollingFileAppender>

<param name=File value=log.txt/>

<param name=AppendToFile value=true/>

<rollingStyle value=Size/>

<maxSizeRollBackups value=3/>

<maximumFileSize value=1KB/>

<layout type=log4net.Layout.PatternLayout>

<conversionPattern value=%-5p %logger %d{yyyy-MM-dd hh:mm:ss} – %m%n/>

</layout>

</appender>

<appender name=SmtpAppender type=log4net.Appender.SmtpAppender>

<to value=[admin email address] />

<!– noreply@websiteurl –>

<from value=noreply@websiteurl />

<!– EXCEPTION:[environment]:[Website name] –>

<subject value=EXCEPTION:[environment]:[Website name] />

<!–

smtp servers

live: localhost

staging: TEQ-STG01

–>

<smtpHost value=[smtp server] />

<bufferSize value=512 />

<lossy value=true />

<evaluator type=log4net.Core.LevelEvaluator>

<threshold value=WARN/>

</evaluator>

<layout type=log4net.Layout.PatternLayout>

<conversionPattern value=%newline%date [%thread] %-5level %logger [%property{NDC}] – %message%newline%newline%newline />

</layout>

</appender>

<root>

<level value=WARN/>

<appender-ref ref=LogFileAppender />

<appender-ref ref=SmtpAppender/>

</root>

</log4net>

I’ll be suggesting that this configuration is adopted as standard for all new builds and I’ll go and reconfigure a few of our other active sites too.

Posted in .net, logging | Tagged: , , | Leave a Comment »

Handling Exceptions in ASP.Net MVC 1

Posted by andrewmyhre on November 20, 2009

Here’s a handy way to handle uncaught exceptions in ASP.Net MVC 1.

Make a base controller with the following code:

public class BaseController : Controller

{

ILog log = LogManager.GetLogger(“BaseController”);

string actionName = “”;

string controllerName = “”;

protected override void OnActionExecuting(ActionExecutingContext filterContext)

{

base.OnActionExecuting(filterContext);

actionName = filterContext.ActionDescriptor.ActionName;

controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;

}

protected override void OnException(ExceptionContext filterContext)

{

log.Fatal(“Unhandled Exception”, filterContext.Exception);

//Displays a friendly error, doesn’t require HandleError

filterContext.ExceptionHandled = true;

this.View(“Error”, new HandleErrorInfo(filterContext.Exception, controllerName, actionName)).ExecuteResult(this.ControllerContext);

}

}

Then make your other controllers derive from this one and hey presto, friendly(er) error messages and better exception logging in your site.

Sources:

http://geekswithblogs.net/SanjayU/archive/2009/11/09/error-handling-in-asp.net-mvc-1-part-2-of-2.aspx

http://stackoverflow.com/questions/362514/asp-net-mvc-current-action

 

 

Posted in .net | Tagged: , , | Leave a Comment »

Providing custom ‘no-Silverlight’ UI using Silverlight Streaming

Posted by andrewmyhre on June 12, 2009

When building and hosting your own Silverlight application it’s pretty simple to provide whatever custom UI you want when a user doesn’t have a required version of Silverlight installed. Refer to Tim Heuer’s article on the subject: http://timheuer.com/blog/archive/2008/03/25/creating-a-great-silverlight-deployment-experience.aspx.

When using Silverlight Streaming, however, it’s not that simple. The two methods provided for embedding your Silverlight application don’t provide a neat space to put your own HTML so you can’t easily ‘own’ the experience.  In my case I used the iFrame solution because I couldn’t get the other method to work straight away.

What I did to get around this was to download the latest Silverlight.js from here: http://code.msdn.microsoft.com/silverlightjs, and the latest JQuery from here: http://docs.jquery.com/Downloading_jQuery#Current_Release.

Reference both scripts from your web page and then add the following script:

$(document).ready(function() {
if (Silverlight.isInstalled(‘2.0.30226.2′) == true) {
showSilverlight();
}
else {
showCopy();
}
});
$(document).ready(function() {
    if (Silverlight.isInstalled('2.0.30226.2') == true) {
        showSilverlight(); // function to display the iframe & hide the default copy
    }
    else {
        showCopy(); // function to hide the iframe & show the default copy
    }
});

And that’s it!

Note: there’s a comment on the silverlight.js download page that the script links to an older version of the silverlight player. It seems to be correct but even when I updated my script file I still got the ‘older version of Silverlight’ message when using Chrome. Also I don’t know yet whether the experience works on a Mac – if anyone can let me know I’d really appreciate it!

Posted in .net, silverlight | Tagged: | Leave a Comment »

Create a list in a SharePoint site programmatically

Posted by andrewmyhre on March 21, 2009

Creating a list programmatically might be handy when you need to do this in a web part or, if you’re in the situation I was in today, you need to create a list where the template is not available on the Create page.

In my case I had a Collaboration site but I needed to create a Discussion Board – impossible using the SharePoint UI. How to get around this?

The first solution that occurred to me, and what I assumed I HAD to do, was to create a custom site definition. I had no idea how to go about doing this so this was a daunting prospect. But it occurred to me that, ultimately, I’ll only need to do this one time, maybe twice, and my users will never do this. So why go to all that trouble when the purpose of a site definition is to create a repeatable story for your end users? All I needed was a one shot hack.

So I remembered the SharePoint object model, and wrote an app. This app takes three arguments – Site URL, List Name, List Template ID. I used it to create a new discussion board in my site, it’s repeatable enough for my purposes, and it took me 5 minutes to write.

The code is provided below, but I want to hit home the point of this post – SharePoint is not as difficult as you think. There is always a simple way to do what you want to do. The difficulty is remembering to think outside the UI. I used to think that where SharePoint build was concerned I’d have to get used to telling customers ‘No’ but, as it turns out, that’s not that case at all.

CreateList.exe Source

1 using System;

2 using System.Collections.Generic;

3 using System.Linq;

4 using System.Text;

5 using Microsoft.SharePoint;

6

7 namespace CreateList

8 {

9 class Program

10 {

11 static void Main(string[] args)

12 {

13 if (args.Length == 0)

14 {

15 PrintListTemplates();

16 return;

17 }

18

19 bool validArgs = true;

20 if (!Uri.IsWellFormedUriString(args[0], UriKind.Absolute))

21 {

22 Console.WriteLine(“Arg 0 must be an absolute Sharepoint site URL e.g: http://mysite.com”);

23 validArgs = false;

24 }

25

26 int templateId=0;

27 if (!int.TryParse(args[2], out templateId))

28 {

29 Console.WriteLine(“Arg 2 must be a valid list template id from the following list:”);

30 validArgs = false;

31 PrintListTemplates();

32 }

33 if (!validArgs)

34 {

35 Console.WriteLine(“Invoke with no arguments to get a list of available SharePoint List templates”);

36 return;

37 }

38

39

40 Uri siteUrl = new Uri(args[0]);

41 string listName = args[1];

42

43 AddListToSite(siteUrl, listName, templateId);

44 }

45

46 private static void AddListToSite(Uri siteUrl, string listName, int SPListTemplateTypeId)

47 {

48 using (SPSite site = new SPSite(string.Format(“{0}”, siteUrl)))

49 {

50 SPWeb web = site.OpenWeb();

51 Guid listGuid = web.Lists.Add(listName, “”, (SPListTemplateType)SPListTemplateTypeId);

52 SPList list = web.Lists.GetList(listGuid, true);

53 }

54 }

55

56 private static void PrintListTemplates()

57 {

58 string[] typeNames = System.Enum.GetNames(typeof(SPListTemplateType));

59 Array typeValues = System.Enum.GetValues(typeof(SPListTemplateType));

60

61 int j = 0;

62

63 foreach (int i in typeValues)

64 {

65 Console.WriteLine(typeNames[j++].ToString() + ” “ + i.ToString());

66 }

67 }

68 }

69 }

Posted in .net, moss 2007, sharepoint | Tagged: , , | 1 Comment »

Explanation for a weird Visual Studio 2008 Silverlight 2 issue

Posted by andrewmyhre on January 22, 2009

I ran into a weird and annoying Silverlight/Visual Studio quirk today which cost me a little bit of time to work out the cause of, so here’s my story in case it helps anyone else out.

If you’re building a Silverlight Page/UserControl and you run it and instead of seeing your lovely application appear you see something like this:

 

 

(line 1, col 26): Unknown attribute xmlns on element WallContentView”]weird error

Sys.InvalidOperationException: Invalid XAML for control 'Xaml1'. [

 

And you notice in the XAML where you have included your control some blue lines:

 

 

021

 

And when you place your mouse cursor over the lines you see something incomprehensible, like this:

 

 

“]031

AG_E_UNKNOWN_ERROR [Line: 49 Position: 51

 

I did today. After trying essentially random and arbitrary things to solve the issue (deleting and recreating the control, renaming the control, removing sections of XAML and code from the control) I finally narrowed it down to this:

 

 

041

 

In my constructor I was causing an null reference error, but it was being reported as a XAML error! How bloody confusing.  And the reason this didn’t twig immediately is that I didn’t realise the XAML editor actually creates instances of the control tree and invokes the constructors of the controls in the process. Never occurred to me before, but makes total sense.

Anyway, so I fixed my code:

051

 

Rebuilt the solution and checked the containing control’s XAML:

061

 

No more blue lines – nice. Finally I ran my test page and lo and behold it worked!

Posted in .net, silverlight, visual studio 2008, xaml | Tagged: , , , | Leave a Comment »

The Sharepoint Development Experience – Part 1

Posted by andrewmyhre on January 15, 2009

I want to describe the development process involved in creating a web part for a Sharepoint site, hopefully to dispel the belief that it’s difficult and time-consuming. What I want to demonstrate is that it’s actually very simple – no more difficult than creating a custom control in ASP.Net 2.0 – provided you have set up your development infrastructure correctly.

Development infrastructure is where most of the pain associated with Sharepoint development really exists, which is why following this article I’m going to continue with a series describing how you can set up the various parts of your infrastructure to enable friction-free development.

This post, however, will show you exactly how friction-free it can be. I’m going to show the steps to build a basic web part and deploy it to your sharepoint solution in a repeatable and reversible way. I’ll also give a tour of how to customise the look-and-feel of a Sharepoint website using the Sharepoint designer. The purpose of this is show to illustrate that developing with Sharepoint isn’t really that much different to developing for a standard ASP.Net 2.0-based website.

Development

Watch me create and deploy a brand new web part to a Sharepoint server:

1. This is my out of the box Publishing Site template
01 

2. I’m going to add a web part to my site by adding a new class to my visual studio project
02

3. My class must inherit from Microsoft.SharePoint.WebPartPages.WebPart. I’m going to override the Render method to make the web part output some text. Note how similar this is to an ASP.Net custom control.
03

4.  I build the project. A post-build step creates a CAB file which can be deployed to Sharepoint. This packages up my new features/webparts so that I can manage their usage within Sharepoint and easily repeat/reverse this deployment process.
04

5.  I run a script to deploy the CAB file to Sharepoint. 
05 

6. In Sharepoint I add the Web Part to a page. If I haven’t deployed this web part before I need to Import the web part from the Site Settings menu first.
06 

7. And there it is!
07 

This development process is so simple and repeatable, it’s just like a standard ASP.Net website. What’s more when I set up source-control for my visual studio solution I can set up a continuous integration environment to automatically deploy my changes for me.

Layouts

Now I’m going to change the layout for this page. Most developers seem to believe this is an almost impossible task, or at least much more painful than editing a regular ASP.Net 2.0 Web Forms page. Well, watch:

1. My page layout
08 

2. I open up Sharepoint Designer and browse to the page I want to edit and double click. Sharepoint Designer asks me if I want to edit the content for the page or the layout for the page. I select layout. Here’s what I see:

09

There are a lot of controls on the page. Most of them have the prefix SharePointWebControls, so we can pretty easily see what they’re doing and we don’t have to be afraid. Otherwise this is just like a standard ASP.Net Web Forms page – it has stuff inside ContentPlaceHolder controls. Sharepoint assigns this page layout a master page at runtime.

3. See those ugly tables in the PlaceHolderMain ContentPlaceholderControl? I’m going to change those to divs:

 10

4. And now I’m going to edit the master page for this page layout. I know that the master page I want to edit happens to be BlueBand.master, because I chose it within the SharePoint Site Settings menu. And I also know that all master pages can be found in /catalog/masterpage in SharePoint Designer. I’ll change the tables there to divs too.
12 

5. I check-in the changes to these files (SharePoint automatically provides versioning on these files because they’re actually in the SharePoint database – more on that in another post) and reload my site homepage:
13 

Not such a visually impressive example, I know, but I just wanted to demonstrate that editing a SharePoint website isn’t really that different to building an ASP.Net website, and it’s no more difficult.

In future posts I’m going to walk through how to set up the infrastructure to be able to enjoy the development experience I demonstrated in the first section, and I also hope to demonstrate some ways to make layout editing more enjoyable, like by removing as much of the .Net cruft as possible and make your pages generate something more like semantic markup.

Posted in .net, moss 2007, sharepoint | 2 Comments »

ALT.Net Beers Tonight at Tequila

Posted by andrewmyhre on January 12, 2009

A reminder that ALT.Net Beers is tonight at the bar in the Tequila London building.

Question/comment here or contact me or Seb on Twitter.

Beer and pizza will be supplied, cheap but not free I’m afraid. £2 beers though – better than a poke in the eye, no?

Seb’s post with more information about format and stuff.

Posted in .net, alt.net, community events | Leave a Comment »

Digital Wall – redux

Posted by andrewmyhre on November 20, 2008

I posted last week about the release of Digital Wall to the internet – the application that lets you graffiti on our office wall from your browser. Well I was so pleased with how it performed that I scrapped the entire codebase and started again from scratch. Mostly I did it because the original version was the first time I had played with Silverlight, WPF and WCF, so I realised there was a lot that I would do differently a second time around which would make adding cool features easier. So I did it, and I added some cool features.

The new version is up at http://wall.tequila-uk.com. A number of things are different:

 

  • I can now write a welcome message on the server which will appear in your browser. I can write the welcome message in XAML. I do that using Mike Snow’s excellent tip for loading XAML into a control at runtime.
  • As well as drawing on the wall, you can now add images to it. You have two options for doing this – upload an image from your hard-drive, or provide a link to an image on the internet. Then you get to drag the image around and scale it as you desire. When you’re happy with it just click the Send button or switch to the Brush mode to have the image sent to the server.
  • The webcam is still pretty poor, so the Silverlight client will now download the server’s representation of the wall as objects and display it in your browser, overlayed on top of the stream. You can adjust the transparency of the overlay by clicking the button at the bottom of the toolbar. There are three settings: off, transparent and opaque. This way you can draw moustaches and fake wangs on people much more easily.
  • You can identify yourself (this is optional) and see who else is using the wall at the bottom-right corner of the screen.

 

And of course the wall is publishing canvases out through a number of different channels:

 

 

Previous posts: Digital Wall Goes Public, Digital Wall (provides a video demonstrating what it basically does)

To talk to me about the wall you can message me on Twitter.

Enjoy!

Posted in .net, Digital Wall, silverlight | Tagged: , , , , | Leave a Comment »

Digital Wall Goes Public

Posted by andrewmyhre on November 11, 2008

You can now draw on the wall yourself! Go here to try it out: http://wall.tequila-uk.com/

I explained concept in my previous post, but in a nutshell you can graffiti on one of the walls in our office. Like, the actual wall. Eventually I want to set this up somewhere more interesting, like in our reception area, but there are some logistical issues with that so for now it’s just in the office.

Screen captures are being published via TwitPic, so you can keep up in various ways:

Twitter: http://twitter.com/DigitalWall

TwitPic: http://www.twitpic.com/photos/DigitalWall

RSS: http://feeds.feedburner.com/DigitalWallPhotoStream

There are a couple of obvious things that still kinda, well, suck.

1. You can hardly see what’s on the wall via the webcam feed. This is because we’re just using a £5 logitech quickcam, and because the wall itself is in our office under halogen lights.

2. When you add something to the wall it takes a good 30 seconds before you see it in the webcam feed. I had thought this was because the camera feed was too high-bandwidth, but I’ve done a load of tweaking and I’m convinced now it’s simply because of the latency between our office, StreamWebTown and the browser. Whatever you draw shows up on our wall immediately, trust me.

We’re looking at ways to improve it, but at the moment it seems making it really good will take cash. Unfortunately, because this is just pure folly, it probably won’t improve.

Anyway, enjoy.

Posted in .net, Digital Wall, silverlight | Tagged: , , , | 1 Comment »