adrian’s blog

January 31, 2009

Sending mail in .Net – just a few tips

Filed under: Software — Tags: , — Adrian @ 8:29 pm

Sending mails in .Net is actually very easy. In just a few lines you can send you very first mail automatically:

MailMessage mailMessage = new MailMessage();
mailMessage.To.Add(new MailAddress("myfriend@domain.com"));
mailMessage.Subject = "Adrian's blog rocks";
mailMessage.IsBodyHtml = true;
mailMessage.Body = "Check out this cool blog";
SmtpClient emailClient = new SmtpClient();
emailClient.Send(mailMessage);

That’s pretty much it! You’ll probably ask about the from email address and the SMTP server. These are configured in Web.config:

<configuration>
    ...
    <system.net>
    ...
    <!-- the mail settings used to send emails -->
    <mailSettings&gt
      <smtp deliveryMethod="Network" from="admin@domain.com"&gt
        <network host="smtp.domain.com"/&gt
      </smtp&gt
    <mailSettings&gt
    ...
    </system.net>
    ...
<configuration>

But anyway you can specify them too:

mailMessage.From = new MailAddress("admin@domain.com");
SmtpClient emailClient = new SmtpClient("smtp.domain.com");

Multiple recipients

If you want to send your message to multiple recipients, just use message.To.Add. So if you have a string with semicolon(;) separated email addresses here’s the code for you:

String emailAddresses = "a.friend@domain.com; another.friend@domain.com";
foreach (String to in emailAddresses.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries))
{
    mailMessage.To.Add(new MailAddress(to));
}

The same goes for CC, BCC, ReplyTo.

Flag a message

Are you a fan of those follow up message? Let me show you how to send them. The idea is pretty simple: those mail messages have two headers – one for the flag and one for the follow up date. To get/set headers of a mail message just use the Headers property.

mailMessage.Headers["X-Message-Flag"] = "Follow up";
mailMessage.Headers["Reply-By"] = DateTime.Now.AddDays(1).ToString("ddd, dd MMM yyyy HH:mm:ss %K");

The above will send a message to be followed up one day later from the sending time. The format of the date in the Reply-By header is specified in RFC822 and if you want to know how to format a date in .Net, see this. If you just want to send your message use what I compiled for you.

The invalid subject error

If you try to set the message subject to a string that contains invalid characters you will get the error System.Net.Mail: The specified string is not in the form required for a subject. This can be easily fixed with

mailMessage.Subject = Regex.Replace(subject, @"[^ -~]", "");

January 28, 2009

!u@#!^$ “Invalid character” IE error

Filed under: Web — Tags: , , — Adrian @ 7:36 pm

Internet Explorer is probably the worst browser for web development. Or maybe I’m too used to Firefox.
Let me give you just a simple example, that can drive you mad.
Have you ever encountered the below error?

Line: 2
Char: 1
Error: Invalid character
Code: 0
URL: ... 

I did. So I googled a little bit to see what could be the problem and I come over this article. Of course, that wasn’t the problem. Finally, I realized myself: one of the referenced JavaScript files was missing.

I know that this is my mistake, but I’m totally amazed about the usefulness of the IE error messages. It is a missing file, not an invalid character.
Not to mention, that the URL is always the main one, even though the error occurred in one of the referenced JavaScript files and the line reported is not the actual line where the error occured, but increased by 1. But this is already common knowledge.

That’s one of the reasons I always use Firefox for web development, try to stick to the standards and only in the end, test the solution on Internet Explorer too. And there is no decent JavaScript debugger for IE. And …

I also wrote a small HTML, for you to see what I’m talking about.

January 13, 2009

Resize images for mobile web

Filed under: Software, Web — Tags: , , , — Adrian @ 4:08 pm

If you decide that your mobile website won’t be nothing more than a translation of your website, then you have to look into resizing the images too. There are pretty good reasons for doing it:

  • mobile devices supports images only up to a certain file size
  • mobile devices supports images only up to a certain image width and height
  • mobile devices supports web pages only up to a certain total size (page + resources)
  • performance, when it comes to bandwidth
  • user experience, when it comes to rendering capabilities

