Showing posts with label ASP.NET 5. Show all posts
Showing posts with label ASP.NET 5. Show all posts

Tuesday, 10 May 2016

Deploy ASP.Net Core 1.0 to Remote IIS Using MSDeploy

In order to run ASP.Net Core 1.0 in IIS you need to setup IIS with HttpPlatformHandler instructions are here. IIS configurations for ASP.NET Core 1.0 can be found here.

Follow the below steps to use msdeploy to deploy ASP.NET Core 1.0 from a remote machine

1. Install web deploy 3.5, using webpi in remote IIS machine. Make sure you have availability of Deploy menu in IIS. (close and open IIS)image

image

2. Now install Web deploy 3.6 in the IIS  machine, hosting the web site. image

3. Configure web deploy publishing for the site.image

4. In IIS machine hosting the site, create a user say “deployadmin” and add it to administrators group.image

5. Setup deployment execution machine with web deploy 3.5 and the with web deploy 3.6 using webpi

6. Using the below PS script you can deploy the site. To run this script powershell 5.0 is required. Download powershell 5.0 from here.

.\DeploySite.ps1 -MSDeployPath "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3" -packageWWWRoot "C:\temp\Portal\wwwroot" -websiteName DeployTest -targetFQDN yourserver.yourdomain -deployUser yourserver\deployadminuser -deployUserPwd deplyuserpwd

param($MSDeployPath, $packageWWWRoot, $websiteName, $targetFQDN, $deployUser, $deployUserPwd)

. "$MSDeployPath\msdeploy" -verb:sync -source:iisapp=$packageWWWRoot -dest:iisapp="$websiteName",computerName=$targetFQDN,username=$deployUser,password=$deployUserPwd -enablelink:contentlibextension -allowUntrusted

image

image

To solve the issue ERROR_USER_NOT_ADMIN follow the instructions here.image

Registry fix (bit of a hack) for target IIS machine. image

Wednesday, 4 May 2016

Build ASP.NET Core 1.0 with TFS 2013.4 Build Server

To build ASP.NET Core 1.0 with Team foundation 2013.4 XAML builds, following steps should be done.

Prepare the build server
1. Install VS 2015 in the build server
2. Install below by login to the build server as build service user (tfsbuildsvc in this case). Install chocolatey in build server (its easy to do other installations when chocolatey is installed.)

  • To install chocolatey run below command in PS window(run as administrator)
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
  • install nodejs with below command
choco install nodejs.install
  • Change directory to nodejs install path (C:\Program Files\nodejs)
  • Install bower and gulp for global use using below commands

npm install bower -g
npm install gulp -g

Build Scripts – Pre Build
Pre build script to set dnx is required. use below script.

# bootstrap DNVM into this session.
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}

# load up the global.json so we can find the DNX version
$globalJson = Get-Content -Path $PSScriptRoot\..\..\MainSolution\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"
}

# install DNX
# only installs the default (x86, clr) runtime of the framework.
# If you need additional architectures or runtimes you should add additional calls
# ex: & $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -r coreclr
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent

# run DNU restore on all project.json files in the src folder including 2>1 to redirect stderr to stdout for badly behaved tools
Get-ChildItem -Path $PSScriptRoot\..\..\MainSolution -Filter project.json -Recurse | ForEach-Object { & dnu restore $_.FullName 2>1 }

dnvm upgrade -r clr

Make sure to add global.json file to the location of the solution file and check it in to version control.

image

Global.json content below specifying version globally.

{
  "projects": [ "Portal" ],
  "sdk": {
    "version": "1.0.0-rc1-update1"
  }
}

Build Scripts –  Post Build Publish Script
In publish script environment variable settings to path should be added with below. This will allow to run PrePublish script specified in project.json
$env:Path += ";C:\Program Files\nodejs;C:\Users\tfsbuildsvc\AppData\Roaming\npm"

image
param($solutionName, $projectName, $projectPath, $buildConfiguration, $buildStagingDirectory)
 
$VerbosePreference = "continue"
$ErrorActionPreference = "stop"
     
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}
$globalJson = Get-Content -Path "$PSScriptRoot\..\..\$solutionName\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"
     
#& "dnu" "build" "$PSScriptRoot\src\$projectPath" "--configuration" "$buildConfiguration"
Write-Warning "Path is $PSScriptRoot\..\..\$projectPath"

$env:Path += ";C:\Program Files\nodejs;C:\Users\tfs10buildsvc\AppData\Roaming\npm"

$publichLocation = "$buildStagingDirectory\$projectName"
[IO.Directory]::CreateDirectory($publichLocation)
 
& "dnu" "publish" "$PSScriptRoot\..\..\$projectPath" "--configuration" "$buildConfiguration" "--out" "$publichLocation" "--runtime" "$dnxRuntimePath"

Check in Build Scripts
Scripts are in below folder structure. Path changes ($PSScriptRoot\..\..\) to script required if it is checked in to different folder hierarchy.

image
Set Build definition to Run Build scripts
In build definition set to execute scripts as shown below. Set tool version in build definition to use VS 2015 tools. /tv:14image
RunPreBuildScript.ps1
Invoke-Expression "$PSScriptRoot\SetDNX.ps1"

RunPostBuildScript.ps1

param($buildConfiguration)

Invoke-Expression "$PSScriptRoot\PublishWebSite.ps1 -solutionName MainSolution -projectName WebPortal -projectPath 'MainSolution\WebPortal' -buildConfiguration $buildConfiguration -buildStagingDirectory $Env:TF_BUILD_BINARIESDIRECTORY"

RunPreBuildScript and RunPostBuildScript are used since there could be more scripts that need to be executed and only one is allowed in XAML build definition. These script could invoke other scripts.

You could run into

npm WARN deprecated graceful-fs@3.0.8: graceful-fs version 3 and before will fail on newer node releases. Please update to graceful-fs@^4.0.0 as soon as possible.
npm WARN deprecated graceful-fs@2.0.3: graceful-fs version 3 and before will fail on newer node releases. Please update to graceful-fs@^4.0.0 as soon as possible.
npm WARN deprecated npmconf@2.1.2: this package has been reintegrated into npm and is now out of date with respect to npm
npm ERR! cb() never called!
npm ERR! not ok code 0

image
This is discussed in here. To disable this warning raising as an error change the project.json prepublish script section as below (Add --loglevel=error to npm install).image
You can get a successful build with TFS build 2013.4, for ASP.NET Core 1.0.image
image

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

Popular Posts