Thursday, 8 September 2016

Sitecore - Real page/item last modified date, Global.asax

Recently been looking through some optimisation techneques for our websites.

I noticed that the last modified date was always incorrect.  As this could affect caching etc, I decided to apply a quick fix.  As our code is in MVC the physical pages themselves may not get changed, so the modified date being used is misleading even if it used the file modified date.

This can be added into the global.asax PreSendRequestHeaders

if (Sitecore.Context.Item != null)
            {
                Response.Headers.Remove("Last-Modified");
                Response.Headers.Add("Last-Modified", Sitecore.Context.Database.GetItem(Sitecore.Context.Item.ID).Statistics.Updated.Date.ToString());
            }

This will allow you to apply a modified date of your choice.

The affect we want is for the pages to accurately reflect when the relative sitecore item is updated.

Hope this helps.

Friday, 22 July 2016

Get Macro List from the current page in Umbraco 7.4

(Model.Content).Properties.ToList().Any(x => x.DataValue.ToString().Contains("ImageGallery"))

Enjoy

Friday, 20 June 2014

MVC, ImageResizer, Windows Azure and Creating a Thumbnail Image

Ok you will need the nuget package for ImageResizer, you will not need any of the plugins for this to work, just so you are aware. Use: Package Manager, make sure you have the right project in the dropdown and type: Install-Package ImageResizer [enter]

This example below will take your file, created it in azure and also create thumbnail, it needs to create 2 seperate streams for this.  Before the the StreamUploadFile is called we do a check for any image types we want as thumnbnails, there is a probably a better way to this, but I had to get it done quick(quick isn't always slick :).  On the GetThumbnail Method on the controller is where it will return the image stream, we also have a fallback in case there is no image to display.

Azure Document Manager Class:

        public void StreamUploadFile(string myContainer, string fileName, HttpPostedFileBase file, bool isImage)
        {
            try
            {
                // Retrieve reference to a previously created container.
                var container = _blobClient.GetContainerReference(myContainer);
               
                // Create the container if it doesn't already exist.
                container.CreateIfNotExists();

                // Retrieve reference to a blob named "myblob".
                var blockBlob = container.GetBlockBlobReference(fileName);

                // Create Thumbnail If it is an image
                if (isImage)
                {
                    //Stream fileStreamThumb;
                 

                    // Copy File Stream
                    MemoryStream fileStreamThumb = new MemoryStream();
                    file.InputStream.CopyTo(fileStreamThumb);

                    fileStreamThumb.Seek(0, SeekOrigin.Begin);
                    string thumbnailUri = String.Concat(Path.GetFileNameWithoutExtension(fileName),
                        "_thumb" + Path.GetExtension(fileName));

                    CloudBlockBlob thumbnailBlob = container.GetBlockBlobReference(thumbnailUri);
                    thumbnailBlob.UploadFromStream(CreateThumbnail(fileStreamThumb));
                }

                // Create or overwrite the "myblob" blob with contents from a local file.
                using (var fileStream = file.InputStream)
                {
                    fileStream.Seek(0, SeekOrigin.Begin);
                    blockBlob.UploadFromStream(fileStream);
                }
            }
           
            catch (Exception ex)
            {
                _exceptionHandler.Invoke(ex);
            }
        }

// For Image Resizing
        public Stream CreateThumbnail(Stream input)
        {
            var output = new MemoryStream();
           
            ImageResizer.ImageJob i = new ImageResizer.ImageJob(input, output, new ImageResizer.ResizeSettings("width=100;height=100;mode=max"));
            i.Build();

             
            output.Seek(0, SeekOrigin.Begin);
            return output;
         }

  public byte[] ReturnFileStream(string filePath, string myContainer, string myFile)
        {
            try
            {
                // Retrieve reference to a previously created container.
                var container = _blobClient.GetContainerReference(myContainer);

                // Retrieve reference to a blob named "photo1.jpg".
                var blockBlob = container.GetBlockBlobReference(@myFile);

                // Save blob contents to a file.
                var sStream = new MemoryStream();
                using (var fileStream = File.OpenWrite(filePath))
                {
                    blockBlob.DownloadToStream(sStream);
                }
                return sStream.ToArray();
            }
            catch (Exception ex)
            {
                _exceptionHandler.Invoke(ex);
                return null;
            }
        }


MVC Controler Method:

 public FileContentResult GetThumbnail(int id = 0)
        {
            try
            {
                // Needs a bit of tidying up
                var document = db.Documents.Find(id);
                if (document == null) return null;
                var container = ((int) document.SurveyID).ToString("D8");
                var azureDocument =
                    new DocumentManager.AzureDocumentManager(
                        Encryption.DecryptStorageConnectionString(_storageConnection), null);
                var temp =
                    azureDocument.ReturnFileStream(
                        Path.GetTempPath() + Path.GetFileNameWithoutExtension(document.Name) + "_thumb" +
                        Path.GetExtension(document.Name), container,
                        Path.GetFileNameWithoutExtension(document.Name) + "_thumb" + Path.GetExtension(document.Name));
                var temp2 = new FileContentResult(temp, "application/text") {FileDownloadName = document.Name};
                return temp2;
            }
            catch (Exception ex)
            {
                var fileName =   Server.MapPath("..\\..\\images") + "\\missing.png";

                using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    // Get Error Image
                    MemoryStream input = new MemoryStream();
                    fs.CopyTo(input);
                    input.Seek(0, System.IO.SeekOrigin.Begin);

                    // Resize
                    var output = new MemoryStream();
                    ImageResizer.ImageJob i = new ImageResizer.ImageJob(input, output, new ImageResizer.ResizeSettings("width=64;height=64;mode=pad"));
                    i.Build();
                    output.Seek(0, SeekOrigin.Begin);

                    // Ouput Image
                    var temp2 = new FileContentResult(output.ToArray(), "application/text") { FileDownloadName = "error.jpg" };
                    return temp2;
                }
            }
            finally
            {
            }
           }

