IBlog<Johan>

This and that in a developer's life in general

News

Follow johandanforth on Twitter

Random Links

Walkthroughs and Tutorials

Center Aligning a Table with CSS

So you want to center align a table, try text-align: center and it doesn’t work…. I have to look this up every time, so here goes:

<

table style="margin-left: auto; margin-right: auto;">

This is because text-align applies to inline content, not to a block-level element like a table and this article describes it in detail:

 http://www.granneman.com/webdev/coding/css/centertables/

Thanks Scott Granneman for the detailed article.

Binding MediaElement to a ViewModel in a Windows 8 Store App

If you want to play a video from your video-library in a MediaElement control of a Metro Windows Store App and tried to bind the Url of the video file as a source to the MediaElement control like this, you may have noticed it’s not working as well for you:

<MediaElement Source="{Binding Url}" />

I have no idea why it’s not working, but I managed to get it going using  ContentControl instead:

<ContentControl Content="{Binding Video}" />

The code behind for this is:

protected override void OnNavigatedTo(NavigationEventArgs e)

{

    _viewModel = new VideoViewModel("video.mp4");

    DataContext = _viewModel;

}

And the VideoViewModel looks like this:

public class VideoViewModel

{

    private readonly MediaElement _video;

    private readonly string _filename;

 

    public VideoViewModel(string filename)

    {

        _filename = filename;

        _video = new MediaElement { AutoPlay = true };

        //don't load the stream until the control is ready

        _video.Loaded += VideoLoaded;

    }

 

    public MediaElement Video

    {

        get { return _video; }

    }

 

    private async void VideoLoaded(object sender, RoutedEventArgs e)

    {

        var file = await KnownFolders.VideosLibrary.GetFileAsync(_filename);

        var stream = await file.OpenAsync(FileAccessMode.Read);

        _video.SetSource(stream, file.FileType);

    }

}

I had to wait for the MediaElement.Loaded event until I could load and set the video stream.

Posted: Dec 14 2012, 03:07 PM by jdanforth | with 3 comment(s)
Filed under: ,
File Activation in Windows RT

The code sample for file activation on MSDN is lacking some code Winking smile so a simple way to pass the file clicked to your MainPage could be:

protected override void OnFileActivated(FileActivatedEventArgs args)

{

    var page = new Frame();

    page.Navigate(typeof(MainPage));

    Window.Current.Content = page;

 

    var p = page.Content as MainPage;

    if (p != null) p.FileEvent = args;

    Window.Current.Activate();

}

And in MainPage:

public MainPage()

{

    InitializeComponent();

    Loaded += MainPageLoaded;

}

void MainPageLoaded(object sender, RoutedEventArgs e)

{

    if (FileEvent != null && FileEvent.Files.Count > 0)

    {

        //… do something with file

    }

}

Posted: Nov 23 2012, 11:57 AM by jdanforth | with 1 comment(s)
Filed under: , , , , ,
Read All Text from Textfile with Encoding in Windows RT

A simple extension for reading all text from a text file in WinRT with a specific encoding, made as an extension to StorageFile:

public static class StorageFileExtensions
{
    async public static Task<string> ReadAllTextAsync(this StorageFile storageFile)
    {
        var buffer = await FileIO.ReadBufferAsync(storageFile);
        var fileData = buffer.ToArray();
        var encoding = Encoding.GetEncoding("Windows-1252");
        var text = encoding.GetString(fileData, 0, fileData.Length);
        return text;
    }
}

Posted: Nov 21 2012, 03:53 PM by jdanforth
Filed under: , ,
Sideloading and Testing Windows 8 Store Apps on Other Machines

This is a good, short article how to create a store app package and test on another machine, see http://blog.aggregatedintelligence.com/2012/11/how-to-sideload-windows-8-store-apps.html

Posted: Nov 20 2012, 02:32 PM by jdanforth | with 1 comment(s)
Filed under: ,
How to do Custom Event Logging and Trace Writing in Azure

We’re about to begin our first “real” Azure project and I needed to wrap my head around event logging and trace writing in the cloud. Any proper application running in any cloud needs this sooner or later.

I quickly noticed that the information around Azure diagnostics was all over the place, and some things seems to have been changed in newer versions of the Azure SDK. So, something I thought was going to take me just a few minutes to figure out took about a day, but I think I got it sorted in the end and here’s what I did to get simple event logging and trace writing to work for our web role.

