BM-Bloggers

The blogs of Black Marble staff

Updates to my StyleCop task for VSTS/TFS 2015.2

Tracking the current version of StyleCop is a bit awkward. Last week I got an automated email from CodePlex saying 4.7.52.0 had been released . I thought this was the most up to date version, so upgraded my StyleCop command line wrapper and my VSTS StyleCop task from 4.7.47.0 to 4.7.52.0.

However, I was wrong about the current version. I had not realised that the StyleCop team  had forked the code onto GitHub. GitHub is now the home of the Visual Studio 2015 and C# 6 development of StyleCop, while Codeplex remains the home of the legacy Visual Studio versions. I had only upgraded to a legacy patch version, not the current version.

So I upgraded my StyleCop Command Line tool and my VSTS StyleCop task to wrapper 4.7.59.0, thus I think bringing me up to date.

Using Coded UI from Windows 8.1 to Windows 10 UWP

Recently one of our bigger projects which has a Windows 8.1 client has just been migrated to Windows 10 UWP. The application is quite big and is rapidly changing every week. When it comes to testing we need to make sure that all of the old functionality is still working as expected. To do this we run a set of nightly builds which execute Coded UI tests.When converting the application to Windows 10 we was not sure if the Coded UI tests would just work or if we needed to do some work….so we just ran them!

At first all was looking well as the application launched however nothing else happened to our disappointment. So, I decided to debug one of the tests to find out what was happening.

The way that we was launching the application was my just grabbing the application tile by its ID (guid) as you can see from the screenshot below:

image

This worked fine and then when we was trying to find one of the controls it thought about it for a very long time and then couldn’t find it. When I looked further into the child controls of the main application window it did seem to be picking some up, however none of the controls had an automation id that had initialised. So I decided to try searching for the control by name which also did not work. I was very confused as I could see a long list of controls as child items from the main application.

 

At this point I needed some more feedback from the UI so I decided to basically loop through each child control and highlight it so I could see what controls it was actually picking up and see where they was located on the UI.

I was very disappointed to see that none of the buttons highlighted, but what seemed to be random pieces of the UI.

 

We often come across some controls on the application that the Coded UI finds difficult to interact with. To help the search methods we can filter the search by providing some more attributes. Search configuration and search properties filters through the list of controls as you can see below:

image

So instead of trying this on the actual control itself (i.e button or combo box) I decided to add these filters when grabbing the main application window. Whilst debugging I could actually see the controls where found and the automation id’s where now initialised. This looked more promising!

 

I decided to let the debugger continue and see if the test got any further…which it did! It now seemed to be behaving as I would expect it to. However I did run into another problem. In our application we use quite a lot of dialogs. The way that these dialogs are created in the Windows 8.1 application was by using Direct UI controls. In Windows 10 UWP the dialogs are built up using Xaml controls which make interacting with them a lot easier. Because the application uses a lot of dialogs I thought it would be easier to make a helper method that i can call from different tests:

image

Again using the filters to make sure that the test can find the dialog. The first action of getting the child controls gets the parent areas of the dialog, such as title, or buttons. The second action will then get the child controls from the parent container and I know that each time the tests interact with a dialog the buttons will be in this parent control of the dialog.

 

This actually made my life a little easier as I knew that all dialogs would be using the same controls and automation id’s. The last challenge that we faced was that now most of our Windows 10 builds have now been migrated to vNext. This means that we will now have to set up a release pipeline to get the tests running again…..another blog post to follow!

Azure Logic Apps-The template language function 'json' parameter is not valid.

This is a follow up from my original blog post Azure Logic Apps–Parsing JSON message from service bus

If you see the following error from a Logic App using Service Bus trigger:

{"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'Next_action' inputs at line '1' and column '11': 'The template language function 'json' parameter is not valid. The provided value 'eydlbWFpbCcgOiAndGVzdEB0ZXN0LmNvbSd9' cannot be parsed: 'Unexpected character encountered while parsing value: e. Path '', line 0, position 0.'. Please see https://aka.ms/logicexpressions#json for usage details.'."}

It’s because messages that from service bus topic triggers are now presented as base 64 encoded messages rather than plain text.  Fortunately the fix is straightforward, Logic Apps give you a decodeBase64 function that you can use in the Logic App. 

You need to switch the Logic App to to code view, and use the decodeBase64 function before parsing the json.  So

image

becomes (note the call to decodeBase64 before the call to json):

image

Build 2016 - Overview

Overall I must say that I found this to be one of the best Build's yet. The keynotes had people cheering and applauding almost none stop, the content in the sessions was exemplary and the expo hall and was fun to spend time in with lots of interesting stands to talk to people on.

My only regret is that I didn't have as much time to spend in a actual sessions due to my running around doing other things. Though I have been watching sessions that I missed at https://channel9.msdn.com/Events/Build/2016                                             to catch up and continue learning.

