Quick Tips for the Sitecore Package Deployer

There is a package for Sitecore called the Sitecore Package Deployer, that updates the Sitecore Content Management System(CMS) with packages from Team Development for Sitecore(TDS). While working with this package extension I have been told and shown two tips that can help with your development and deployment.

Admin Update Installation Wizard

With this tool you can analyse as well as install new/existing update packages to the Sitecore instance. If you browse to ‘sitecore/admin/UpdateInstallationWizard.aspx’ on your Sitecore instance, you should be presented with a login page.

If you login with your admin credentials and sign in you should be presented with the welcome page.

 

s1.png

Once you click ‘Select a package >’ you will go to a page to select a new package, which should be an update file. Once you have selected your package you can press the ‘Package Information >’ button.

 

s2

 

When you go to the next page you can then see the package detail and go on to ‘analyse the package >’. This will display the analyse page, which if you select the ‘Analyse’ button, it will as it says, analyse the package to identify potential conflict. Once you have reviewed you can then install the package safely and securely.

Sitecore Package Deployer URL

So back to the TDS side, that once you have put your packages in the ‘SitecoreDeployerPackages’ folder you want them to update, but now.

In our release process after putting the files in the location, we don’t want to wait for the timer to trigger, so a method is to request this URL:

[YourSite]/sitecore/admin/SartStiecorePackageDeployer.aspx

This will trigger the deployer to start processing the update files, but it doesn’t stop there. While do this we started to get failed processes as the deployer was busy. This is caused by a clash between the timer and the request, so there is a way to force this by adding the query string name/value of ‘force=1’

This makes the URL look like this:

[YourSite]/sitecore/admin/SartStiecorePackageDeployer.aspx?force=1

 

Anymore?

If you have any tips on using the Sitecore Package Deployer or other Sitecore related tips then please share.

 

How to get a PDF from Server Side to Client Side?

So you generate a PDF in the C# code or any back end code, but need to send it back to the JavaScript doing the AJAX request. The trouble is how do you return a file back to the client side, which is the same problem I faced. There are loads of methods of how to do this that I have seen on the line, but these are the ways I found worked with C#.NET and JavaScript consistently.

Returning the File

First method I found was very simple and the most direct route to the user. In this scenario you do an AJAX request from the JavaScript straight to the back end system that is generating the PDF file and return that file in the request.

First get the file from the file system into a ‘FileStream’:

Var filesFullPath = "C:\documents\pdfDocument.pdf";
Var fileStream = new FileStream(filesFullPath , FileMode.Open, FileAccess.Read, FileShare.Delete, 4096, fileOptions);

Then use the ‘ControllerBase.File’ class, part of the Controllers inherited class, to convert the ‘FileStream’ into a ‘FileResult’ with a PDF content Type:

Var fileResult = ControllerBase.File(fileStream, "application/pdf");

‘ControllerBase’ is part of the inherited ‘Controller’ Class from ‘Microsoft.AspNetCore.Mvc’.

You can then return this object back to the requesting JavaScript. On the client side it is just a standard ‘XMLHttpRequest’, but the key part is the ‘responseType’ is set to ‘arrayBuffer’.

This means when the response comes back in that format we can create a new ‘Blob’ from the object with the correct content type. This Blob is then converted to a URL and opened in a new window.

var url = "<a href="http://www.GetMyPdf.com/GetPdf">http://www.GetMyPdf.com/GetPdf</a>";

// Send Request
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'arraybuffer';
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function (e) {

// Check status
if (this.status == 200) {

// convert response to Blob, then create URL from blob.
var blob = new Blob([this.response], { type: 'application/pdf' }),
fileURL = URL.createObjectURL(blob);

// open new URL
window.open(fileURL, '_blank');

} else {

console.error('response: ', this);

}
};

xhr.send(JSON.stringify(data));

Now this works great in the scenario above, but a situation that we came against was the back end code to the client side was not doing the generating there was a middle tier, then also it was handling the response from all APIs as a json response which is a string type. Therefore we couldn’t return the file directly and not in an Array Buffer format.

A better solution would be to store the PDF file somewhere the client side can request it after it has been generated. This will save on the large packet of data being sent back and less worry of data loss, but let us continue on this path anyway.

The solution to the weird request is to use Base64 as the string based response. In the C# code we can convert the file into ‘bytes’, which can then be converted to Base64 string:

var fileFullPath = "C:\documents\MyPdf.pdf";

// Convert to Bytes Array
bytes[] pdfBytes = File.ReadAllBytes(fileFullPath );

// Convert to Base64
var base64Str = Convert.ToBase64String(pdfBytes);

