Sunday, 1 May 2016

ASP.NET Core 1.0–Store Images in Azure Blob When Deployed as Azure Web Site


Data and images are not meant to be stored in Azure Web Site web root directory. It could cause problems doing so, few ideas discussed in below links.
http://stackoverflow.com/questions/12964129/can-i-write-to-file-system-on-azure-web-site
https://social.msdn.microsoft.com/Forums/vstudio/en-US/a8dec55e-c74b-482b-bc65-1c580e4672f4/i-cant-upload-image-on-azure-website?forum=windowsazurewebsitespreview
http://stackoverflow.com/questions/14323548/upload-picture-to-windows-azure-web-site
To store a image or other files in Azure blob container, the below class can be used, with ASP.NET Core 1.0. This class creates the blob container if it does not exist, with required access level (Blob) to allow store and retrieve images to the web site. (Class and interface can be downloaded from here)

Class

using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.AspNet.Http;

namespace BookMyEvents.Services
{
    public class AzureImageHandlerService : IAzureImageHandlerService
    {
        public async Task<string> UploadFileToBlob(IFormFile file, string storageConnectionString, string blobContainerName, string fileName)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);

            // Create a blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Get a reference to a container 
            CloudBlobContainer container = blobClient.GetContainerReference(blobContainerName);

            // If container doesn’t exist, create it.
            await container.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);

            // Get a reference to a blob 
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            // Create or overwrite the blob with the contents of a local file
            using (var fileStream = file.OpenReadStream())
            {
                await blockBlob.UploadFromStreamAsync(fileStream);
            }

            return blockBlob.Uri.AbsoluteUri;
        }

        public async Task<bool> RemoveFileFromBlob(string storageConnectionString, string blobContainerName, string fileName)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);

            // Create a blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Get a reference to a container 
            CloudBlobContainer container = blobClient.GetContainerReference(blobContainerName);

            // If container doesn’t exist, create it.
            await container.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);

            // Get a reference to a blob 
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            // Delete the blob if it is existing
            return await blockBlob.DeleteIfExistsAsync();            
        }
    }
}

Interface

using Microsoft.AspNet.Http;
using System.Threading.Tasks;

namespace BookMyEvents.Services
{
    public interface IAzureImageHandlerService
    {
        Task<string> UploadFileToBlob(IFormFile file, string storageConnectionString, string blobContainerName, string fileName);
        Task<bool> RemoveFileFromBlob(string storageConnectionString, string blobContainerName, string fileName);
    }
}

The above class can be used in an ASP.NET Core 1.0 web application as shown below.image
In startup class Startup.cs of ASP.NET Core 1.0 web application, add the class to SerivcesCollection as shown below to make it available for MVC 6.0 controllers.
services.AddScoped<IAzureImageHandlerService, AzureImageHandlerService>();image
Then in a controller, this can be used. MVC 6.0 will auto inject it to controller.image
Upload File usage sampleimage
Remove File usage sampleimage

Saturday, 30 April 2016

Azure Roadshow 2016 - Continuous Delivery to Azure with VS Team Services

Great one day event on Azure at SLIDA (Sri Lanka Institute of Development Administration), on 29 April 2016.

My session - Continuous Delivery to Azure with VS Team Services

Visual Studio Team Services (VSTS, former VSO) empowers the software development teams. It as a DevOps ready Application Life-Cycle tool, will give you the ability to, track your requirements from inception to delivery to production. Build and Release Management services built in to, VS Team Services, enhance your software delivery process, with controlled, automated, delivery pipelines, an essential for DevOps. Let's explore VSTS features enabling software delivery to Azure.

image

Tuesday, 19 April 2016

Bower with VS 2015–Resolve ECMDERR Failed to execute "git clone https://github.com/components/ … exit code of #-532462766