If you want to see more photos of our time at Build please check out our Facebook page at

https://www.facebook.com/Calicowind/?fref=ts

Or if you want to follow us on twitter you can find us at

https://twitter.com/Calicowind                                                                   Follow us to keep track of all our fun exploits in programming

Thank you :D

 

 

 

 

 

How to build a connection string from other parameters within MSDeploy packages to avoid repeating yourself in Release Management variables

Whilst working with the new Release Management features in VSTS/TFS 2015.2 I found I needed to pass in configuration variables i.e. server name, Db name, UID and Password to create a SQL server via an Azure Resource Management Template release step and a connection string to the same SQL instance for a web site’s web.config, set using an MSDeploy release step using token replacement (as discussed in this post)

Now I could just create RM configuration variables for both the connection string and ARM settings,

image

 

However, this seems wrong for a couple of reason

  1. You should not repeat your self, too easy to get the two values out of step
  2. I don’t really want to obfuscate the whole of a connection string in RM, when only a password really needs to be hidden (note the connection string variable is not set as secure in the above screenshot)

What did not work

I first considered nesting the RM variables, e.g. setting a the connection string variable to be equal to ‘Server=tcp: $(DatabaseServer).database.windows.net,1433;Database=$(DatabaseName)….’, but this does not give the desired results, the S(DatabaseServer) and $(DatabaseName) variables are not expanded at runtime, you just get a string with the variable names in it.

How I got want I was after….

(In this post as a sample I am using the Fabrikam Fiber solution. This means I need to provide a value for the FabrikamFiber-Express connection string)