This is then saved to return back as a string to the middle tier and then back to the client side.

We now have a string response that we can to convert the Baset64 into a PDF file for the client, which can work both of these ways.

If you first prefix the Base64 with the PDF Base64 DataURI as below:

var base64Str = "****";
var base64DataUri = 'data:application/pdf;base64,' + base64Str;

You can then open the Data URI in a window:

// open new URL
window.open(base64DataUri , '_blank');

However I didn’t find this consistently working, so instead I do the same as before with the ‘XMLHttpRequest’, but instead the URL is the Data URI.

var url = base64DataUri;

// Send Request
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'arraybuffer';
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function (e) {

// Check status
if (this.status == 200) {
// convert response to Blob, then create URL from blob.
var blob = new Blob([this.response], { type: 'application/pdf' }),
fileURL = URL.createObjectURL(blob);

// open new URL
window.open(fileURL, '_blank');

} else {

console.error('response: ', this);
}
};

xhr.send();

This now uses the base64 string as the URL to request the PDF as a web request so we can return the PDF as a Byte Array, then just like before it is converted to a Blob, to URL and opened in a new window.

So far this has worked and consistently, so try it out and give me any feedback.

How to merge multiple images into one with C#

Due to a requirement we needed to layer multiple images into one image. This needed to be faster and efficient plus we didn’t want to use any third party software as that would increase maintenance. Through some fun research and testing I found a neat and effective method to get the outcome required by only using C#.NET 4.6.

So the simple result was to use the C# class ‘Graphics’ to collect the images as Bitmaps and layer them, then produce a single resulting Bitmap.

As you can see from below, we first create the instance of the end Bitmap by create a new type with the width and height of the resulting image passed in. Using that Bitmap we create an instance of the Graphics, which we use in our loop of each image. For each of the images, they are added to the graphic with the starting X/Y co-ordinates of 0.

This solution solves the requirement I had as they all needed to be layered from the starting point of the top left corner, but you could also get imaginative with the settings to place the layers in different places, or even with the Bitmaps width you could create a full length banner.

// merge images
var bitmap = new Bitmap(width, height);
using (var g = Graphics.FromImage(bitmap)) {
foreach (var image in enumerable)     {      
g.DrawImage(image, 0, 0);
    }
}

This is of course handy and simple, so I thought to share and help I would create a full class to handle the processing. With the class below you do not need to create an instance as it is static, so that it can be used as a tool like it is.

You can find the full code on my Github at https://github.com/PureRandom/CSharpImageMerger

The aim of this class which can be expanded, is to layer an array of images into one. You can do this by passing an array of links, of bitmaps or a single folder directory.

When you pass the array of links, you also have the option of providing proxy settings depending what your security is like. It then uses an inside method to loop each link to attempt to download it and return them in a bitmap list.

private static List ConvertUrlsToBitmaps(List imageUrls, WebProxy proxy = null) {
    List bitmapList = new List();
    // Loop URLs
    foreach (string imgUrl in imageUrls)
    {
      try
      {
        WebClient wc = new WebClient();
        // If proxy setting then set
        if (proxy != null)
        wc.Proxy = proxy;
        // Download image
        byte[] bytes = wc.DownloadData(imgUrl);
        MemoryStream ms = new MemoryStream(bytes);
        Image img = Image.FromStream(ms);
        bitmapList.Add((Bitmap)img);
      }
      catch (Exception ex)
      {
        Console.Write(ex.Message);
      }
      }
    return bitmapList;
}

When you pass the array of bitmaps it is the same as the above, but it doesn’t have to download anything.

Finally the file system method can be used by passing the folder directory you wish it to search, then the image extension type. So if you was looking to merge all png’s in the directory ‘src/images/png’, then that is what you pass.

private static List ConvertUrlsToBitmaps(string folderPath, ImageFormat imageFormat)
{
    List bitmapList = new List();
    List imagesFromFolder = Directory.GetFiles(folderPath, "*." + imageFormat, SearchOption.AllDirectories).ToList();
    // Loop Files
    foreach (string imgPath in imagesFromFolder)
    {
      try
      {
        var bmp = (Bitmap) Image.FromFile(imgPath);
        bitmapList.Add(bmp);
      }
      catch (Exception ex)
    {
      Console.Write(ex.Message);
      }
      }
    return bitmapList;
}

With all of these it then uses the common method to loop each item in the array of bitmaps for find the biggest width and height, so the images don’t over or under run the results size. As explained above, each bitmap is looped through to merge the images to the top left of the result Bitmap to create the final image.