Next, I will present a short and practical solution, implemented as an aspx page. The page is taking only one parameter (i), which is the URL of the original image, downloads it, resizes it and sends it back to the client. This can also be implemented as an HTTP filter as well: every time an image is requested, it gets the original image, resizes it and pushes it into the response. The advantage as a page is that you can process this way, even images from other servers.
As for how to recognize the user mobile device, we will use my favorite, WURFL. For more information see Mobile device recognition.

I will include here only the C# code with enough comments so I won’t need to say anything else. :D
But before, one more thing: what is the new size of the image? First of all we need the maximum image width and height supported by the user mobile device. Here, WURFL is the solution. Then I made the supposition that the images are optimized for 800×600 and I will reduce the image proportionally to the maximum width and height supported by the mobile device. To not give anomalies, I also introduce a minimum width and height, not to go below.

public partial class MobileImageResizer : System.Web.UI.Page
    {
        // image should not be reduce under this width
        private static int MIN_WIDTH = 24;
        // image should not be reduce under this height
        private static int MIN_HEIGHT = 24;
        // images on the desktop version are optimized for this width
        private static int OPTIMIZED_WIDTH = 800;
        // images on the desktop version are optimized for this height
        private static int OPTIMIZED_HEIGHT = 600;

        protected void Page_Load(object sender, EventArgs e)
        {
            HttpContext context = HttpContext.Current;
            // get the image URL
            String url = context.Request.QueryString.Get("u");

            // if no URL is specified in the u parameter then send a NOT_FOUND error
            if (url == null)
            {
                Utils.Send(context.Response, HttpStatusCode.NotFound);
                return;
            }

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            // specify a timeotu for the request
            // request.Timeout = 10000; // 10s
            // if you want use a proxy for request
            // request.Proxy = WebProxy;
            HttpWebResponse initialResponse = (HttpWebResponse)request.GetResponse();

            // if something went wrong don't try to transform
            if (initialResponse.StatusCode != HttpStatusCode.OK)
                throw new HttpException((int)initialResponse.StatusCode, initialResponse.StatusDescription);

            context.Response.ContentType = initialResponse.ContentType;
            Image image = Bitmap.FromStream(initialResponse.GetResponseStream());

            // get the maximum image size from the WURFL database
            // see my other article about WURFL filter
            int maxWidth = ...;
            int maxHeight = ...;

            // calculate the resize ratio
            double ratio = Math.Min( // final ratio
                    Math.Max( // final width ratio
                        ((double)maxWidth) / Math.Max(image.Width, OPTIMIZED_WIDTH), // width ratio
                        ((double)MIN_WIDTH) / image.Width // minimum width ratio
                    ),
                    Math.Max( // final height ratio
                        ((double)maxHeight) / Math.Max(image.Height, OPTIMIZED_HEIGHT), // height ratio
                        ((double)MIN_HEIGHT) / image.Height // minimum height ratio
                    )
                    );

            if (ratio < 1)
            {
                // if we have to reduce the image
                int newWidth = (int)(image.Width * ratio);
                int newHeight = (int) (image.Height * ratio);

                Image newImage = new Bitmap(newWidth, newHeight, image.PixelFormat);
                Graphics g = Graphics.FromImage(newImage);
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle r = new Rectangle(0, 0, newWidth, newHeight);
                g.DrawImage(image, r);
                newImage.Save(context.Response.OutputStream, image.RawFormat);
            }
            else
            {
                // otherwise simply send the image
                // we don't make bigger the smaller images
                image.Save(context.Response.OutputStream, image.RawFormat);
            }

            // finish
            context.Response.End();
        }
    }

January 10, 2009

Mobile web

Filed under: Web — Tags: , , , — Adrian @ 6:47 pm

Mobile web is a new trend and a website for mobile devices is more like a must have these days. It is more likely that your company has a web site, but if you access it with a mobile device, the user experience could be unpleasant.

It is not easy to create a site for mobile devices and it is definitely hard to maintain. And not only because of the huge amount of mobile devices, but also because you have to keep it in sync with the normal one. Following I’ll give you a few pointers.