I wanted to build the connection string from the other variables in the MSDeploy package. So to get the behaviour I want…

  1. In Visual Studio load the Fabrikam web site solution.
  2. In the web project, use the publish option to create a publish profile use the ‘WebDeploy package’ option.
  3. If you publish this package you end up with a setparameter.xml file containing the default connection string
    <setParameter name="FabrikamFiber-Express-Web.config Connection String" value="Your value”/>
    Where ‘your value’ is the value you set in the Publish wizard. So to use this I would need to pass in a whole connection string, where I only want to pass parts of this string
  4. To add bespoke parameters to an MSDeploy package you add a parameter.xml file to the project in Visual Studio (I wrote a Visual Studio Extension that help add this file, but you can create it by hand). My tool will create the parameters.xml file based on the AppSettings block of the projects Web.config. So if you have a web.config containing the following
    <appSettings>
        <add key="Location" value="DEVPC" />
      </appSettings>
    It will create a parameters.xml file as follows
    <?xml version="1.0" encoding="utf-8"?>
    <parameters>
      <parameter defaultValue="__LOCATION__" description="Description for Location" name="Location" tags="">
        <parameterentry kind="XmlFile" match="/configuration/appSettings/add[@key='Location']/@value" scope="\\web.config$" />
      </parameter>
    </parameters>
  5. If we publish at this point we will get a setparameters.xml file containing
    <?xml version="1.0" encoding="utf-8"?>
    <parameters>
      <setParameter name="IIS Web Application Name" value="__Sitename__" />
      <setParameter name="Location" value="__LOCATION__" />
      <setParameter name="FabrikamFiber-Express-Web.config Connection String" value="__FabrikamFiberWebContext__" />
    </parameters>
    This is assuming I used the publish wizard to set the site name to __SiteName__ and the DB connection string to __FabrikamFiberWebContext__
  6. Next step is to add my DB related parameters to the paramaters.xml file, this I do by hand, my tool does not help
    <?xml version="1.0" encoding="utf-8"?>
    <parameters>
      <parameter defaultValue="__LOCATION__" description="Description for Location" name="Location" tags="">
        <parameterentry kind="XmlFile" match="/configuration/appSettings/add[@key='Location']/@value" scope="\\web.config$" />
      </parameter>

      <parameter name="Database Server" defaultValue="__sqlservername__"></parameter>
      <parameter name="Database Name" defaultValue="__databasename__"></parameter>
      <parameter name="Database User" defaultValue="__SQLUser__"></parameter>
      <parameter name="Database Password" defaultValue="__SQLPassword__"></parameter>
    </parameters>
  7. If I publish again, this time the new variables also appear in the setparameters .xml file
  8. Now I need to supress the auto generated creation of the connection string  parameter, and replace it with a parameter that uses the other parameters to generate the connection string. You would think this was a case of added more text to the parameters.xml file, but that does not work. If you add the block you would expect (making sure the name matches the auto generated connection string name) as below
    <parameter 
      defaultValue="Server=tcp:{Database Server}.database.windows.net,1433;Database={Database Name};User ID={Database User}@{Database Server};Password={Database Password};Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
      description="Enter the value for FabrikamFiber-Express connection string"
      name="FabrikamFiber-Express-Web.config Connection String"
      tags="">
      <parameterentry
        kind="XmlFile"
        match="/configuration/connectionStrings/add[@name='FabrikamFiber-Express']/@connectionString"
        scope="\\web.config$" />
    </parameter>

    It does add the entry to setparameters.xml, but this blocks the successful operations at deployment. It seems that if a value needs to be generated from other variables there can be no entry for it in the setparameters.xml. Documentation hints you can set the Tag to ‘Hidden’ but this does not appear to work.

    One option would be to let the setparameters.xml file be generated and then remove the offending line prior to deployment but this feels wrong and prone to human error
  9. To get around this you need to added a file name <projectname>.wpp.target to the same folder as the project (and add it to the project). In this file place the following
    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="DeclareCustomParameters"
              BeforeTargets="Package">
        <ItemGroup>
          <MsDeployDeclareParameters Include="FabrikamFiber-Express">
            <Kind>XmlFile</Kind>
            <Scope>Web.config</Scope>
            <Match>/configuration/connectionStrings/add[@name='FabrikamFiber-Express']/@connectionString</Match>
            <Description>Enter the value for FabrikamFiber-Express connection string</Description>
            <DefaultValue>Server=tcp:{Database Server}.database.windows.net,1433;Database={Database Name};User ID={Database User}@{Database Server};Password={Database Password};Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;</DefaultValue>
            <Tags></Tags>
            <ExcludeFromSetParameter>True</ExcludeFromSetParameter>
          </MsDeployDeclareParameters>
        </ItemGroup>
      </Target>
      <PropertyGroup>
        <AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
      </PropertyGroup>
    </Project>

    The first block declares the parameter I wish to use to build the connection string. Note the ‘ExcludeFromSetParameter’ setting so this parameter is not in the setparameters.xml file. This is what you cannot set in the parameters.xml

    The second block stops the auto generation of the connection string. (Thanks to Sayed Ibrahim Hashimi for various posts on getting this working)
  10. Once the edits are made unload and reload the project as the <project>. wpp.targets file is cached on loading by Visual Studio.
  11. Make sure the publish profile is not set to generate a connection string

    image
  12. Now when you publish the project, you should get a setparameters.xml file with only the four  SQL variables, the AppSettings variables and the site name.
    (Note I have set the values for all of these to the format  __NAME__, this is so I can use token replacement in  my release pipeline)
    <?xml version="1.0" encoding="utf-8"?>
    <parameters>
      <setParameter name="IIS Web Application Name" value="__Sitename__" />
      <setParameter name="Location" value="__LOCATION__" />
      <setParameter name="Database Server" value="__sqlservername__" />
      <setParameter name="Database Name" value="__databasename__" />
      <setParameter name="Database User" value="__SQLUser__" />
      <setParameter name="Database Password" value="__SQLPassword__" />
    </parameters>
  13. If you deploy the web site, the web.config should have your values from the setparameters.xml file in it
    <appSettings>
       <add key="Location" value="__LOCATION__" />
    </appSettings>
    <connectionStrings>
         <add name="FabrikamFiber-Express" connectionString="Server=tcp:__sqlservername__.database.windows.net,1433;Database=__databasename__;User ID=__SQLUser__@__sqlservername__;Password=__SQLPassword__;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" providerName="System.Data.SqlClient" />
    </connectionStrings>

You are now in a position manage the values of the setparameters.xml file however you wish. My choice is to use the ‘Replace Tokens’ build/release tasks from Colin’s ALM Corner Build & Release Tools Extension, as this tasks correctly handles secure/encrypted RM variables as long as you use the ‘Secret Tokens’ option on the advanced menu.

image



 

Summary

So yes, it all seems a but too complex, but it does work, and I think it makes for a cleaner deployment solution, less prone to human error. Which is what any DevOps solution must always strive for.

Depending on the values you put in the <project>.wpp.targets you can parameterise the connection string however you need.

UWP-Using WebAccountManager API to connect your Windows 10 to Microsoft Account

Prior to Windows 10 UWP the recommendation for federated authentication in Windows was (and still is) to use ADAL.net.

If you have a Windows 10 UWP application you have a new platform capability available to you called the WebAccountManager. This is the recommended approach going forward from Windows 10.

The Windows 10 UWP samples available on github https://github.com/Microsoft/Windows-universal-samples contain a sample WebAccountManagement which shows you how to integrate your app with Azure AD, Live connect, Local, and other identity providers.

