First of all, I am a php developer and most of .net is alien to me which is why I am posting here!
I just migrated over a site from one set of webhosting to another. The whole site is written in .net. None of the site is database driven so most of it works, except for the contact form. The output on the site simple states there was an error with "There has been an error - please try to submit the contact form again, if you continue to experience problems, please notify our webmaster." This is just a simple message it pops out of it gets to the "catch" part of the email function.
I went into web.config and changed the parameters:
<emailaddresses>
<add name="System" value="roeland#hoyespharmacy.com"/>
<add name="Contact" value="roeland#bythepixel.com"/>
<add name="Info" value="roeland#bythepixel.com"/>
</emailaddresses>
<general>
<add name="WebSiteDomain" value="hoyespharmacy.com"/>
</general>
Then the .cs file for contact contains the mail function EmailFormData():
private void EmailFormData()
{
try
{
StringBuilder body = new StringBuilder();
body.Append("Name" + ": " + txtName.Text + "\n\r");
body.Append("Phone" + ": " + txtPhone.Text + "\n\r");
body.Append("Email" + ": " + txtEmail.Text + "\n\r");
body.Append("Fax" + ": " + txtEmail.Text + "\n\r");
body.Append("Subject" + ": " + ddlSubject.SelectedValue + "\n\r");
body.Append("Message" + ": " + txtMessage.Text);
MailMessage mail = new MailMessage();
mail.IsBodyHtml = false;
mail.To.Add(new MailAddress(Settings.GetEmailAddress("System")));
mail.Subject = "Contact Us Form Submission";
mail.From = new MailAddress(Settings.GetEmailAddress("System"), Settings.WebSiteDomain);
mail.Body = body.ToString();
SmtpClient smtpcl = new SmtpClient();
smtpcl.Send(mail);
}
catch
{
Utilities.RedirectPermanently(Request.Url.AbsolutePath + "?messageSent=false");
}
}
How do I see what the actual error is. I figure I can do something with the "catch" part of the function.. Any pointers?
Thanks!
Change the catch to
catch(Exception ex)
{
throw;
}
The ex variable will hold your exception information, so you can put a breakpoint there. It'd be easier to step through it, but you can just throw the error as well.
Comment out Utilities.RedirectPermanently(Request.Url.AbsolutePath + "?messageSent=false");
and replace it with throw;
What development environment are you using?
It's probably best to use Visual Studio (Express if you don't have the full version), and debug this code, hitting F11 to step through each statement until it breaks. Then you should have access to more information.
I would suggest logging in the long term (such as log4net). But for the sake of speed try changing your catch statement to look like:
catch(Exception e)
and then use the debugger in VS to explore the actual exception.
Place a breakpoint on the first line of the EmailFormData method and run the application in debug mode. You can then step through the code line by line.
Related
I have to debug an old VB.NET 2.0 code of someone who has left the company. We have a production system (let us call it http://prod) and a test system (http://test). Both are nearly similiar including a documents repository. When looking at docs in production, all the hyperlinks showing up at the bottom are okay (meaning they say something like http://prod/download.ashx?id={GUID}).
However in test it is the same (http://prod/download.ashx?id={GUID}), even it should be http://test/download.ashx?id={GUID} instead.
After hours of debugging I have found the relevant line of code:
html += "<td><a href='" + HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "/") + "int/download.ashx?id=" + row.Item(0).ToString() + "' target='_blank' class='" + row.Item(3).ToString() + "'>" + row.Item(1).ToString() + "</a>" + privat + "</td><td>" + row.Item(2).ToString() + "</td>"
Looking at html this shows i.e.
"<table class='table_dataTable'><thead><tr><td>Name</td><td>Jahr</td></tr></thead><tbody><tr><td><a href='http://prod/int/download.ashx?id=4d280886-db88-4b25-98d8-cf95a685d4a4' target='_blank' class='doc'>Document for managers</a></td><td>2014</td>"
So I wonder, where does this come from incorrectly? I may have found the relevant part of coding, but I am not sure, what to do now, respectively if I am right on this?:
Public Class download : Implements IHttpHandler, IReadOnlySessionState
Dim debug As String = ""
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim fehler As String = ""
Try
' Get the file name from the query string
Dim queryFile As String = context.Request.QueryString("id")
debug += "id=" + queryFile + "<br>"
Any help is appreciated as VB.NET is not my main focus.
You have probably checked this but sometimes the obvious gets overlooked.
Verify the URL in your browser window. Make sure it has not changed to http://prod... while you were navegating.
Verify that your web application is not using frames. The page in question could be loaded in a frame using the prod URL. If this is the case your web.config might have a setting to say where this frame is loaded from or it might simply be hardcoded.
Check for URL Rewrite rules in IIS or your web.config
in asp.net, i am trying to send a template in an email, so when a user will get a message from my website, then it will be in a template,
e.g. when FB sends you a notification via mail, then it has a header and footer too, so i want to do that, i tried but it isn't sending any template within email body
CODE:
MailDefinition mailDefinition = new MailDefinition();
mailDefinition.BodyFileName = "emailBody.htm";
mailDefinition.From = "hunain.hafeez#gmail.com";
MailMessage message = new MailMessage();
message.From = new MailAddress(user_email);
message.To.Add(new MailAddress(email));
message.Subject = "Registration";
message.IsBodyHtml = true;
message.Body = "Congrats" + " " + userName + " " + " You have been shortlisted for interview. Please appear on " + " " + date +", "+time+" "+ "for interview";
SmtpClient objClient = new SmtpClient("smtp.gmail.com", 587);
objClient.EnableSsl = true;
objClient.Credentials = new System.Net.NetworkCredential("hunain.hafeez", "*******");
Short Answer: For quick fix use HTML mark-up templates , however a more flexible solution is Razor with email templating.
There are different approaches on how to achieve this. However, I stumbled upon a greate article about how to use Razor with email templating. Razor was pushed with ASP.NET MVC 3, but MVC is not required to use Razor. This is pretty slick processing of doing email templates
As the article identifies, "The best thing of Razor is that unlike its predecessor(webforms) it is not tied with the web environment, we can easily host it outside the web and use it as template engine for various purpose. "
Use Razor for Email Template outside ASP.NET MVC
Your message body needs to have HTML markup in it.
ie:
<html><body><b>Congrats ....
i have the following code in my global.ascx and when i click a generate error button the code gets run but seems to fail on the insert error into the DB.
I want the error to be saved to the DB and redirect to default.aspx.
pretty standard stuff.
the error i get is: exe.Message = "Incorrect syntax near 'System'."
(looks like somethign with the SQL objects used in global.asx)
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception ex = Server.GetLastError();
StringBuilder theBody = new StringBuilder();
theBody.Append("Error Message: " + ex.ToString() + "\n");
Server.ClearError();
try
{
string sSQL = "INSERT INTO PMISwebErr VALUES ('" + theBody.ToString() + "', GETDATE())";
using (System.Data.SqlClient.SqlConnection con = STAR.Global.GetConnection())
{
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sSQL, con);
cmd.CommandType = System.Data.CommandType.Text;
cmd.ExecuteScalar();
}
Response.Redirect("~/default.aspx?Err=sysError");
}
catch (Exception exe) {
Response.Redirect("~/default.aspx?Err="+ exe.Message.ToString() );
}
}
the problem is in the addition of the error message. it has a single quote that breaks the SQL. The code gets this value as a result at this line:
theBody.Append("Error Message: " + ex.ToString() + "\n");
sSQL = "INSERT INTO PMISwebErr VALUES
('URL:
http://localhost:14854/PMIS/Default.aspx\nReferer:
http://localhost:14854/PMIS/Default.aspx\nIP:
127.0.0.1\nError Message: System.Web.HttpUnhandledException:
Exception of type
'System.Web.HttpUnhandledException'
was thr...
that's the actual value from my quick watch, strange to see the ... at the end.
You really should use a parameterized insert. I'm sure there are quote issues with the string you're trying to insert, and it's causing the exception.
Here is an example:
https://web.archive.org/web/20210512233418/http://www.4guysfromrolla.com/webtech/092601-1.shtml
This should really be an ExecuteNonQuery() call. ExecuteScalar() is intended more for selecting atomic values from aggregates.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
As #ScottE already expected, you have a problem with quotes. The string is surronded by single quotes, but inside is the text Exception of type 'System.Web.. which adds a quote in a place where you don't want it.
The solution? Use parameters and let the driver handle those quotes.
I have a page that have fileupload control, on the submission of the form, when the fileupload control has file, file is sent via attachment in a mail and working absulutly fine, but when the fileupload control does not have file, ATT00006.dat file is automatically sent via email attachment.
Reference URL: http://nextech.pk/Enquiry.aspx?Enq=cu
Advance Thanks for any help
Edit -- Code:
hpf = fup1.PostedFile;
String toEmail = "test#hotmail.com";
String fromEmail = "mailer#hotmail.com";
MailMessage objMail = new MailMessage(fromEmail, toEmail);
objMail.IsBodyHtml = true;
StringBuilder MailBody = new StringBuilder();
MailBody.Append("<html><head></head><body> <br>");
MailBody.Append("<br>" + "An enquiry is filed <br><br>");
MailBody.Append("<strong><u>Enquirer Information</u></strong>" + "<br><br>");
MailBody.Append("<strong>Contact Name:</strong> " + txtFirstName.Text + "<br>");
MailBody.Append("<strong>Email:</strong> " + txtEmail.Text + "<br>");
MailBody.Append("<strong>Institute:</strong> " + txtInstitute.Text + "<br>");
MailBody.Append("<strong>Phone #:</strong> " + txtPhone.Text + "<br>");
MailBody.Append("<br><strong>Description:</strong><br> " + txtEnquiry.Text + "<br>");
if (hpf != null)
{
MailBody.Append("<br>" + "This email also contains an attachment:- <Strong>(" + hpf.FileName + ")</Strong><br>");
}
MailBody.Append("</body></html>");
objMail.Body = MailBody.ToString();
if (hpf != null)
{
System.IO.Stream inputStream = hpf.InputStream;
String fileName = hpf.FileName;
Attachment attach = new Attachment(inputStream, fileName);
objMail.Attachments.Add(attach);
}
SmtpClient SmtpClnt = new SmtpClient();
SmtpClnt.Send(objMail);
I don't know if you ever got an answer to this, but I've recently studied the problem in detail. The problem occurs because you did not provide an explicit name for the attachment. ASP.NET will always attach as .DAT unless the name is explicitly defined.
The problem is that people assume ASP.NET will use the Filename as the attachment name, which doesn't happen!
In your code, you should create an instance of the attachment, then provide the name explicitly using the FileUpload.FileName property:
Dim att As New System.Net.Mail.Attachment(fu.PostedFile.InputStream, System.Net.Mime.MediaTypeNames.Application.Octet) ' use Octet for binary files '
att.Name = fu.FileName ' get the file name and type automatically '
mm.Attachments.Add(att)
A full explanation of ASP.NET attaching .DAT files is available here
Its a mis-match in the attachment type that the system doesn't understand. Please post your code and what you do when there is not file as an attachment.
I think the mail server you are using (or antivirus software used by the mail server) is automatically adding this file.
Does the file in question contain anything, or is it empty?
Our site doesn't show the exception to the user. But having to be in the local server to see the error is something really bad for us.
The question is:
How to allow developer machines to see the errors in production?
EDIT: Could I do this by altering Web.config file? You guys showed up with some interesting ideas, but I cannot alter right now the application.
Check out Elmah, http://code.google.com/p/elmah/
I think the stack overflow guys use it too.
Try putting this in your Global.asax
void Application_Error(Object sender, EventArgs E)
{
// Code that runs when an unhandled error occurs
string strError = "Error in: " + Request.Path +
"\nUrl: " + Request.RawUrl + "\n\n";
// Get the exception object for the last error message that occured.
Exception ErrorInfo = Server.GetLastError().GetBaseException();
strError += "Error Message: " + ErrorInfo.Message +
"\nError Source: " + ErrorInfo.Source +
"\nError Target Site: " + ErrorInfo.TargetSite +
"\n\nQueryString Data:\n-----------------\n";
// Gathering QueryString information
for (int i = 0; i < Context.Request.QueryString.Count; i++)
strError += Context.Request.QueryString.Keys[i] + ":\t\t" + Context.Request.QueryString[i] + "\n";
strError += "\nPost Data:\n----------\n";
// Gathering Post Data information
for (int i = 0; i < Context.Request.Form.Count; i++)
strError += Context.Request.Form.Keys[i] + ":\t\t" + Context.Request.Form[i] + "\n";
strError += "\n";
if (User.Identity.IsAuthenticated) strError += "User:\t\t" + User.Identity.Name + "\n\n";
strError += "Exception Stack Trace:\n----------------------\n" + Server.GetLastError().StackTrace +
"\n\nServer Variables:\n-----------------\n";
// Gathering Server Variables information
for (int i = 0; i < Context.Request.ServerVariables.Count; i++)
strError += Context.Request.ServerVariables.Keys[i] + ":\t\t" + Context.Request.ServerVariables[i] + "\n";
strError += "\n";
// Sending error message to administration via e-mail
System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
mail.To.Add(new System.Net.Mail.MailAddress("youremailadrress"));
mail.From = new System.Net.Mail.MailAddress("youremailadrress");
mail.Subject = "SDI Error";
mail.Body = strError;
System.Net.Mime.ContentType("text/plain"));
System.Net.Mime.ContentType("text/html"));
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("YourSMTPServer");
smtp.Send(mail);
}
If the exception does not contain sensitive information, you may consider writing it out to your "friendly" error page as a comment. This way it does not show up on the page, but a dev can view source and see the info.
There isn't a way to show errors for some machines (other than local) and not for everyone else. You should use the global application error event in global.asax to record the exception.
protected void Application_Error(object sender, EventArgs e)
{
System.Exception ex = Server.GetLastError();
//TODO: Log Exception
}
We use the global exception error event to both log the error into a Db table and to email a comprehensive list of error state to the complete dev team. The information in the email includes:
Request information
CallStack
User/Client Information
Complete dump of Session
Complete dump of cookies
Complete dump of Application variables
Sending this as an email to all devs also has the added benefit of keeping all problems visible, and being immediately obvious if there is a major problem - your email box starts filling up.
It depends on how you're telling the web server to show custom error pages. If you're doing it through web.config (the system.web customErrors element), then you could just have your development box with a different web.config than that of production.
You could use the remote debug tool for visual studio 2008. Look here for more info: http://msdn.microsoft.com/en-us/library/bt727f1t.aspx
You could turn on tracing in the web.config, then open http://your-server/trace.axd to see reports about requests to the server, including exceptions thrown.
See http://msdn.microsoft.com/en-us/library/1y89ed7z(VS.71).aspx for more information.
In a nutshell, you'll add the following to your web.config.
<configuration>
<system.web>
<trace enabled="true" requestLimit="100" localOnly="false"/>
</system.web>
</configuration>
Since you want a solution that is part of the framework, and is something that you can enable and disable in the web.config, I believe this is your best solution.