[AJAX] IE and its stupidity–Part 100255454577 – Ajax Caching


This is a note to anyone who uses Ajax and Http GET requests – turn off cache for each request otherwise IE wont refresh and display the latest response. Good example is in JQuery:

$.ajax({
  type: 'get',
  url: url,
  cache: false,
  success: function(result) {
 $(targetDiv).html(result);
  }

This nice little method allows you to pass a parameter called cache which you need to set to false.

Another method in JScript is to provide dummy URL parameter to fool the old dog into refreshing:

var url = '/accountstest/SiteAdmin/Dashboard' + "?dummy=" + new Date().getTime();

Chrome and Firefox do not have this problem.

Reading AJAX For Dummies

Reading AJAX For Dummies (Photo credit: daveynin)

Enhanced by Zemanta

[MVC 3] MvcImage Project……Its Alive!…..


Over the last few months i have done the following blog posts to explain how to handle images using MVC and various technologies like JQuery and Entity Framework. Now the majority of hits i receive are concerning these blogs posts, so obviously Image Handling is a common Achilles heel. The posts are also being referenced in forums to answer Image related questions. So i have decided to create a Open Source project which combines all of these blog posts into one solution for people to use. This project can be found here for anyone who wants to use it:

Codeplex: http://mvcimage.codeplex.com/

Github: http://garfbradaz.github.com/MvcImage/

At the moment it includes everything i have blogged about and shows you how to extend the RegisterModel to include adding Images when registering a new user. I will be adding the following to the project moving forward as i want this to an organic project that grows:

  1. Adding Thumbnails to the database and displaying these
  2. A details page of users so you can view their details and the images – A User Dashboard for the Admin
  3. A Image FileResult.
  4. A PDF document explaining what the Project does and where.

MY ORIGINAL BLOG POSTS – Image Handlers – JQuery/ASP.NET/SQL DB & Entity Framework (MVC3)

Tutorial 1 – Image Preview – JQuery

Tutorial 2 – Image Preview – HTML Helpers

Tutorial3 – Upload Image – SQL Server & Entity Framework

Tutorial 4 – Images – Downloading Images

Tutorial 5 – Thumbnail Support

Enhanced by Zemanta

[MVC 3] Image Preview–JQuery


UPDATE: I have now combined all my MVC Image Handling  blog posts into a Open Source Project. Feel free to check this out once you have read the post.

http://mvcimage.codeplex.com/

Original Blog Post:

At the moment I’m learning ASP.NET and MVC 3. Lets say I’m loving it at the moment, and at this present moment, I’m trying to employ my new skills in creating a new site for my friends friend, but i cannot disclose anymore on that….for now.

What i can disclose is snippets and code samples on my journey. Once such snippet is Image Previewing. Sounds easy, but as I’m new to this, it isn’t!

What I’m blogging about today and code I’m showing you is based on lots of articles i have read on the web. I’m one of those coders that cannot just Google + Copy & Paste, then move on to the next problem (to be resolved by the latter). I need to try and understand what the code is doing. So in the last week i have learnt:

  • JQuery and some JavaScript
  • A little more on how HTTP works behind the scenes using an awesome tool called Fiddler.
  • Specific browser requirements

Now before i move on, i have based my code on the following. Before this i was learning JQuery, so i wanted to amend the JavaScript portion to JQuery, but keeping the same concept:

http://weblogs.asp.net/imranbaloch/archive/2010/04/03/image-preview-in-asp-net-mvc.aspx

In addition my good friend and fellow Web Developer, Shaw Young, helped me with some tweaks! So thank you Imran for teaching me and Shaw for helping me!

Before i start discussing the JQuery, the following is the HTML that the code references.

        <input class="upload" type="file" name="imageLoad2" id="File1"/> <img alt="Preview" id="imgThumbnail2" height="26px" width="26px" /> 

So lets start from the beginning. I have created a JQuery script file, which is bound to the change JavaScript event, using the JQuery handler .change().

$(document).ready(function () {
  var inputTag = ".upload";
  var imgTag = "#imgThumbnail2";
  $(inputTag).change(function () {

I’m presuming you understand JQuery, but the .change() is hooking ANY input tags with the CSS class name of .upload and referencing any image tags with the id of  #imgThumbnail2 (which if you are using id, should be 1!).

Next we create a cloned image tag. We do this, because modern browsers will not allow you to copy the filename/directory values from one tag to another due to security reasons.  We then insert this cloned tag after the original .upload one.

NB: If you query the value in IE9 of the directory, you will be greeted with C:\Fakepath… now.

//-- Create a input attribute with the same type as the original //-- Insert it after the original's location. $('<input>').attr(
{
           class: "upload-clone",
           type: $(inputTag).attr('type'),
           name: "name-clone" }).insertAfter(inputTag);

Next we need to create a hidden form which we will post to one of our action methods Ajaxsubmit.

//--Create a hidden form with an action method pointer to //--our custom controller. $("<form>").attr(
{
           method: "post",
           id: "prototype",
           action: "/ImagePreview/AjaxSubmit" }).appendTo("body").hide();

We then need to change our new form’s encoding. Because different browsers behave differently, we change the attribute using the following.

//--Change the encoding based on the browser, as IE doesn't allow you to//--change the encoding. //--Append our original input to the hidden form. $('#prototype').attr((this.encoding ? 'encoding' : 'enctype'), 'multipart/form-data');

So we can submit the form and its contents, in this case the .upload input tag, we append it to the form, and hide it.

$(inputTag).appendTo("#prototype").hide();

We then use AJAX to submit the input .upload and its contents. Because we set the action method ImagePreview/Ajaxsubmit, this will be called, then the image tag will use the ImageLoad method. The first set is the JQuery and the 2nd is to re-iterate Imran’s method.

JQuery:

//--Use AJAX to post the form, and if successful, load the binary info the //--image tag. $('#prototype').ajaxSubmit(
        {
            success: function (responseText) {
                var d = new Date();

                $(imgTag)[0].src = "/ImagePreview/ImageLoad?a=" +                  d.getMilliseconds();

                $(inputTag).insertAfter('.upload-clone').show();

                $('.upload-clone').remove();
                $('#prototype').remove();

            }

        });

C# Action Methods:

public class ImagePreviewController : Controller {
    #region Ajax Submit
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AjaxSubmit(int? id)
    {
        Session["ContentLength"] = Request.Files[0].ContentLength;
        Session["ContentType"] = Request.Files[0].ContentType;
        byte[] b = new byte[Request.Files[0].ContentLength];
        Request.Files[0].InputStream.Read(b, 0, Request.Files[0].ContentLength);
        Session["ContentStream"] = b;
        return Content(Request.Files[0].ContentType + ";" +         Request.Files[0].ContentLength);
    }
    #endregion #region ImageLoad
    public ActionResult ImageLoad(int? id)
    {
        byte[] b = (byte[])Session["ContentStream"];
        int length = (int)Session["ContentLength"];
        string type = (string)Session["ContentType"];
        Response.Buffer = true;
        Response.Charset = "";
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.ContentType = type;
        Response.BinaryWrite(b);
        Response.Flush();
        Response.End();
        Session["ContentLength"] = null;
        Session["ContentType"] = null;
        Session["ContentStream"] = null;
        return Content("");
    }
    #endregion }

So that’s it, with a little of JQuery magic, sprinkled with MVC goodness, we have an Image Previewing client side code, mixed with some AJAX.

I will try and get a solution up for people to use ASAP. In the meantime, if anyone needs it, let me know and i will email them the code.
Next up i will be:

  1. Adding some client side validation to make sure we are selecting image content types.
  2. Wiring up the JQuery to a HTML Helper using Razor for input file types.
  3. Create a T4 scaffolding template for input types to be re-used.