Hoepfully that should solve a few headaches or create more in some cases, let me know if there is nothing clear on here :D

Wednesday, 12 March 2014

Geolocation, JSON not working on any browser, but works on desktop?

Well, took me a couple of hours to find out this one, but basically if it works on the desktop then there is a good chance there is nothing wrong with your code, simple reboot the phone and try again. 

Obviously you can put the location services on as well and accept.

Sunday, 23 February 2014

Umbraco MVC - Partial View and Models


The model item passed into the dictionary is of type 'Umbraco.Web.Models.RenderModel', but this dictionary requires a model item of type 'UmbracoBaseFinal.Models.EnquiryModel'.

That is one annoying error, took me ages to find the solution, I knew what the problem is as it basically spells it out for you, but the solution was more difficult to find.  Anyway here it is.


In your main view you have a call like this to your partial view:


@Html.Partial("EnquiryForm", new EnquiryModel())
OR
 @Html.Partial("~/Views/Partials/EnquiryForm.cshtml", new EnquiryModel())


Which is all nice and simple.

Next we have the partial view, my example here, my Model has the properties for the contact form, but this

@inherits Umbraco.Web.Mvc.UmbracoViewPage

@using (Html.BeginUmbracoForm("HandleContactSubmit", "Enquiry"))
{
Enquiry Form

            @Html.LabelFor(x => Model.ContactName)
            @Html.TextBoxFor(x => Model.ContactName)
            @Html.ValidationMessageFor(x => Model.ContactName)
}

Your model should inherit from RenderModel, for example this is what I am using for my contact form at the moment.

using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Umbraco.Core.Models;
using Umbraco.Web;
using Umbraco.Web.Models;

namespace UmbracoBaseFinal.Models
{
    public class EnquiryModel : RenderModel
    {
        [Required]
        public string
ContactName { get; set; }

        [Required]
        [RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")]
        public string Email { get; set; }

        [Required]
        [Display(Name = "Enter a comment")]
        public string Comment { get; set; }

        public EnquiryModel() : this(new UmbracoHelper(UmbracoContext.Current).TypedContent(UmbracoContext.Current.PageId)) { }
        public EnquiryModel(IPublishedContent content, CultureInfo culture) : base(content, culture) { }
        public EnquiryModel(IPublishedContent content) : base(content) { }
    }

}

Umbraco 7 - Setting it up in MVC

1. Created a Blank MVC Project(I used 4 in my case)

2. Deleted all files in the solution and remove all references

3. Right click on your solution and Click 'Manage Nuget Packages'

4. Search for Umbraco 7, find the "Umbraco CMS" and install it.

5. Setup the site in IIS as usual then the rest will prompt you through when you start the site.


Happy Playing, hopefully this simplified the process for people who havent set it up before.


Tuesday, 18 February 2014

MVC 4 - Populate a DropDownList

I'll keep this simple as most other examples seem not to be :D

For example in your controller:

 public ActionResult MyDropDownList()
        {
            ViewBag.MyType = GetDropDownList();

            return View("");
        }

        public static List GetDropDownList()
        {
            var ls = new List
            {
                new SelectListItem() {Text = "Bob", Value = "0"},
                new SelectListItem() {Text = "Jeff", Value = "1"},
                new SelectListItem() {Text = "Rob", Value = "2"}
            };

            return ls.OrderBy(x => x.Text).ToList();
        }

In your razor script/cshtml:

@Html.DropDownList("MyType", MyController.GetDropDownList())

Hopefully that will help you to get your populated dropdown list :)


Additional

You can put this in your razor script for example:

var amountList = new List();
    for (var i = 0; i <= 10; i++)
    {
        amountList.Add(new SelectListItem { Text = i.ToString(CultureInfo.InvariantCulture), Value = i.ToString(CultureInfo.InvariantCulture) });
    }
    amountList = amountList.ToList();
}


Then for display purposes:



                        @Html.DropDownListFor(model => model.ReceptionRooms,  amountList)
                        @Html.ValidationMessageFor(model => model.ReceptionRooms) 



This will display a dropdown from 1-10, the beauty of this also is that you can reuse the same list for multiple controls.