Mike Borozdin's Blog

A blog about programming, web and IT in general

Free .NET 4.0 Hosting

I received an e-mail from DiscountASP which hosting services I was using that they had launched a free beta testing programme of their .NET 4.0 hosting. The beta testing is open to everyone, it’s not limited to the DiscountASP customers.

As their website says you will have the following:

  • Windows Server 2008 R2 Platform
  • .NET Framework 4.0 beta 2
  • 50 MB disk space
  • 50 MB SQL Server 2008 disk space
  • FTP
  • Uses DiscountASP.NET subdomain
  • End Date: Sunday, January 31, 2010
  •  

    http://labs.discountasp.net/netfx4/index.aspx


    Tags:
    Posted by Mike Borozdin on Thursday, December 10, 2009 2:09 PM GMT
    Shout it Kick it!  
    Permalink | Comments (1) | Post RSSRSS comment feed

    AJAX File Upload in ASP.NET with the AsyncFileUpload Control

    Finally, it has become possible to easily add AJAX file uploading capabilities to ASP.NET applications. The newly released version of the AJAX Control Toolkit ships with two new controls, one of them is called AsyncFileUpload control which was designed specially for the above mentioned purpose. It’s really great that a new version of AJAX Control Toolkit has arrived, because the project seemed to be dead, especially since ASP.NET MVC had taken its place on the stage and many developers switched to it and to jQuery which can also be used with ASP.NET WebForms.

    Anyway, it is the time to introduce the control for asynchronous file uploading. First of all, you should download the newest version of the ACT, unpack it and add to the Visual Studio toolbox, or replace the previous versions controls. Actually, you can follow these installation instructions.

    After installing the toolkit, just create a new web site, place a ScriptManager on a web page and eventually drop a AsyncFileUpload. Basically, here is a small code snippet asynchronous image uploading and immediate displaying it on the page.

     Default.aspx

    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

    <%
    @ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <
    html xmlns="http://www.w3.org/1999/xhtml">
    <
    head runat="server">
    <
    title></title>
    <
    script type="text/javascript">
    function
    showUploadConfirmation() {
    alert("Upload finished!");
    }
    </script>
    </
    head>
    <
    body>
    <
    form id="form1" runat="server">
    <
    asp:ScriptManager runat="server" />
    <
    div>
    Just some time to make sure that the page doesn't get reloaded after uploading: <%=DateTime.Now %><br />

    <
    cc1:AsyncFileUpload ID="AsyncFileUpload1" runat="server" UploadingBackColor="Yellow"
    OnUploadedComplete="ProcessUpload" OnClientUploadComplete="showUploadConfirmation" ThrobberID="spanUploading" />
    <
    span id="spanUploading" runat="server">Uploading...</span>
    <
    br />

    <
    img src="" id="imgUpload" alt="" />
    </
    div>
    </
    form>
    </
    body>
    </
    html>

    There are a few points of interest in this piece of code. In this particular example I’m only using some of the AsyncFileUpload attributes.

    OnUploadComplete – the name of a public code-behind method that is invoked after uploading is completeat

    OnClientUploadComplete – as the name suggests it is the same thing but it’s for client-side, therefore it’s just a JavaScript function

    ThrobberID – the ID of a control to display while uploading is in process, please note it can be either a WebForm control or an HTML one but with the necessary runat=”server” attribute

    UploadingBackColor – the background colour of the upload control during the uploading process

    For the complete list of the control attributes, please use this reference page.

    Also, please pay attention at the <img /> that is going to be used for immediate display of an uploaded image.

    The code-behind code is also not difficult to use.

    Default.aspx.cs

    protected void ProcessUpload(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
    {
    string fileName = Server.MapPath("./") + "image.jpg";
    AsyncFileUpload1.SaveAs(fileName);

    ScriptManager.RegisterClientScriptBlock(AsyncFileUpload1, AsyncFileUpload1.GetType(), "img",
    "top.document.getElementById('imgUpload').src='image.jpg';",
    true);
    }

    Here we just have the method used for handling the event. The main idea is not just to save a received file, but also to display an uploaded image immediately. For this purpose we have to use ScriptManager.RegisterClientScriptBlock() that basically injects a portion of JavaScript code into a page. It is also important to notice that we are using top.document.getElementById(), this is because the AsyncFileUpload is still making use of the iframe to make the asynchronous upload possible.


    Tags: ,
    Posted by Mike Borozdin on Monday, October 12, 2009 11:24 AM GMT
    Shout it Kick it!  
    Permalink | Comments (0) | Post RSSRSS comment feed

    Working with Google Maps API in ASP.NET

    Recently I have been working on a project where I needed to make use of some geographical data and I decided to use Google Maps for that. So, in this particular tutorial I will explain how one can start working with the Google Maps API in ASP.NET.

    Basically, the following topic will be covered:

    • How to find a place on the map by address
    • How to let a user choose a place on the map and retrieve its coordinates and save them in a database.

    What is Google Maps API?

    But first we need to learn some basic of working with Google Maps. As a matter of fact when integrating Google Maps in your application you have to use the Google Maps API, which is in fact just a set of JavaScript functions. As a result you don’t interact directly with the Google Maps API in ASP.NET, I mean server-side, but instead you place your code to client-side and work with JavaScript.

    image

     

    So, the Google Maps can be used with any server-side technology/language, like ASP.NET, PHP, Ruby on Rails, Python and etc., but this tutorial is about ASP.NET.

    Getting Google Maps API Key

    The first important step of getting started with the Google Maps API is obtaining the Google Maps API Key. Don’t worry it is free of charge and you receive the key immediately after filling in a form here.

    Creating a Simple Map

    Okay, now it’s the right time to open Visual Studio and create a new web site.

    Then, add the following code to the <head> tag:

     

    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<YOUR_API_KEY>&sensor=false"
            type="text/javascript"></script>
    <script type="text/javascript">
        function initialize() {
            if (GBrowserIsCompatible()) {
                var map = new GMap2(document.getElementById("map"));
                map.setCenter(new GLatLng(51.5, -0.1), 10);
                map.setUIToDefault();
            }
        }

    Don’t forget to change <YOUR_API_KEY> to an appropriate value. As you can see we have just one function called initialize() that creates a new instance of the map object. We also pass the object – a div – that will be a map container. Then, we invoke the setCenter() method that receives two arguments –coordinates and a zoom level. The setUIToDefault() method just adds the UI manipulators, if you remove or comment that line, you will receive a bare map without any UI controls.

    Also, you need to add some code that will run the initialize() function and the HTML code for the map container.

    <body onload="initialize()" onunload="GUnload()">
        <form id="form1" runat="server">
            <div id="map" style="width: 500px; height: 500px"></div>
        </form>
    </body>

    The code is pretty self-explanatory, it just adds the handlers for the onLoad and onUnLoad events of the page and also we put a div that will contain the map, you can adjust its width and height in order to get a bigger or a smaller map.

    After compiling this page you should see a map similar to this one:

    image

    Finding a place by its address

    Well, it was pretty simple, but in real life project you usually have to find a place on the maps by its address. This is also possible with the Google Maps API. All you have to do is to make use of the GClientGeocoder class and its method called getLatLang() that accepts two parameters:

    • address – the address to look for
    • function – a callback function with one parameter point that posses the coordinates of the found place

    So, if we want to find a house where Sherlock Holmes lived we have to write the following code:

    <script type="text/javascript">
            var map;
            var geocoder;
            function initialize() {
                if (GBrowserIsCompatible()) {
                    map = new GMap2(document.getElementById("map"));
                    map.setCenter(new GLatLng(51.5, -0.1), 10);
                    map.setUIToDefault();
    
                    geocoder = new GClientGeocoder();
    
                    showAddress("221B Baker Street, London, United Kingdom");
                }
            }
            function showAddress(address) {
                geocoder.getLatLng(
                    address,
                    function (point) {
                        if (!point) {
                            alert(address + " not found");
                        }
                        else {
                            map.setCenter(point, 15);
                            var marker = new GMarker(point);
                            map.addOverlay(marker);
                            marker.openInfoWindow(address);
                        }
                    }
                );
            }
            </script>

    Also, we create a map overlay that will contain the address information, for this purpose we create an instance of the GMarker class and use the openInfoWindow() method.

    User Interaction with Map

    Okay, but what if we want to let user enter an address in a form and find its on the map? No problems! Just add the necessary field and write an event-handler.

    <script type="text/javascript">
            var map;
            var geocoder;
            function initialize() {
                if (GBrowserIsCompatible()) {
                    map = new GMap2(document.getElementById("map"));
                    map.setCenter(new GLatLng(51.5, -0.1), 10);
                    map.setUIToDefault();
    
                    geocoder = new GClientGeocoder();
                }
            }
            function showAddress() {
                var txtAddress = document.getElementById("<%=txtAddress.ClientID %>");
                var address = txtAddress.value;
                
                geocoder.getLatLng(
                    address,
                    function (point) {
                        if (!point) {
                            alert(address + " not found");
                        }
                        else {
                            map.setCenter(point, 15);
                            var marker = new GMarker(point);
                            map.addOverlay(marker);
                            marker.openInfoWindow(address);
                        }
                    }
                );
            }
            </script>
    </head>
    <body onload="initialize()" onunload="GUnload()">
        <form id="form1" runat="server">
            <div>
                <asp:TextBox ID="txtAddress" runat="server" />
                <input type="button" value="Find" onclick="showAddress();" />
            </div>
        
            <div id="map" style="width: 500px; height: 500px"></div>
        </form>
    </body>

    Letting Users to Manually Select a Place on the Map

    Well, finding a place by its address is certainly cool, but we can add yet another level of interactivity to our map. Basically, we can let users to use manually choose a place on the map by just dragging a marker.

    <script type="text/javascript">
            var map;
            var geocoder;
            function initialize() {
                if (GBrowserIsCompatible()) {
                    map = new GMap2(document.getElementById("map"));
                    var center = new GLatLng(51.5, -0.1);
                    map.setCenter(center, 10);
                    map.setUIToDefault();
    
                    var marker = new GMarker(center, { draggable: true });
                    map.addOverlay(marker);
                    marker.openInfoWindow("Drag the marker to a specific position");
    
                    GEvent.addListener(marker, "dragstart", function() {
                        map.closeInfoWindow();
                    });
    
                    GEvent.addListener(marker, "dragend", function() {
                        var hdnLat = document.getElementById("<%=hdnLat.ClientID %>");
                        var hdnLng = document.getElementById("<%=hdnLng.ClientID %>");
    
                        hdnLat.value = this.getLatLng().lat();
                        hdnLng.value = this.getLatLng().lng();
    
                        marker.openInfoWindow("New position has been set");
                    });
                }
            }
            </script>
    </head>
    <body onload="initialize()" onunload="GUnload()">
        <form id="form1" runat="server">
            <asp:HiddenField ID="hdnLat" runat="server" />
            <asp:HiddenField ID="hdnLng" runat="server" />
            <div id="map" style="width: 500px; height: 500px"></div>
            <asp:Button ID="btnSubmit" runat="server" Text="Submit" 
                onclick="btnSubmit_Click" />
        </form>
    </body>

     

    If you look at the HTML code, then you will notice that we have added to hidden field that will contain the coordinates of a chosen place, so the first field is for keeping the latitude and the second one is for keeping the longitude. This time when creating a marker we set its options and one of the option is “draggable: true”, so it lets users to drag the marker over the map. Then, we should add event handlers, the main event is “dragend”. It occurs ever time a user place a marker on a new place. As a result, in its event handler we receive the coordinates of a new position and save them in the hidden fields.

    Also, we wrote an event handler for the “dragstart” event, just to close the info window while dragging the marker.

    In a real world application there would be some server-side code that would place the received coordinates into a database, but in this particular case, we will just output them:

     

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        Response.Write("Latitude: " + hdnLat.Value + " Longitude: " + hdnLng.Value);
    }

     

    Passing the Coordinates from Server-Side to Google Maps

    Now, what if we have the coordinates stores somewhere in the database and want to point to that place on the map? Well, it’s still not difficult. We just have to pass the values from server-side to JavaScript.

    <script type="text/javascript">
            var map;
            function initialize() {
                if (GBrowserIsCompatible()) {
                    map = new GMap2(document.getElementById("map"));
                    
                    var lat = <asp:Literal ID="ltrLat" runat="server" />;
                    var lng = <asp:Literal ID="ltrLng" runat="server" />;
                    
                    var center = new GLatLng(lat, lng);
                    
                    map.setCenter(center, 10);
                    map.setUIToDefault();
                    
                    var marker = new GMarker(center);
                    map.addOverlay(marker);
                    marker.openInfoWindow("Here");
                }
            }
            </script>

    The easiest way to achieve this is to use the ASP.NET Literal controls that doesn’t generate any tags around their values.

    Since, those Literal controls are outside of the form tag, we have to use the FindControl() method to access them in code-behind:

    protected void Page_Load(object sender, EventArgs e)
    {
        Literal ltrLat = (Literal)FindControl("ltrLat");
        Literal ltrLng = (Literal)FindControl("ltrLng");
        
        ltrLat.Text = "51";
        ltrLng.Text = "0";
    }

    Conclusion

    In this tutorial we have covered the basics of working with the Google Maps API. We have learnt how to add a map on a page, how to use geo coding for finding a place by its address on the map. We have also got to know how we can let users interact with a map by dragging a marker and how to receive the marker coordinates and store them on server-side. Finally, we have learnt how to pass the coordinates stored on server-side to the Google Maps API and point to that place on a map.

    Also, in this tutorial version 2 of the API was covered, however the 3rd version is currently in Google Labs.

    Resources

    The main resource for the developers willing to work with the Google Maps API is certainly the Google Code reference page.


    Tags:
    Posted by Mike Borozdin on Tuesday, July 28, 2009 6:34 AM GMT
    Shout it Kick it!  
    Permalink | Comments (3) | Post RSSRSS comment feed

    Put EntityDataSource Attributes to Code-Behind

    The EntityDataSource control is a very powerful one. It allows you to rapidly create database driven application. You don’t have to manually write code for extracting, modification and deleting records from the database. Moreover since this code is backed by Entity Framework, you are not tied up with a particular database schema and can easily change it or even choose other database application.

    However when working with EntityDataSource sometimes I feel like I using plain old SqlDataSource and simply have too much unnecessary code in my .aspx files. For instance, you may end up have code like this one:

    <asp:EntityDataSource ID="EntityDataSource1" runat="server" 
        ConnectionString="name=NorthwindEntities" 
        DefaultContainerName="NorthwindEntities" EnableDelete="True" 
        EnableInsert="True" EnableUpdate="True" EntitySetName="Products" Include="Categories, Suppliers" AutoGenerateWhereClause="true">
        <WhereParameters>
            <asp:QueryStringParameter Type="Int32" Name="CategoryID" QueryStringField="CategoryID" />
            <asp:QueryStringParameter Type="Int32" Name="SupplierID" QueryStringField="SupplierID" />
        </WhereParameters>
    </asp:EntityDataSource>

    That certainly isn’t cool at all. Because it simply shouldn’t be in an .aspx file, not only because it breaks application layers, but simply because it inconvenient. It clutters .aspx files which should be templates only. What if a designer meets code like this? What if accidently change something?

    Instead it’s reasonable to move all these lines of code to code-behind.

    So, in your .aspx file you just leave this declaration:

    <asp:EntityDataSource ID="dsProducts" runat="server" />

     

    While put all the attribute assignments to code-behind:

    NorthwindEntities db = new NorthwindEntities();
    
    dsProducts.ConnectionString = db.Connection.ConnectionString;
    dsProducts.DefaultContainerName = "NorthwindEntities";
    dsProducts.EntitySetName = "Products";
    dsProducts.Include = "Categories, Suppliers";
    
    dsProducts.EnableUpdate = true;
    dsProducts.EnableInsert = true;
    dsProducts.EnableDelete = true;
    dsProducts.AutoGenerateWhereClause = true;
    
    dsProducts.WhereParameters.Add(new QueryStringParameter("CategoryID", TypeCode.Int32, "CategoryID"));
    dsProducts.WhereParameters.Add(new QueryStringParameter("SupplierD", TypeCode.Int32, "SupplierID"));

     

    In fact, the same technique applies to any other data source control, like LinqDataSource or even ObjectDataSource.


    Posted by Mike Borozdin on Monday, March 23, 2009 8:43 AM GMT
    Shout it Kick it!  
    Permalink | Comments (6) | Post RSSRSS comment feed

    CSS Class Names Instead of ASP.NET Client IDs

    In ASP.NET the client IDs of controls are often really unpredictable. When you need to add some JavaScript code that works with rendered controls you have to know their IDs. But usually an ID looks like something like this: “ctl00_contentBody_txtStreet”. There are several methods for overcoming that difficulty explained here. However they require writing additional code or even creating your own controls inherited from the original ones.

    But there is one simply but yet dirty way of addressing HTML elements rendered by ASP.NET. Do you remember that you can assign the CssClass attribute to any server control? Do you remember the jQuery selector that allows you to retrieve the elements with the specified CSS class? So, we can use it!

    The pattern is simple:

    <asp:TextBox ID="txtStreet" runat="server" CssClass="txtStreet" />

    You just add the CssClass attribute and give it a unique value.

    Then you can retrieve the value of the element or perform any other manipulation with jQuery:

    alert($('.txtStreet').val());

    Pretty simple. Although you must remember that it can take some time in case you have a long page because it will look through all the HTML tags to find the one with the given class name. At the same time for fast execution you can specify which elements to look for, you can simply add a tag name before, for instance “input” or a jQuery attribute – “:input”:

    alert($('input.txtStreet').val());

    Tags:
    Posted by Mike Borozdin on Thursday, February 26, 2009 1:32 AM GMT
    Shout it Kick it!  
    Permalink | Comments (9) | Post RSSRSS comment feed

    Creating a Simple Ad Rotation User Control with LINQ to XML

    Download files

    Although there is a built-in control for advertisement rotation in ASP.NET, it is capable of showing image ads only. However, in the real life you often have to deal with the ads that require some JavaScript code, for instance, you want to put there AdSense code or want to use Flash banners instead of images. Thus, if you want to rotate complex ads, you have to develop your own control.

    In this particular tutorial I'll show you how to create a very simple, but rather functional user control that will randomly show an ad from an XML file of the following format:

    <Advertisements>
        <Ad>
            <Html>
                <![CDATA[
                    Some HTML code
                ]]>
            </Html>
        </Ad>
        
        <Ad>
            <Html>
                <![CDATA[
                    Some other HTML code
                ]]>
            </Html>
        </Ad>
    </Advertisements>

     

    Well, as you can see, it's very very simple, there is even no NavigateUrl element, but we don't even need, because we can always put a link into the HTML element, besides usually we use something similar to AdSense, so there is no need defining the URL.

    The control will accept have only one attribute - AdvertisementFile - which points to an XML file with ads. So, to ad a control, you just have to place a similar code:

    <uc1:HtmlAdRotator runat="server" AdvertisementFile="~/App_Data/ads.xml" />

     

    Let's start creating it. We should add a new user control to our web site, then put a <div> that will hold the content of advertisements.

    <div id="adContent" runat="server"></div>

     

    In the code-behind we define the only attribute the user control has, please note that we use a neat feature of C# 3.0 that simplifies creation of properties. In the Page_Load() method we extract the data from the specified XML file and pick-up a random ad from there. We use LINQ to XML for XML file parsing.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Xml.Linq;
    
    public partial class HtmlAdRotator : System.Web.UI.UserControl
    {
        public string AdvertisementFile { get; set; }
        
        protected void Page_Load(object sender, EventArgs e)
        {
            XDocument xAds = XDocument.Load(Server.MapPath(AdvertisementFile));
    
            var ads = from a in xAds.Descendants("Ad")
                      select (string)a.Element("Html");
    
            Random rand = new Random();
            var ad = ads.ElementAt(rand.Next(ads.Count()));
            adContent.InnerHtml = ad;
        }
    }

    So, with ASP.NET you can easily build your own control suits your needs in a few minutes, while LINQ to XML helps you to extract the data in a very elegant way.

    Download files


    Tags: ,
    Posted by Mike Borozdin on Saturday, August 30, 2008 2:43 PM GMT
    Shout it Kick it!  
    Permalink | Comments (3) | Post RSSRSS comment feed

    ASP.NET Myths Busted

    busted Having read a great variety of forum and blog posts, I met a lot of misconceptions about ASP.NET that definitely made people to turn away from ASP.NET. I won't argue whether ASP.NET is better than PHP (or Ruby on Rails) or not, instead I'll try to bust those myths.

     

     

     

    The common myths are:

    • ASP.NET is slow
    • ASP.NET produces non XHTML compliant code
    • ASP.NET validators work in IE only
    • ASP.NET produces dirty HTML code that is full of tables
    • ASP.NET is only about drag-n-drop controls
    • ASP.NET doesn't allow you to use any other databases except Microsoft SQL Server
    • ASP.NET doesn't allow you to use friendly URLs

    ASP.NET is slow

    That is certainly wrong. This misconception is caused by dynamic compilation, when an ASP.NET application is accessed for the first time it gets compiled unless it wasn't pre-compiled before. This leads to a delay in page loading. However, the next requests are served much faster.

    ASP.NET produces non XHTML compliant code

    Wrong. In fact, ASP.NET since its 2.0 version produces XHTML compliant code.

    ASP.NET Validators work in IE only

    First, all ASP.NET validators perform server-side validation that is surely cannot be browser dependent. Second, client-side validation works in any modern browser.

    ASP.NET produces dirty HTML code that is full of tables

    Well, some ASP.NET controls really output the code that is full of tables, however due to the extensible nature of ASP.NET you can write your own adapters that will extend the current controls and make them produce clean tableless code. Actually, you don't need to write adapters yourself, there is already a good set of ones available for free download.

    ASP.NET is only about drag-n-drop controls

    No. Although Visual Studio allows you drag controls from the Toolbox in the visual or in the source code, you still can write code yourself, IntelliSense helps a lot with that. Even if you use the drag-n-drop method and the visual tools, you still can see all the changes in the source view. Basically, those tools don't hide anything from you, they just generate the code that you can always view and modify.

    ASP.NET doesn't allow you to use any other databases except Microsoft SQL Server

    No. You can you any database that has a .NET provider. At the present time, you can find providers for MySQL, Oracle, DB2, PostgreSQL, Informix, Sybase, sqlite.

    ASP.NET doesn't allow you to use friendly URLs

    No. Just read some tutorials, for example, this one. There is also a module for IIS 7 that provides a mod_rewrite style of URL rewriting.

    ASP.NET MVC Framework

    If you want to have 100% control over HTML code, then you should definitely have a look at ASP.NET MVC Framework.

    Conclusion

    I think there are some more misconceptions. Anyway, if you already developer web sites with ASP.NET, then you are likely to know the truth, however if you develop web application with some other tools or want to start web programming, I recommend to take a closer look at ASP.NET. Sometimes, it is not a best option to read opinions on web forums that tend to be biased sometimes. You'd better visit some comprehensive resources, like www.asp.net and msdn.microsoft.com.


    Tags:
    Posted by Mike Borozdin on Wednesday, August 27, 2008 9:29 AM GMT
    Shout it Kick it!  
    Permalink | Comments (9) | Post RSSRSS comment feed

    High Quality Image Resizing with .NET

    I want to proceed with telling how to deal with uploaded images with ASP.NET. I have already showed how to resize images. However, that resizing method isn't perfect. It doesn't produce images of high quality. Even though it just shrinks images, the quality of resized images don't match the quality of original images, the produced quality usually appears to be worse. Sure, there is a neat solution. We just need to use the HighQualityBicubic Interpolation mode. Sounds difficult? In fact, it's not difficult to implement, just need to add a few lines of code,  but the result is great.

    Here are two images, the left is made with a simply resizing method, while the right one is made with a resizing method. Note, that it doesn't have noise on the buildings and the right image has the better contrast.

    low high

    The code is:

    private Bitmap ResizeImage(Stream streamImage, int maxWidth, int maxHeight)
    {
        Bitmap originalImage = new Bitmap(streamImage);
        int newWidth = originalImage.Width;
        int newHeight = originalImage.Height;
        double aspectRatio = (double)originalImage.Width / (double)originalImage.Height;
    
        if (aspectRatio <= 1 && originalImage.Width > maxWidth)
        {
            newWidth = maxWidth;
            newHeight = (int)Math.Round(newWidth / aspectRatio);
        }
        else if (aspectRatio > 1 && originalImage.Height > maxHeight)
        {
            newHeight = maxHeight;
            newWidth = (int)Math.Round(newHeight * aspectRatio);
        }
    
        Bitmap newImage = new Bitmap(originalImage, newWidth, newHeight);
        
        Graphics g = Graphics.FromImage(newImage);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
    
        originalImage.Dispose();
        
        return newImage;     
    }

    You can read more on different interpolation mode here.

    You can also download the project files here, they include uploading and high quality resizing.


    Tags:
    Posted by Mike Borozdin on Monday, August 25, 2008 2:53 AM GMT
    Shout it Kick it!  
    Permalink | Comments (14) | Post RSSRSS comment feed

    ASP.NET Image Uploading (part II)

    In the k">previous tutorial I showed how to handle image uploads, how to validate some things and finally how to resize images retaining their proportions. This time I'll show you how to prevent uploading of files which size exceeds the defined limit. Well, this is not difficult to implement,  however there are some pitfalls I'll tell you about later.

    Let's create a validator that will check if the size of an uploaded file is greater than the limit you set. We use a  CustomValidator for this.

    <asp:CustomValidator ID="valFileSize" runat="server" 
        ErrorMessage="The image exceeds 10 MB" 
        onservervalidate="valFileSize_ServerValidate" Display="Dynamic" />

     

    The method that actually performs the validation looks like this one:

     

    protected void valFileSize_ServerValidate(object source, ServerValidateEventArgs args)
    {
        if (IsValid)
        {
            int maxSize = 5 * 1024 * 1024;
            if (fileImage.PostedFile.ContentLength > maxSize)
            {
                args.IsValid = false;
            }
        }
    }

    Why do we check if the page is valid in the validation method? We check it, because the file size validation has sense only if there is an uploaded file and this file is an image. We should ensure that the validator that checks the file size is executed after all other validators, in order to make sure we should just put the corresponding CustomValidator after the other ones. On the other hand, we can have other fields on the form that we also want to validate and those fields are not connected to file uploading, in this case we can use a boolean field that will indicate whether file uploading is correct or not.

    Well, if you run the web site and upload an image that is larger than 4 MB, you are likely to get a server error. This error is caused by uploading a file which size is larger than the maximum allowed size that is usually set to 4 MB. In order to extend that amount, you must correct Web.config, basically you need to set the maxRequestLength attribute of the httpRuntime element.

    <httpRuntime maxRequestLength="20480"/>

     

    In this example the maximum uploaded file size is set to 20 MB, because you set the value in KB, so 20480 = 20 * 1024.

    You may also want to to set the value of the executionTimeout which will allow longer uploads.

    However, you still cannot prevent a server from displaying an error if an uploaded file is larger than the value in Web.config, so it's recommended to set a deliberately large value and validate the file size programatically.


    Tags:
    Posted by Mike Borozdin on Sunday, August 24, 2008 9:21 AM GMT
    Shout it Kick it!  
    Permalink | Comments (1) | Post RSSRSS comment feed

    Correction to the Article on ASP.NET Image Uploading

    I apologize, there were few mistakes in the article on ASP.NET Image Uploading. There was a logic error in the resizing method. Furthermore, I decided to use the <asp:FileUpload /> control instead of the HTML input, FileUpload automatically adds a proper encryption type to the form.

    The article is still available by its previous URL, but now it's correct, as well as the project files.


    Tags:
    Posted by Mike Borozdin on Saturday, August 23, 2008 8:47 AM GMT
    Shout it Kick it!  
    Permalink | Comments (0) | Post RSSRSS comment feed