So I've been meaning to make this blog happen now for, what? A about a year? Heh. It's high time I got this baby off the ground. Well, let's get back into the swing of things with another fun story. This one happened to me yesterday. A client called to tell me they were having trouble with a website I'd built for them. I asked them to send me a screenshot of the error message, and what I got was a Firefox display of the standard ASP.NET error screen. In big red letters the error message read: "SQL Server does not exist or access denied." I haven't changed anything on this app in well over a year, so that came as quite a surprise.
My thought process went as follows:
1. Can't connect to the SQL Server? Let me try it. Hmmm, I can connect just fine from here. That's weird.
2. What page is having the error? Survey.aspx ... hmmm, I don't remember writing that. Let me check in the project. Weird, it isn't there.
3. Wait a sec, what's that "error in application /xyz" text all about? My app was called "abc". Did they move it??
4. Holy shit. This is a completely different URL. This isn't my site at all.
They called me to complain about an error on a completely different website that I've never even heard of. Ahh, clients. :)
Having written no less than two introductary posts, I suppose it's high time I wrote something worthwhile to my fellow tech bloggers. This post goes out to all the ASP.NET coders reading my blog. Both of you.
If you've created more than a few websites, you probably know that sending an email is a requirement in almost every site you'll ever be asked to build. It's such a ubiquitous feature that it's even a part of the simplest practical website to actually require server side scripting: the form mailer. And while sometimes plain text emails will suffice, other times the situation calls for the prettier presentation of HTML emails.
If you're like me, you'll find that a lot of your code resembles this:
string html = "";
html += "<html>\n";
html += " <head>\n";
html += "\n";
html += " <style type=\"text/css\">\n";
html += " body,td \n";
html += " {\n";
html += " font: 12pt Arial; \n";
html += " }\n";
html += " </style>\n";
html += "\n";
html += " </head>\n";
html += "<body>\n";
html += "\n";
html += "<div id=\"thanksdiv\">\n";
html += "Thank you for your order!\n";
html += "</div>\n";
html += "\n";
html += "<div id=\"bodydiv\">\n";
html += "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n";
html += "<tr><td>\n";
...
return html;
There are two big problems with this approach. The first is time of development: first, you have to write & test the HTML. Then, you have to convert it into code, inserting the code to append a string, escape all the embedded double quotes, and close the string. The second problem is maintenance. What happens if you need to change the email?
What would be ideal is if you could have the flexibility of using Visual Studio's HTML preview functions, while still maintaining the ability to send the email as a string. Enter an unorthodox use of UserControls.
Instead of dynamically building a string that hardcodes the body of the email, put the HTML in a UserControl, like this:
EmailBody.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="EmailBody.ascx.cs" Inherits="EmailBody" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Page Title</title>
<style type="text/css">
body
{
font: 12pt Arial;
color: red;
}
</style>
</head>
<body>
<h3>Thank you for your order!</h3>
<p>Your email address is <%=EmailAddress %>.</p>
</body>
</html>
EmailBody.cs:
public partial class EmailBody : System.Web.UI.UserControl
{
private string email = "";
public string EmailAddress
{
get { return email; }
set { email = value; }
}
}
To get the body of the email, rendering the UserControl to a string using this method:
public static string GetEmailBody(UserControl ctl)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter( sb );
HtmlTextWriter htw = new HtmlTextWriter( sw );
ctl.RenderControl( htw );
return sb.ToString();
}
When it's time to send the email, get the body of the desired user control like this:
EmailBody email = (EmailBody) LoadControl("~/EmailThankYou.ascx");
email.EmailAddress = "charliekilian@gmail.com";
string body = EmailManager.GetEmailBody((UserControl) email);
Note how we set the necessary properties to render the control properly.
That's it! I hope you find this tip useful!
This happened to me six months ago. I've been saving it as an introductary type post for Cödenfreude ever since. Never mind the fact that I already wrote an introduction. *waves hands* Pay no attention to the mand behind the curtain! There is nothing to see here! Um, except this story I'm about to tell.
This is a live chat support with a Register.com representative. Keep in mind, I had to enter my email address before I could even establish a chat session.
Peter S: Thank you for visiting Register.com's Live Support. How can I help you?
Charlie: I am trying to set my DNS servers to use a two third party servers.
Charlie: I am getting the following error message: rahvin.tk2.com is an invalid format for a DNS name
Charlie: why am i getting this?
Charlie: rahvin.tk2.com is the primary server, ns2.afraid.org is the secondary.
Peter S: Please let me know your domain name.
Charlie: longlastinglinks.com
Peter S: Thank you for the domain name. Please give me a few minutes while I check the records for you.
Peter S: Thank you for waiting.
Peter S: Please let me know the DNS servers you wish to keep.
Charlie: Didn't I just tell you that?
Charlie: rahvin.tk2.com is the primary, and ns2.afraid.org is the secondary
Peter S: Charlie, I am sorry the name server which you wish to keep are not in right format.
Charlie: what does that even mean?
Peter S: rahvin.tk2.com name server is not yet registered.
Charlie: with who?
Peter S: Can you paste the name server setting information which you got from your Hosting company?
Charlie: yes
Charlie: it's rahvin.tk2.com, the IP is 158.247.218.187.
Charlie: and ns2.afraid.org, the IP is 69.94.1331.63.
Peter S: Can you please log in to your Account manager?
Charlie: Done. I'm there.
Peter S: Okay.
Peter S: Please click on the domain name for which you wish to change the name server entries.
Charlie: done.
Peter S: And once you click please scroll down now.
Charlie: done.
Peter S: Can you see the option ADVANCED TECHNICAL SETTINGS ?
Peter S: It is at the bottom.
Charlie: yes
Peter S: Now please click on the "Manage Registered Name Servers".
Charlie: done, i'm there.
Peter S: Please wait.
Peter S: Please wait.
Peter S: Can you please answer the secret question on file?
Peter S: [question redacted by Charlie]
Charlie: [answer redacted by Charlie]
Peter S: Thank you for verification.
Peter S: Please wait while I make all the changes for you.
Charlie: um
Charlie: but i want to know how to make them myself.
Peter S: Thank you for waiting.
Peter S: Charlie, I will have to forward your request to our appropriate department.
Peter S: Please be assured they will be contacting you soon with all the information.
Peter S: They will be contacting you through email.
Peter S: Please let me know by which email address you wish to be contacted.
Charlie: charliekilian@gmail.com
Charlie: i have another question for you
Peter S: Yes please.
Charlie: what color is your hair?
Charlie: consider that a turing test.
Peter S: Sorry, please explain.
Charlie: actually, that answers my question perfectly adequately.
Charlie: thanks!
Hello! My name is Charlie Kilian. Welcome to my new tech blog, Cödenfreude! I've blogged before as a political blogger. Chances are, though, that you don't actually care about that. If I'm wrong, well, Google is your friend.
I should probably introduce myself. I'm a software developer from Omaha, Nebraska. I specialize in .NET development -- both Windows Forms and ASP.NET, though recently my focus has been on the latter. I work for Lutz Software, which is a division of the accounting firm Lutz & Company. In our tech group, there are currently about 13 people. Of those, only about five of us are what you'd call pure programmers. And of those, only one -- me -- focuses on .NET development. Everyone else works in VBA with Microsoft Access. But with time that will be changing.
If you've noticed that my company is a pure Microsoft shop, well, you're right. But I've been known to dabble in Linux and such technologies before. For one thing, I own one of these, which I highly recommend. Back in the day (which was, um, 1998), I broke into the technology industry as a sysadmin working for KansasNet. Almost everything there was Linux based, and that's how I I got my start in web development writing Perl for Apache web servers. After that, I transitioned to Frontier Consulting Group in Manhattan, Kansas, working on VB6 and ASP using Access and SQL Server as a backend, before moving on to found Aphelion Studios in Wamego, Kansas. There, we moved back to the cheaper Linux development, specializing in PHP with a MySQL backend.
But for the last three and a half years, it's been all Microsoft, all the time. When I first started at Lutz, that also meant all Access, all the time. Since I personally hate Microsoft Access with the burning passion of a thousand firey suns, when I had the opportunity to transition into the .NET world, I jumped at it. I'm currently working on growing our .NET operations. For now, it's just me, working as a jack of all trades, starting from database design and working all the way through to final release at the end of the development cycle. I'm also doing a lot of .NET work on the side, which I'm sure I'll be writing about. Notably, I'm doing some development on NetTiers, a set of templates for Codesmith that are used to generate a kickass DAL and BLL
.
This concludes your friendly host's introduction. I do hope you'll check back and leave lots of comments. Nothing warms a blogger's heart (and ego!) like feedback.