First thing I had to understand was how data for all kinds of diagnostics is handled and stored in Azure. You need to define which kinds of diagnostics data you want to capture, and you need to define where Azure should transfer the data captured so that you can download them or look at then with various tools. You also need to define how often these values should be transferred. I’ll get back to that a bit later.

Create a Custom Event Source

First thing I wanted to have was a custom event source to write to for warnings and errors. To do this I created a simple cmd-file which I placed inside the web role project and uploaded with the packed deployment. Now when the web role is deployed, you define startup task which runs in elevated mode (to be able to create the event source) and points to this cmd-file. So, create a file inside your project’s root called CreateEventSource.cmd and put this inside it:

EventCreate /L Application /T Information /ID 900 /SO "MySource" /D "my custom source" 
NOTE! Make sure the cmd-file property for “copy to output directory” is set to “copy always” or “copy if newer”.
Then open up your service definition file, ServiceDefinition.csdef, and add a startup task to it:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="MyWeb" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="MyWebRole" vmsize="ExtraSmall">
    <Startup>
      <Task commandLine="CreateEventSource.cmd" executionContext="elevated" taskType="simple" />
    </Startup>
    <Sites>
… and so on…
</ServiceDefinition>

So now when your application is deployed the cmd-file should be executed with elevated permission and create the event log source you specified. EventCreate is a tool which is available on the Azure server so it’s nothing you need to worry about. Same thing should work well on your local dev machine too.

Storage Location for Diagnostics Data

You need a place for the diagnostics data to be transferred to. This is number of Azure Storage tables so you need to create an Azure Storage Account where Azure can create these specific tables and transfer the captured data. So you basically go to the Azure Management Portal and create a new Storage Account and copy the access key. Then paste the storage account name and key into the Service Configuration:

image

Now when Azure starts to transfer data from event log and trace writes, they will be written to these two tables; WADLogsTable and WADWindowsEventLogsTable:

image

If you capture performance counters and such, these will be written to other tables.

Diagnostics Configuration

Next thing to do is to configure which diagnostics to capture for your application. This is done in the OnStart() method of your WebRole.cs file. What I wanted to test initially was event logging to my custom source and also some trace writings for information, warning and errors. I also specified how frequently I wanted these diagnostics to be written to the storage tables:

public override bool OnStart()
{
    var diag = DiagnosticMonitor.GetDefaultInitialConfiguration();
            
    diag.Logs.ScheduledTransferLogLevelFilter = LogLevel.Information;
    diag.Logs.ScheduledTransferPeriod = TimeSpan.FromSeconds(30);

    diag.WindowsEventLog.DataSources.Add("Application!*[System[Provider[@Name='MySource']]]"); 
    diag.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromSeconds(30);

    DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", diag); 

    return base.OnStart();
}

Note a few things about this code – The transfer schedule is set to 30 seconds and you may want to set this one a bit higher and also look at the buffer quotas. The sample code is also only capturing and transferring event logs from the “Application” logs, and I’ve added an xpath expression to only transfer logs from the “MySource” event source we specified in the cmd-file earlier. You may want to grab all application events as well as all system logs too, in that case:

diag.WindowsEventLog.DataSources.Add("System!*");
diag.WindowsEventLog.DataSources.Add("Application!*");

Writing to Event and Trace Logs

The simplest thing is then to add some code to write to the event log and trace logs in your code, for example:

Trace.TraceError("Invalid login");
EventLog.WriteEntry("MySource","Invalid login",EventLogEntryType.Error);

Looking at the Data

To actually see what’s been written to these tables, you need to either download the data from the storage tables via APIs, use the server explorer or some tool, like the one from Cerebrata – “Azure Diagnostics Manager” – which seems to do the job pretty well. As far as I know, there is no proper tool available from Microsoft. Be that as it may.

Please, feel free to write comments below and add tips and tricks about handling diagnostics in your Azure application. I’d like to know more about the Transfer Period and Buffer Quotas and how they may affect the application and maybe also the billing… I’m sure there are loads to learn about this Ler.

Posted: Feb 24 2012, 03:56 PM by jdanforth | with 1 comment(s)
Filed under:
How to Force Comments When Doing Check-In in TFS

I was looking for a policy like this, and found this blog article by Claus Konrad:

http://blog.clauskonrad.net/2010/08/tfs-2010-how-to-force-comments-when.html