Recently encountered error in getting bower packages with VS 2015 Update 1 (Enterprise), which is confirmed error on VS 2015 Update 2 Community as well, according to MSDN forum thread here.
PATH=.\node_modules\.bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External;%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External\git
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External\Bower.cmd" install --force-latest
bower jqueri-ui#*           not-cached
https://github.com/components/jqueryui.git#*
bower jqueri-ui#*              resolve https://github.com/components/jqueryui.git#*
bower jqueri-ui#*             checkout 1.11.4
bower jqueri-ui#*              ECMDERR Failed to execute "git clone
https://github.com/components/jqueryui.git -b 1.11.4 --progress . --depth 1", exit code of #-532462766
image
It does not load the version number of the package properly in bower.json as well.01
It is same issue in corporate network and in no firewall, no proxy direct internet connection.
Search on the error and trying out so many suggestions, the most stable workaround is mentioned in this connect feedback (workaround link given stackoverflow answer).
Solution Step By Step
1. Download Git from http://git-scm.com/
2. Install in your machine.03
image
3. Open Git Bashimage
4. Run below command with Git Bash
git config --global url."http://".insteadOf git://image
5. In Visual Studio right click on Dependencies – > Bower and click External toolsimage
or click Tools, Options in Visual Studio.image
6. Go to Project and Solutions –> External Web Tools in Options dialog.image
7. Uncheck “$(DevEnvDir)\Extensions\Microsoft\Web Tools\External\git” and add a new folder path to your Git installed location bin folder.image
8. Close and open Visual Studio and you are good to go.
Now packages give version number in bower.jsonimage
Restore package completes smoothly.image
image
One caveat with the solution is having to install external Git in the machine, which will not be used for anything other than fixing this issue. MSFT should fix the problem with embedded Git shipped with VS to make this a seamless experience for the developers.

Thursday, 31 March 2016

MSDeploy dacpac Deployment ERROR_EXECUTING_METHOD

When using the RM tool to deploy dacpacs as explained in “Deploy dacpac with MSDeploy in VS Release Management”, below error might occur.
image
Info: Adding MSDeploy.dbDacFx (MSDeploy.dbDacFx).
Info: Adding database (server=tcp:mydb.database.windows.net,1433;database=DeployTest;user id=
e;trustservercertificate=False;connection timeout=30)
Info: Initializing deployment: Pending.
Info: Analyzing deployment plan: Pending.
Info: Updating database: Pending.
Info: Creating deployment plan: Pending.
Info: Verifying deployment plan: Pending.
Info: Deploying package to database: Pending.
Info: Creating deployment plan: Running.
Info: Initializing deployment: Running.
Info: Initializing deployment (Start)
Info: Initializing deployment: Faulted.
Info: Initializing deployment (Failed)
Info: Creating deployment plan: Faulted.
Info: Verifying deployment plan: Faulted.
Info: Deploying package to database: Faulted.
Error Code: ERROR_EXECUTING_METHOD
More Information: Could not deploy package.
Unable to connect to target server.
  Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_EXECUTING_METHOD.
Error: Could not deploy package.
Error: Unable to connect to target server.
This is without much information and a generic error, might require tearing your hair out a lot, trying to resolve.
How to resolve
This could be easily a firewall blocking access to your SQL server, or firewall not allowed IP for your Azure database server. Fix could be easy as adding the required firewall exceptions.image

Friday, 25 March 2016

Build C# 6 Syntax with TFS 2013.4 Build Services

If you are using VS 2015 with C# 6 syntax and try to build it with, TFS 2013.4 (build agent installed with VS 2015 Update1 enterprise) you might run into issues like shown below.
The name 'nameof' does not exist in the current context01
This error occurs, since TFS 2013.4 build template is using, msbuild 12.0. To let the TFS build to use msbuild 14.0, you can provide msbuild argument /ToolsVersion switch (or /tv, for short), in TfvcTemplate.12.xaml build process template.
/tv:14.002
With this the previous error solved but now it runs into below issue.
TF900547: The directory containing the assemblies for the Visual Studio Test Runner is not valid ''image
To solve this install VS 2013 in build agent. It solves the problem.03
Tests in here fail, but that is nothing to do with build. Tests are not properly written.
You might run into below issue as well.
Unhandled Exception: System.TypeInitializationException: The type initializer for 'LibGit2Sharp.Core.NativeMethods' threw an exception. ---> System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at LibGit2Sharp.Core.NativeMethods.git_libgit2_init()
at LibGit2Sharp.Core.NativeMethods.LibraryLifetimeObject..ctor()
at LibGit2Sharp.Core.NativeMethods..cctor()
--- End of inner exception stack trace ---
at LibGit2Sharp.Core.NativeMethods.RemoveHandle()
at LibGit2Sharp.Core.NativeMethods.LibraryLifetimeObject.Finalize()x

This is discussed in below links and you can solve using different techniques described in them.
https://social.msdn.microsoft.com/Forums/en-US/5a0d1950-1367-41a6-9171-676a0d0e93c1/tfs-online-getted-checkin-build-failures-vs-online-tfs-online-team-need-to-look-into-it?forum=TFService
http://stackoverflow.com/questions/29286052/tfs-2013-throws-lib2gitsharp-error-during-build-deploy-intermittent

Tuesday, 22 March 2016

Deploy dacpac with MSDeploy in VS Release Management