I’ve been through the sample and distilled the key points for Microsoft Account integration.

  1. Provide a handler for AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested.  This is the method that windows will execute when the ‘login’ dialog is shown in your app.  At this stage you add the identity providers you want users to be able to log in with.
  2. Per provider, provide a handler for WebAccountProviderCommand. This is the method that windows will execute when the user has selected the identity provider from the list defined at stage 1.  At this stage, you will be physically issuing a login request using the WebAuthenticationCoreManager.  At the end of this handler, you should have a login result (success/fail) and a token which you can use in downstream processing.
  3. From your client (UWP app), tell the app to show the action settings page using Windows.UI.ApplicationSettings.AccountsSettingsPane.Show().  This will start the login process, and accordingly trigger the above handlers when users have interacted with the account settings pane.

   Below is the code to implement steps 1 and 2.  Note in this example I am using MVVM light dispatcher (Messenger.Default.Send) to deliver an event based message to subscribers.  You can use something like event aggregator or your flavour of pub/sub framework to achieve the same result:

public class Authenticator

{

    public Authenticator()

    {

        AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested += Authenticator_AccountCommandsRequested;

    }

 

    private async void Authenticator_AccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e)

    {

        AccountsSettingsPaneEventDeferral deferral = e.GetDeferral();

        var provider =

            await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "consumers");

        WebAccountProviderCommand providerCommand = new WebAccountProviderCommand(provider, WebAccountProviderCommandInvoked);

        e.WebAccountProviderCommands.Add(providerCommand);

        e.HeaderText = "Please select an account to log in with";

        deferral.Complete();

    }

 

    private async void WebAccountProviderCommandInvoked(WebAccountProviderCommand command)

    {

        WebTokenRequest webTokenRequest = new WebTokenRequest(command.WebAccountProvider, "wl.basic", "none");

        WebTokenRequestResult webTokenRequestResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest);

        var token = webTokenRequestResult.ResponseData[0].Token;

        // sends a message with MVVM Light messenger. This is solution specific, typically you want to use the token to

        // query a service (for example live connect)

        Messenger.Default.Send(new AuthenticatedMessage() { Token = token});

    }

}

 

And below is the code to implement step 3:

Windows.UI.ApplicationSettings.AccountsSettingsPane.Show();

 

 Further reading

I’d encourage you to have a good look at the WebAccountManagement sample in https://github.com/Microsoft/Windows-universal-samples.  This samples contains more detail and different usage scenarios for reference.

Also have a look at Vittorio Bertocci’s post at https://blogs.technet.microsoft.com/ad/2015/08/03/develop-windows-universal-apps-with-azure-ad-and-the-windows-10-identity-api/ which gives a bit of background, explains when you should use ADAL.NET vs WebAccountmanager and has example of integrating with Azure AD.

Build 2016 - The Freebies

This year it was hoped that since there would be no hardware giveaways that the number of giveaways around and about the conference would go up as well. Well we weren't disappointed. The number of competitions to win freebies was high with surface books and phones on offer. Hour competitions were run on twitter by Microsoft dev and there was even a student only twitter competition. To aid in our competition every student was given a branded selfie sticks to show how much fun we were having there. Though unfortunately I didn't win any hardware we managed to walk away with a lot of other cool freebies such as..

This cool looking Visual Studio lunchbox which came with a handy multi tool keying, Visual Studio socks and a Visual Studio wrist band. I fully intend on taking this into uni to make those on my course jealous.

Game of Thrones/Star Wars planning poker cards. If planning poker wasn't fun enough for you already then using these are sure to make it an even more joyous experience.

Enough clothes to last a lifetime. Another Visual Studio/Game of Thrones themed freebie this time in the form of a T-Shirt with a Kanban board as the design featuring such  tasks as under planning Arya has to complete revenge. Warning before looking closer said shirt does include spoilers.... And so many pairs of socks. Say what you will but I've never had a pair of Microsoft socks that weren't comfy. And yes that means I have had them before.

Niamh really managed to nab some swag in the form of cushions, posters, stickers, sweets and so many more things including an odd squishy brain...

Build 2016 - Andy Wigley

As Build was closing up we were lucky to quickly grab some of Andy Wigley's time before we were kicked out. Andy Wigley is a technical evangelist in the UK and works primarily with Universal Apps on phone and tablet. Listen to me talk to him about how he found his time at Build and what he likes most about Windows :D

Build 2016 - Richard Campbell

On the last day of Build Richard Campbell was kind enough to spare us some time for an interview. Having already being lovely enough to help us out the day before we were thrilled that he agreed. Richard is one of the people behind .NET Rocks! A weekly show for those interested in the .NET platform. Watch me talk to him about the cool things he had seen at Build and what he thinks can be done to help students get themselves out there.

Then watch Niamh ask him how we can get more children into programming :)

Niamh gets really into it sometimes.

Build 2016 - Craig Kitterman

On Thursday afternoon we were able to borrow Craig Kitterman for some short interviews :) Craig works in the product marketing organisation for developer tools and cloud services. Watch me speak to him about some of the cool things seen at Build and what he likes about Visual Studio.

Then watch me talk to him about what he thinks we can do to get more children into programming.