Quicknote: Binding XAML event to ViewModel

Just a rough note. I was building a WPF interface for a tool i’ve written. I wanted to bind events on this to my ViewModel, instead of have classic “code beside”.

Other than using third party code, the quickest way to do this was to reference the System.Windows.Interactivity.dll. This is part of the Microsoft Expression Blend SDK http://www.microsoft.com/en-us/download/details.aspx?id=3062

I then added a namespace reference as follows: xmlns:i=”http://schemas.microsoft.com/expression/2010/interactivity

I could then bind an even to a property in my ViewModel and thus handle the event there. 

<Button>
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="IsVisibleChanged">
      <i:InvokeCommandAction Command="{Binding VisibleChanged}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>

Related link: http://msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx

PowerShell Variable Scope

Just thought I’d blog about PowerShell variable scope. It seems that not many people are aware of this (I wasn’t aware until recently). There are scopes for private, local (this is the default behaviour), script and global (the PowerShell console).

$private:myVar = “Some value”
$local:myVar = “Some value”
$script:myVar = “Some value”
$global:myVar = “Some value”

This article contains a nice section with slightly more detail. http://powershell.com/cs/blogs/ebookv2/archive/2012/02/02/chapter-3-variables.aspx#scope-of-variables

Quicknote: Equivalent to SPSecurity.RunWithElevatedPrivileges in standard asp.net (4.0)

I have an asp.net web app that must execute code under the context of the current user (via identity impersonate, as it needs to call out to various resources). There are some blocks of code, such as writing exceptions to the event log that must run as the app pool account.

In SharePoint, (which has asp.net set up very similar to my web app), there is SPSecurity.RunWithElevatedPrivileges. This ensure a block of code runs as the app pool account. The equivalent in asp.net is as follows:

using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
}

http://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.impersonate.aspx

Quicknote: A couple of links…

I’m currently debugging WCF, as a reminder, here is an article on how to configure tracing and logging. I simply just put the relevant entries into my web.config and created the folder for my log file to be place in.  http://msdn.microsoft.com/en-us/library/aa702726.aspx

Also, here is a link to force self-signed certificates to appear as trusted on a development environment. http://www.robbagby.com/iis/self-signed-certificates-on-iis-7-the-easy-way-and-the-most-effective-way/

SharePoint 2010: Synchronously Deploying Solutions (WSPs)

When developing larger SharePoint solutions (with multiple developers and environments), we normally write a series of PowerShell scripts to ensure that all our custom functionality and structure can be repeatedly deployed. The problem that commonly arises with this is that SharePoint solution files (wsps) are deployed asynchronously, meaning that later operations in PowerShell scripts can fail. A while ago, i posted a rough article on execadmsvcjobs with SharePoint 2010 (click here to view the original article). I have experimented polling the “Deployed” property of a WSP in PowerShell, however I did not find this robust in some cases.

I have recently hardened my mechanism to ensure that my PowerShell scripts wait synchronously for solutions to deploy / retract as follows (based on a excellent post by Gary LaPointe (see here))

Note that this example assumes a solution to be activated globally (i.e. not at a specific webapp), and that also deploys to the GAC.

   1: Add-PSSnapin "Microsoft.SharePoint.Powershell"

   2: $ErrorActionPreference = "stop"

   3:  

   4: $solutionPath = "C:\DummySolution\DummySolution\bin\Debug\DummySolution.wsp"

   5: $solutionName = "DummySolution.wsp"

   6: $featureName = "DummyWebPart"

   7: $urlToActivateFeature = "http://mywebsite/sites/test"

   8: $webAppUrl = "http://mywebsite"

   9:  

  10: Add-SPSolution -LiteralPath $solutionPath

  11: Install-SPSolution -Identity $solutionName -GacDeployment -WebApplication $webAppUrl

  12:  

  13: do 

  14: { 

  15:     Write-Host "Sleeping for 2 seconds to allow wsp to deploy"

  16:     Start-Sleep 2 

  17:     $solution = Get-SPSolution $solutionName

  18:     if ($solution.LastOperationResult -like "*Failed*") { throw "An error occurred deployment." }

  19:     if (!$solution.JobExists -and $solution.Deployed) { break }

  20: } 

  21: while ($true)

  22: sleep 5  

  23:  

  24: Enable-SPFeature -Identity $featureName -Url $urlToActivateFeature