But first you have to clearly define your mobile web presence. Sometimes it doesn’t even make sense to invest time and effort into it. Let’s say that your solely company product is an FTP server. Definitely you won’t expect to sell it to mobile users. So your entire mobile website can consist of a page stating the company name and logo, product name and description, the link where you can find out more information by browsing with a non-mobile web browser. The best part is that you don’t have to update it and it could remain like this for many years. And that could be the case with many other products for which the target user is an enterprise one, with required access from a non-mobile web browser, like a SDK, online 3D highly graphical game etc.

On the other side of the coin, is when your company product is an exclusively mobile product, like a game for mobile devices, ring tones etc. Then you can simply have only a mobile web site. Of course the desktop users won’t an experience up to their device capabilities, but they aren’t actually your target and your site is not of any real use to them.

And there is the case where your presence has to be strong in both worlds. Following I will concentrate more on this, but most of the below pointers apply to the above cases as well.

  1. CSS. First of all, your web site has to be CSS-based. Forget about tables, use DIVs. Move all CSS rules into external files. Keep the HTML as clean, simple and free of layout settings as possible. Then supporting a mobile device will be as simply as defining a CSS file.
    You can include a CSS in a page and have it active only for mobile devices using the handheld value for the media attribute of the link tag. Even tough this is very convenient, I wouldn’t recommend to be the only thing to rely on. I would define a series of CSS files for each device or set of devices. So, you would include in your HTML the following lines:

    <link rel='stylesheet' type='text/css' href='desktop.css' media='screen'/>
    <link rel='stylesheet' type='text/css' href='[mobile].css' media='handheld'/>
    <link rel='stylesheet' type='text/css' href='print.css' media='print'/>

    [mobile] should be dynamically generated and it should point to a file corresponding to the user mobile device. Notice also that I didn’t forget about the printable version :) . The CSS media target can be specified also with

    <style type='text/css' href='[mobile].css' media='handheld'>
    </style>

    or directly in the CSS

    @media handheld {
        /* mobile specific CSS rules */
    }
    

    If you want to split the devices and optimize for groups, one important criteria could be the screen resolution.

    Even tough this is a very clean approach, as I already said, I would not recommend this to be the only one, especially for very large and complex websites. The mobile website should be a stripped down version, both in terms of layout (most important) and content.

  2. XHTML. Use XHTML instead of HTML. It is better structured and much easier to maintain and to automatically transform.
  3. Dynamically generated content. Even after using CSS for layout, you still have to have different HTML code, then consider generating automatically on the server the specific parts inside the page. For performance purposes you should have in mind using some kind of cache for those automatically generated parts.
    If your entire website is automatically generated, like a portal or an e-commerce website, then you could have different layouts. But don’t fall into having too many device specific code. That should be maintained as well.
  4. Transcoded content. It is the case when you already have a website, specifically a larger one, more likely on the non-mobile web, and you want to reach the mobile users as well. You should consider implementing an automatic translation tool between the two layouts. Of course, here a CSS based website will make your life much more easier. XHTML too.
    As a translation tool, I would recommend XSLT. If your code is HTML, then you have to convert it first to XHTML.
    Don’t forget to resize the images too. Many devices supports images only up to a certain file size, width or height.
    This is a fast and cheap solution, but probably not the best one. Also take into account here the size of your website, otherwise the translation tool could become more expensive then recreating your entire website. And remember that it comes to a cost in performance.
  5. Real life testing. Consider using for testing real mobile devices, not emulators. Use mobile devices with different screen resolution, operating systems, browsers. Don’t forget about touch screens either.
  6. Performance. Test for performance here too, but be careful how you define it. The bandwidth here is different: smaller pages, smaller images, different number of users etc.

If you’re interested in recognizing user’s mobile device on the server side, see my other article: Mobile device recognition.

I hope these will help you in outlining your mobile web personality, but as I said before, first take a step back and think of what exactly you need, want and invest in this.
The mobile web is for sure a different, but thrilling experience.

Blog at WordPress.com.