Microsoft Pro Photo Tools

by agrace 24. September 2008 22:01

Check out the latest version of Pro Photo Tools from Microsoft. It's free to download and play with. It's a set of pretty basic but useful tools enabling you to geotag and geocode your pictures in a very cool way: just drag in your image to the map and the GPS coordinates will be calculated automatically for you. Add a whole slew of other data to your image before saving it back to your folder. The product can also interoperate with Photoshop and has support for 64-bit Windows.

Pro Photos 2

 

You can use Expression Media 2 to leverage even finer details such as three-dimensional maps to accompany your images. This gives you an amazing range of possibilities when it comes to torturing friends and family with the inevitable annual vacation shots... and don't forget the laser pointer ;-)

Pro Photos 2
 

This version of Photo Tools still has all the original features (from the official site):

    * Determine location name automatically
    * Determine GPS coordinates from location name
    * Identify location on a map
    * View images on Windows Live Maps
    * Use Microsoft Virtual Earth for a 3D view of the image location.
    * Edit image metadata
    * RAW support



ASP.NET Email Strategy Pattern

by admin 22. September 2008 18:46

Email Sometimes when building websites, we need to generate email more than once. For example a site could have a contact form and a user-filled form, both generating email to the site owner. You don't need to be able to spout the name of every software pattern verbatim, to recognize the duplication here and the need to somehow factor it out.

We typically use the strategy pattern where we might have several different implementations of something and want to abstract out the common functionality. The strategy is also known as the provider pattern and I prefer this term. An interface is a good candidate data structure to use here because we can stipulate that a client class must implement a mailing method, and we can leave the details to that class. Let's look at some code...

Typical Scenario

Here are some typical Web.config email settings and code to send an email:

<appSettings>
    <add key="ToEmailAddr" value="info@mysite.com" />
    <add key="FromEmailAddr" value="info@mysite.com" />
</appSettings>

<system.net>
    <mailSettings>
        <smtp from="info@mysite.com">
            <network host="smtp.mymailserver.net" port="25" />
        </smtp>
    </mailSettings>
</system.net>

 

using System.Configuration;
using System.Net.Mail;
using System.Web.Configuration;

System.Configuration.Configuration config
  = WebConfigurationManager.OpenWebConfiguration(base.Request.ApplicationPath);
AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("appSettings");

string toAddress = appSettings.Settings["ToEmailAddr"].Value;
string fromAddress = appSettings.Settings["FromEmailAddr"].Value;

SmtpClient smtpClient = new SmtpClient();

MailMessage message = new MailMessage();
message.IsBodyHtml = false
message.Priority = MailPriority.High;
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;

try
{
    message.Subject = "Subject: " + this.subjectBox.Text;
    message.Body = "Sender: " + nameBox.Text.Trim() + "\n";
    message.Body += "Street: " + streetBox.Text.Trim() + "\n";
    message.Body += "City: " + cityBox.Text.Trim() + "\n";
    message.Body += "State: " + stateDropDown.SelectedValue
        + " " + zipBox.Text.Trim() + "\n";
    message.Body += "Email: " + emailBox.Text.Trim() + "\n";
    message.Body += "\n\n" + this.messageBox.Text + "\n\n";

    smtpClient.Send(fromAddress, toAddress, message.Subject, message.Body);
}
catch (Exception ex)
{
    // Log error
}

 

Strategy Pattern

While this particular email example will not save us a whole lot of typing, it does enable us to implement the email functionality differently for each client class that uses it. This may be useful if we had to send mail through several different servers; in such a case we might also want to configure our settings in code, or factor out our Web.config sections. Factoring out parts of your Web.config is another topic and can be used to greatly simplify deployment.

interface IGenerateMail
{
    // Classes using this interface must implement this method
    void SendMail(string to, string from, string subject, string body);
}

 

// Implementing the Strategy Pattern
public class RealtySMTPMailer : IGenerateMail
{
    //(string from, string to, string subject, string message)
    public void SendMail(string from, string to, string subject, string message)
    {
        MailMessage realtyMessage = new MailMessage(from, to, subject, message);
        SmtpClient smtpClient = new SmtpClient();

        realtyMessage.IsBodyHtml = false;
        realtyMessage.Priority = MailPriority.High;
        realtyMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;

        smtpClient.Send(from, to, subject, message);
    }
}

 

// Snippets from revised contact form
...
private RealtySMTPMailer mailProvider;

public Contact()
{
    mailProvider = new RealtySMTPMailer();
}

public Contact(RealtySMTPMailer mailProvider)
{
    this.mailProvider = mailProvider;
}
...

// Send button event handler
System.Configuration.Configuration config
  = WebConfigurationManager.OpenWebConfiguration(base.Request.ApplicationPath);
AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("appSettings");

string toAddress = appSettings.Settings["ToEmailAddr"].Value;
string fromAddress = appSettings.Settings["FromEmailAddr"].Value;

StringBuilder mailBody = new StringBuilder();

mailBody.Append("From:" + " " + nameBox.Text.Trim() + "\n");
mailBody.Append("Address:" + " "
    + streetBox.Text.Trim() + ", "
    + cityBox.Text.Trim() + ", "
    + stateDropDown.SelectedValue + " "
    + zipBox.Text.Trim() + "." + "\n");
mailBody.Append("Email:" + " " + fromAddress + "\n\n");    
mailBody.Append("Message:" + "\n" + messageBox.Text.Trim());

mailProvider.SendMail(fromAddress, toAddress, subjectBox.Text.Trim(), mailBody.ToString());

 

We can now implement email functionality anywhere in the site and change that implementation without breaking code elsewhere. You might notice some refactoring going on in the last snippet; I substituted a string builder to construct the email, as it is more efficient. Remember, when refactoring you must resist the temptation to re-code the logic.

ASP.NET Email Resources

Sending Email with System.Net.Mail - Scott Guthrie

Sending Email in a Development Environment without an SMTP Server

Sending Email from ASP.NET using your Gmail Account




Footer I searched for a long time for a simple CSS solution to the eternal "sticky footer" problem, where the footer goes down to the end of the page. Up to now I have resorted to JavaScript to achieve this, which is not really the most elegant solution. It should be simple, right?

The other day, I stumbled upon what looked like a basic HTML/CSS solution. I wanted CSS that would push the footer to the bottom of the page, irrespective of content height, in an ASP.NET Master Page setup. Thanks to Ryan Fait for this.

It was straightforward enough to get it working for IE7. Firefox 3.0 didn't play nice at first until I moved the wrapper and footer divs out to the master page. Feel free to download the sample below and try it out for yourself - VS 2008 solution. Ignore the red wigglies in the master page. It has been tested in IE7, Firefox 3.0 and Chrome 0.2.149.29.

CSS_Sticky_Footer.zip (19.91 kb)

UPDATE

With master pages you need to take account of the "form" element by  including it in the appropriate CSS selector.

Tags: ,

ASP.NET | CSS