Adsense

Sunday, March 04, 2007

Sending mail through Gmail Programatically - C# .Net VS2005 Gmail

I was implementing a simple Contact Us form for a friend's website that would allow users to shoot him an E-mail message from the site. You can send E-mail directly from a .Net application using an SMTP server, but most free web-based E-mail companies wont allow you to use their SMTP servers for stuff like this. I was delighted to find that you could get this working with Gmail. I'll show you a quick sample method that will allow you to do this.
Information You'll Need...
  1. Your Gmail information (Username, Password)
  2. The Gmail SMTP server address (smtp.gmail.com)
  3. The port Gmail uses (465 or 587)
Namespaces used...
  1. System.Net;
  2. System.Net.Mail;
  3. System.ComponentModel;
Key Objects...
  1. MailMessage
  2. SmtpClient
Your Configuration File
<appSettings> <add key="pswd" value="YourGmailPassword"/> <add key="account" value="yourUserName@gmail.com"/> <add key="host" value="smtp.gmail.com" /> </appSettings>
Implementing a simple SendMail method
public void SendMail(string host, int port, string userName, string pswd, string fromAddress, string toAddress, string body, string subject, bool sslEnabled) { MailMessage msg = new MailMessage(new MailAddress(fromAddress), new MailAddress(toAddress)); // Create a MailMessage object with a from and to address msg.Subject = subject; // Add your subject msg.SubjectEncoding = System.Text.Encoding.UTF8; msg.Body = body; // Add the body of your message msg.BodyEncoding = System.Text.Encoding.UTF8; msg.IsBodyHtml = false; // Does the body contain html SmtpClient client = new SmtpClient(host, port); // Create an instance of SmtpClient with your smtp host and port client.Credentials = new NetworkCredential(userName, pswd); // Assign your username and password to connect to gmail client.EnableSsl = sslEnabled; // Enable SSL try { client.Send(msg); // Try to send your message ShowMailMessage("Your message was sent successfully.", false); // A method to update a ui element with a message Clear(); } catch (SmtpException ex) { ShowMailMessage(string.Format("There was an error sending you message. {0}", ex.Message), true); } }


Calling your SendMail method

public void imgSubmit_Click(object sender, EventArgs e) { string pswd = ConfigurationManager.AppSettings["pswd"]; // Your Password string account = ConfigurationManager.AppSettings["account"]; // Your account name (username@gmail.com) string host = ConfigurationManager.AppSettings["host"]; // Your smtp server name (smtp.gmail.com) int port = 587; // The port used to connect to your host if (string.IsNullOrEmpty(pswd) || string.IsNullOrEmpty(account) || string.IsNullOrEmpty(host)) // Validate App Settings ShowMailMessage("Unable to send your message. Configuration Error.", true); else { SendMail(host, port, account, pswd, txtFrom.Text, account, txtBody.Text, txtSubject.Text, true); } }
That's pretty much all there is to it. Your user fills out the form and clicks submit, and you get an E-mail in your Gmail box, send through your Gmail Account

Debugging ActiveX Controls in VS2005 (Attaching To a Process)

I already wrote a post about creating ActiveX controls in Visual Studio 2005. To make life a bit easier, I'm going to tell you how you can debug an ActiveX control that you have built and embedded into your web page.

I deployed my web page to IIS and then bring it up in the browser (http://localhost/ActiveXTest/Default.aspx.) Once you have the page up and can see your ActiveX control, switch to Visual Studio and click on the 'Debug' menu item. Click on 'Attach to Process'.

On the Attach to Process screen, click on 'Select...' next to the Attach to: label. Select Managed Code and click on 'OK'. In the Available Processes section, select 'iexplore.exe' and click on 'Attach'.

That's all there is to it! You should now be able to place break points into your control and debug. (Assuming that there are no issues with your implementation that would prevent you from even getting to the control.)

Creating ActiveX Controls using C# in VS2005

This will be a short tutorial on how to create a simple ActiveX control that opens a windows forms Message Box while living in an aspx page. Pretty useless, I know, but it will illustrate the basics of how to create and interact with an ActiveX control from a web page in Visual Studio 2005.
A co-worker and myself worked on this for a current project and found bits and pieces of this information and figured it would be a great resource to compile it all into one location. It can get a bit tricky (especially if you add in security issues when handling ActiveX control events) but its not too bad.
Step 1
This first step in this tutorial is to create a web project in Visual Studio. I called mine ActiveXTest.
Step 2
Next, add a new Windows Control Library project to your solution.
This project is where you will develop your ActiveX control. Rename the default user control cs file and double click on it to open up the designer. You can build your control just like you would any other Windows User Control by adding controls and code-behind as necessary. This example doesn't need any controls, but I'll add a picture box just so that we can see it on the aspx page.
Step 3
Now that our project is setup with a web project, a Default.aspx page and a Windows Control Library with our new User Control in it, we are ready to turn the User Control into an ActiveX control by exposing and implementing an interface.
Next, create in interface that will expose parts of your ActiveX control to the browser.
public interface IComInterface { string Msg { set; } // Exposes the Msg property through the interface }
Implement this interface in your User Control.
public partial class MessageBoxControl : UserControl, IComInterface { // Implement IComInterface public string Msg { // Implement the Property set{ MessageBox.Show(value); } // When the property's set is called, show the message box } public MessageBoxControl() { InitializeComponent(); } }
You have just created an ActiveX control that is ready to be embeded in a web page and exposes a property (Msg) to COM through an interface (IComInterface).

Step 4

The next step is to embed your newly created ActiveX control in your web page (Default.aspx.) To do this, you will use the <object> tag like this.
<object id="MessageBoxControl " name="MessageBoxControl " classid="ActiveXControls.dll#ActiveXControls.MessageBoxControl "> </object>
The id and name should be self explanatory. The class id is comprised of the name of your dll file, a # sign, and the namespace.classname of your control. That's all it takes to embed the control into your page. There are a couple of thing you will need to do to allow this to happen, but the coding is done.

Other things to consider...

1. You must have a copy of your Windows Control library dll on the same level of your web project as the default.aspx page. The dll cannot contained in the bin folder.
2. Add your local computer as a trusted zone through Internet Explorer. This will help bypass some of the security issues inherent with ActiveX controls. Do this through the Internet Options of Internet Explorer.
3. You may need to increase the trust level of your assembly before it will load correctly in Internet Explorer. You can do this from the .Net Configuration Tool located in the Administrator Tools of the Control Panel. (Configure Code Access Security Policy -> Increase Assembly Trust)
4. Strongly name your ActiveXControl assembly. (Note: You can do this through the properties page of the project.) This must be done prior to registering the dll in the gac.
5. You may also need to register your assembly/dll in the gac before it will work. You can do this by using gacutil from the command line from the directory of your dll. (gacutil /i ActiveXControls.dll) (Note: You might have to do this after every build of the project.)
6. Modify your AssemblyInfo.cs file and change the ComVisible attribute to true. ([assembly: ComVisible(true)]) This is maily when you want to expose ActiveX control events to your web page.
7. Set ISS so that Execute Permissions on your Virtual Directory are set to "Scripts Only". This is the only option in ISS that would work for me when deploying the ActiveX control and accessing it remotely and was a pain to track down.
Step 5

You can then access properties of your control exposed through your interface by using JavaScript on that page. Something similar to this.
<script type="text/javascript"> function showMessageBox(){ var control = document.getElementById('MessageBoxControl'); control.Msg = document.getElementById('txtMsg').value; } </script>
Tips/Tricks

You can add a build event to your Windows Control Library project that will automatically copy it's dll to the web project when you build it. Open the properties of the project by right clicking on it and add a line like this to the build events.

copy "$(TargetPath)" "C:\Projects\vs2005\ActiveXTest\ActiveXTest"

Creating ActiveX Controls using C# in VS2005 (Intro)

We recently had a need to handle communication between an existing windows service (Running on client machines) and the current ASP.Net web application that we are working on. We chose to implement this feature using .Net Remoting and an ActiveX Control that would live on one of our aspx pages.

Implementing an ActiveX control in VS2005 using C# isn't difficult, but there are a lot of little issues that a co-worker and I encountered along the way.

I'll try and list the results of my research and a walk-through of creating a sample project. This will probably span several posts.

The steps that I will cover... Check it out HERE!

1. Create a C# Web Application project

2. Create a Windows Control Library project

a. Note: The Windows Control Library DLL file must be located in the same directory as the aspx page and NOT in the bin folder.

3. Add a user control item to the class library project

a. Creating the user control

b. Implement an Interface on your user control that will exposes members, methods, and events of your user control to COM

4. Create an object in your aspx page that embeds your user control

5. Handle communication between your web application and your ActiveX control using JavaScript

6. Expose and raise/handle user control events using javascript

7. A brief overview of configuring the .Net Framework and zone permissions to allow your web application and ActiveX control to communicate

8. Configuration issues with IIS (set to allow scripts only, not scripts and exes)

9. How to view IE7 error messages to get the exact exception that might be causing you problems.

Check it out HERE!

"Unrecognized configuration section 'connectionStrings'" .Net 2.0

If you get the following error when trying to bring up your IIS hosted web page, you might need to configure IIS to use .Net 2.0 instead of 1.1.

""Unrecognized configuration section 'connectionStrings'" .Net 2.0"

You can do this through the Internet Information Services configuration. (click on RUN from the start menu, type in 'inetmgr' and hit enter.)

Bring up the properties for your web page or virtual directory and click on the ASP.NET tab. Change your ASP.NET version to the appropriate value and try again.

Monday, January 29, 2007

Centering an Element via CSS vs JavaScript...

We recently ran into a situation where we were dynamically showing and centering model popup windows in an ajaxified environment. Our initial implementation had one down side.

We were showing and dynamically centering our div/panels via JavaScript. The windows would very briefly show up in its default location before jumping to center. Not a huge problem, but very annoying.

Our initial approach looked something like this. Statically build a hidden div/panel and when the user triggers a pop up dialog, call the CenterPanel method from JavaScript and show the panel. We were calculating the screen height and width and making it available globally.

The JavaScript process looked something like this...


CenterPanel("<%= SendToGeneralQueuePopupPanel.ClientID %>");


function CenterPanel(panelId){
var panel
= document.getElementById(panelId);
if (panel) {
panel.style.top
= ((screenHeight / 2) - (GetSize(panel.style.height) / 2)) + 'px';
panel.style.left
= ((screenWidth /2) - (GetSize(panel.style.width) / 2)) + 'px';
}
}

The result was a panel that would show up, then jump to the center of the screen. (Annoying)

After getting a bit of time to think about the issue, I remembered a much simpler way to center a control with pure CSS rather than dealing with problematic JavaScript at all. I'd used this technique in other projects and it makes things quite a bit more simple and stops the panel from jumping around the screen.

The CSS method...

We define a Panel to use as the pop that applies our modalPopup CssClass. Notice that the panel's Width is 200 and it's Height is 60.

<asp:Panel ID="PanelPopup" runat="server" CssClass="modalPopup" Width="200" Height="60">
<div style="text-align:center;">
Are you sure you wish to continue?

</div>
<div style="text-align:center;">
<asp:Button ID="ButtonYes" runat="server" Text="Yes" OnClick="ButtonYes_Click" />

<input id="ButtonNo"
type="button" value="No"
onclick="return HidePopupPanel('PanelPopup', '<%= PanelPopup.ClientID %>');" />
</div>
</asp:Panel>

The modalPopup CSS...

.modalPopup{
//Other CSS
left:50%;
margin-left:-100px;
top:50%;
margin-top:-30px;
}

The CSS above sets the left edge of the panel to be aligned with the center of the browser and then adjusts the left margin of the panel by subtracting 100 pixels (which happens to be half of the panel's width.) This centers the panel horizontally. In the same way, the panel is centered vertically by setting the top of the panel to the middle of the screen and then adjusting the top margin by subtracting 30 pixels which is half of the panel's height.

You can do a lot of fun stuff by using this technique. Setting the left, top, right or bottom of a control and then modifying the margins. Play around with it...

Friday, January 26, 2007

Session Management - Facade Pattern - C# .Net VS2005

State Management is a big part of any web application and using the session variable in ASP.NET is one way to persist data throughout a user’s session. Interacting with the session variable is fairly straight-forward…
Session["UserId"] = user.Id;
int id = (int)Session["UserId"];
Session[
"FirstName"] = user.FirstName;
string fName = (string)Session["FirstName"];
You can store any object or primitive into the session variable and retrieve the value at any time throughout the user’s session.

As you might imagine, your project could get fairly convoluted if you are accessing the same (or many different) session variable across many different pages throughout your application. Using explicit string values as your keys can also cause problems if you accidentally typo when entering them or decide to change one later. Throw several developers into the mix and this can turn into a nightmare.

You can alleviate some of this frustration by using an enum that contains all of your session key values. This allows you to make changes much easier, provides a quick reference to what objects you have in the session, and makes calls to the session variable consistent. The new session calls (with the help of an enum) would look like this.
enum SessionKeys {
UserId
= 1,
FirstName
= 2
}
Session[SessionKeys.UserId .ToString()]
= user.Id;
int id = (int)Session[SessionKeys.UserId .ToString()];
Session[SessionKeys.FirstName .ToString()]
= user.FirstName;
string fName = (string)Session[SessionKeys.FirstName .ToString()];
Taking this a step further, you could wrap this functionality into a static class in your project and route all session traffic through this class. By wrapping session calls in properties within this class, you can ensure type safety and make it much more easy to work with the session object.
public static class SessionFacade {
public static int UserId {
get {
return (int)Session[SessionKeys.UserId.ToString()];
}
set {
Session[SessionKeys.UserId.ToString()]
= value;
}
}
public static string FirstName {
get {
return (string)Session[SessionKeys.FirstName.ToString()];
}
set {
Session[SessionKeys.FirstName.ToString()]
= value;
}
}
}
Sessions calls would then look like this.
int id = SessionFacade.UserId;
SessionFacade.UserId
= user.Id;
string fName = SessionFacade.FirstName;
SessionFacade.FirstName
= user.FirstName;
The SessionFacade class acts as a Facade between you and the session object and alleviates much of the frustrations mentioned above. No more misspelled keys, no more huge updates if you want to change a key. Type safety... Who could ask for more?