Now, unfortunately everyone in the project has to have the TFS Power Tools installed to make this work.

The power tools can be downloaded from the Visual Studio Gallery, this is a direct link to it:

http://visualstudiogallery.msdn.microsoft.com/c255a1e4-04ba-4f68-8f4e-cd473d6b971f?SRC=VSIDE

Whish this was in the box from start.

Posted: Feb 08 2012, 10:35 AM by jdanforth
Filed under:
MSTest and Calling Exe with Sample Data Files

For various reasons I’m using MSTest for my unit tests and I have this console app which generates a PDF file from an XML file that needed some tests.

So, when moving the unit tests over to a TFS build server, having hard coded paths to test data files is not a good idea. The recommended way of doing it is to use the DeploymentItem attribute.

Also, when calling an exe-file which does Environment.Exit() and catching the exit code from the unit test is pretty straight forward by using Process.Start() and checking the ExitCode property.

A small sample:

[TestMethod]
[DeploymentItem(@"TestData\arbetsorder.xml", "TestData")]
[DeploymentItem(@"TestData\arbetsorderReport.rdlc", "TestData")]
public void GeneratorShouldReturnWithExitCode0()
{
    Process proc;
    try
    {
        proc = Process.Start("PdfGenerator.exe", "\"" + Directory.GetCurrentDirectory() + "/TestData/arbetsorderReport.rdlc\" \"" +
            Directory.GetCurrentDirectory() + "/arbetsorder.pdf\" \"" + Directory.GetCurrentDirectory() + "/TestData/arbetsorder.xml\"");
    }
    catch (System.ComponentModel.Win32Exception ex)
    {
        proc = null;
        Assert.Fail(ex.Message);
    }

    Assert.IsNotNull(proc);
    proc.WaitForExit(10000);
    Assert.IsTrue(proc.HasExited);
    Assert.AreEqual(0, proc.ExitCode, "Expected 0, got " + proc.ExitCode);
}

But, there’s a small caveat to get the DeploymentItem argument working properly! First you have to open up the test settings of your .testsettings file, select the Deployment settings and make sure the “Enable deployment” checkbox is checked:

image

That’s all you need to do. And note that you may actually have to exit and restart Visual Studio to make it work. I never got the files deployed until I did that restart.

Posted: Feb 07 2012, 09:52 AM by jdanforth | with 2 comment(s)
Filed under:
Command Handling the Nancy Way

minibuss_small_thumb1_thumb_thumb MiniBuss is a micro service bus framework over msmq which consists of less than 400 lines of code, sitting inside one single source file. The project is hosted over at http://minibuss.codeplex.com and the source code is maintained at https://github.com/johandanforth/MiniBuss

I’ve been a fan of the Sinatra inspired web framework called Nancy, especially the neat way of setting up handlers for routes. The simplest sample on their site is this:

public class Module : NancyModule
{
    public Module()
    {
        Get["/greet/{name}"] = x => {
            return string.Concat("Hello ", x.name);
        };
    }
}

So, I shamelessly dug into the Nancy code and borrowed some 20-30 lines of code and came up with something like this for registering handlers for certain incoming commands on the minibus, what do you think?

public class CommandHandler : MessageHandler
{
    public CommandHandler()
    {
        WhenReceiving[typeof(SampleMessage1)] = x =>
        {
            Console.WriteLine("sample 1 message: " + x.Text);
        };

        WhenReceiving[typeof(SampleMessage2)] = x =>
        {
            Console.WriteLine("sample 2 message: " + x.Text);
        };
    }
}

It’s a bit more code but it helps/enforces you to move the handlers off to a certain module. Thoughts?

More MiniBuss Updates

minibuss_small_thumb1_thumb MiniBuss is a micro service bus framework over msmq which consists of less than 400 lines of code, sitting inside one single source file. The project is hosted over at http://minibuss.codeplex.com

Thanks to @CodingInsomnia for testing out the MiniBuss stuff a bit more than I did Winking smile For the samples, and for my initial testing code, I used a shared assembly with messages (events and commands), which shouldn’t be necessary. So I made a few simple changes and now you can choose to either share messages in an assembly between your sender/receiver and publisher/subscribers OR you can declare local message classes as long as those classes use the same class name and properties it should work.

The NuGet package has been updated, and the new code is in package version 1.0.2.0.

More Posts Next page »