private static Bitmap Merge(IEnumerable images)
{
  var enumerable = images as IList ?? images.ToList();
  var width = 0;
  var height = 0;
  // Get max width and height of the image
  foreach (var image in enumerable)
  {
    width = image.Width > width ? image.Width : width;
    height = image.Height > height ? image.Height : height;
  }
  // merge images
  var bitmap = new Bitmap(width, height);
  using (var g = Graphics.FromImage(bitmap))
  {
    foreach (var image in enumerable) {
      g.DrawImage(image, 0, 0);
    }
  }
  return bitmap;
}

Feel free to comment, expand and share this code to help others.

https://github.com/PureRandom/CSharpImageMerger

Returning an image from a General Handler in .NET

You know how to return a string, you know how to return an integer and you know how to return JSON, but do you know how to return an image from a General Handler file (ashx) in .NET 4.6?

Well if not then fear not as I have the answer.

Simply put you make sure the return type is or an image:

C#

context.Response.ContentType = "image/"  + System.Drawing.Imaging.ImageFormat.Jpeg;

VB

context.Response.ContentType = "image/" + System.Drawing.Imaging.ImageFormat.Png;

We then use the ‘Image’ class from the ‘System.Drawing’ namespace, which can be used in both VB and C#. With this item we can use the method ‘Save’ to instead of saving it to a file, we save it to the http requests ‘OutputStream’ as this is what will be returned to the user.

C#

Using System.Drawing;

## Get your image into the Image class via your own method
Image MyImage = GetImage();

## Save the Image to the OutputStream back to the request
MyImage.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);

##Clean up after yourself
MyImage.Dispose();

VB

Import System.Drawing

' Get your image into the Image class via your own method
Dim MyImage As Image = GetImage()

' Save the Image to the OutputStream back to the request
MyImage.Save(context.Response.OutputStream, Imaging.ImageFormat.Jpeg)

' Clean up after yourself
MyImage.Dispose()

Here are some helpful links for some further reading:

Should you unit test CSS?

When I told a college I was going to write some unit tests for CSS they went crazy, and I do see why, however I think it can be valuable in the right way. I would like to describe to you why I think doing unit tests on CSS can be worth your time as a developer and also beneficial to the project.

Why oh why you may ask would you unit test CSS? Styles change so often, the style might be abstract from the code and they can be hard to test. You can’t test just the code, you have to test it for what it is, which is User Interface(UI) coding. Therefore you need to test it through the UI with something like Selenium, that boots up a browser and checks the UI. Though even if you use this technology then testing literally the size of the font and the colour of the background, which have no variable changes, you not testing properly.

Normally when you are unit testing, it is on something that can change depending on multiple variables, so testing the font size isn’t that. When you are testing them things they can only change if you want them to, so you not testing the code, you’re testing that you remembered to update the test. For example, if you have a ‘h1′ with a font size ’14px’ and write a unit test to check the browser has rendered a ‘h1’ with that size, then you have a change come in. You change the font size and now your unit test fails, so you update the test case, but what have you just shown to the project? You have proved that the font has been updated in both places.

It also gets hard when you are testing with browsers, as each browser will interpret the CSS in different ways. They render different, so when you test ‘1em’ is ’14px’ you might get a different answer in another browser.

Therefore why do I think you should unit test CSS?

Well that’s more because I am not saying to test the CSS purely, but to test modular items. In the project I work on there are modules in the site that share classes. Things like a promotion box with a background colour and a banner with the same background colour. We use the CSS pre-processor called LESS, so the background colour is stored in a variable shared across the code base. If a developer decides to change that variable for the banner, we want the unit test to flag that changing this colour effects the promotion box as well.

Example CSS:

@bg-color: #66bb6a;

.banner { background-color:@bg-color;}
.promo { background-color:@bg-color;}

This is why we should unit test, because we want to know if a classes style changes then what else does it effect. Imagine the above CSS lines were in separate files. You change the ‘@bg-color’ as you want the banner to be a different colour and then the unit test flags that the promotion box is incorrect. The value from this means the developer can find out what breaking changes they have introduced, which helps them decide it should all change or no I need a new class.

There is also testing where it takes graphical images and compares the two, but this is browser and code structure dependent. You can to make sure you can test the code in all situations and that’s why a banner for example is better than a whole page.

In our organisational structure then CSS is in a separate code base as the HTML it is running on, due to the CSS project being used in multiple projects. Therefore, we can’t test against the project’s code base, instead we need to create a running example each time. This has it benefits as we then have a working example to demo to the HTML developers.

This is where and why I think there is value in doing unit testing on CSS, but what do you think? Do you do it already or do you think it is a waste of time?