To deploy a dacpac against a target database, MSDeploy can be used. In powershell, following command allows to deploy a dacpac.
Invoke-Expression "& 'WebDeployFolderPath\msdeploy.exe' --% -verb:sync -source:dbDacFx=`'SourceDACPAC`' -dest:dbDacFx=`'DestinationDBConnection`',commandTimeout=100"  -Verbose -ErrorAction "Stop"
Example
.\DeployDacpacMSDeploy.ps1 -WebDeployFolder "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3" -SourceDACPAC "C:\temp\MyDb.dacpac" -DestinationDBConnection "Server=tcp:qa-db.database.windows.net,1433;Database=mydb;User ID=dbadmin@qa-db;Password=pwd;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30" -CommandTimeout 100
A poweshell script can be developed, to use in a Release Management tool.image
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
param(
    [Parameter(mandatory=$true)]
    [string]$WebDeployFolder,
    [Parameter(mandatory=$true)]
    [string]$SourceDACPAC,
    [Parameter(mandatory=$true)]
    [string]$DestinationDBConnection,
    [Parameter(mandatory=$true)]
    [string]$CommandTimeout
  )

$ErrorActionPreference = "Stop"

Invoke-Expression "& '$WebDeployFolder\msdeploy.exe' --% -verb:sync -source:dbDacFx=`'$SourceDACPAC`' -dest:dbDacFx=`'$DestinationDBConnection`',commandTimeout=$CommandTimeout"  -Verbose -ErrorAction "Stop" | Out-Host

if ($lastexitcode -ne 0) 
    {
        throw "Dacpac deploy failed."
    }
Using this poweshell script a tool in RM can be created as shown below.01
Using the tool, create an action component.02
This component can be used in a release template.03
Database updates can be pushed to Azure SQL or any other target SQL server.04

Wednesday, 9 March 2016

Run xUnit Unit Tests for (dnx)ASP.Net 5 with VS Team Services Build


To run the xUnit unit tests developed for ASP.Net 5 (ASP.Net Core 1.0 now), you need to setup a powershell step/task. Setting up a build with VS Team Services, for ASP.Net 5 is explained here.
First thing we need is a powershell script, which can runt xUnit tests, in VS Team Services build. (Hardcoded paths and project names in the script)

Set-ExecutionPolicy unrestricted -Scope CurrentUser -Force

$VerbosePreference = "continue"
$ErrorActionPreference = "Continue"
     
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore
 
if($globalJson)
{
    $dnxVersion = $globalJson.sdk.version
}
else
{
    Write-Warning "Unable to locate global.json to determine using 'latest'"
    $dnxVersion = "latest"
}
 
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent
 
$dnxRuntimePath = "$($env:USERPROFILE)\.dnx\runtimes\dnx-clr-win-x86.$dnxVersion"

dnx -p $PSScriptRoot\..\..\EventBooking\BookMyEvents.UnitTests test 
Check this script in.image
We have to make sure test results are available to publish in the build. for that we can change the test project .json to create a results xml.image
Next add a powershell script task/step to the build. Set the script to execute and let it continue on error, to make sure, it will not break the build on a test failure.image
To publish the results, use “Publish Test Results” step. Set the test results xml file name specified in the project .json, for the results files. Select the Test result format as XUnit.image
Once a build queues it executes the test and publish the results.image
image
When there are multiple tests running in the build, a detailed test report helps to identify which tests fail.image

Monday, 29 February 2016

Unit Test for ASP.Net 5 with xUnit

Unit testing plays a significant role in assuring the quality of the applications we develop. To unit test an ASP.Net 5 RC1 Update1 (ASP.Net Core 1.0 now), web application we can use xUnit.
To add xUnit test to the solution add a Class Library (Package) project.image
image
Edit the default project.json shown below.image
Add dependency to the ASP.Net 5 web project, and to xUnit and xUnit.Runner.Final project.json should be similar to below.image

{
  "version": "1.0.0-*",
  "description": "BookMyEvents.UnitTests Class Library",
  "authors": [ "Chaminda" ],
  "tags": [ "" ],
  "projectUrl": "",
  "licenseUrl": "",

  "dependencies": {
    "BookMyEvents": "1.0.0-*",
    "xunit": "2.1.0",
    "xunit.runner.dnx": "2.1.0-rc1-build204"
  },

  "commands": {
    "test": "xunit.runner.dnx"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": {}
  }
}
Once the project.json saved the references get updated.image
Let’s write a test for a very simple controller method.image
Test method as a Fact (There are two types of Unit Tests in xUnit. Fact and Theory. More information here).image
Go to test explorer in VS to view the test.image
image
If you cannot see test as above build your solution. Test will be then available in the explorer. Execute and you can see the results.image
Next post let’s learn how to run the unit tests (xUnit), with VS Team Service build and publish test results.

Popular Posts