Received multiple email errors form Elmah - asp.net

2 for my ASP.NET web pages .NET 4.0 app. I was using Enterpriselibrary to log and send error via email before the app was upgraded to .NET 4.0 but since its upgraded the EnterpriseLibrary logging has stopped logging so I have decided to switch to Elmah.
In part of my web.config file of the app:
<add name="ErrorHandler" type="myWebApp.ErrorHandlingModule, myWebApp" preCondition="managedHandler" />
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
As you can see there is already an Errorhandling module there (ErrorHandlingModule), which creates a custom error message ("ex" object in the following code). Originally in the ErrorHandlingModule:
try
{
ExceptionPolicy.HandleException(ex, "myWebApp Error Handling");
}
catch (Exception exApplicationBlockError)
{
try
{
EventLog log = new EventLog("Application");
log.Source = "Application Error";
log.WriteEntry(exApplicationBlockError.ToString(), EventLogEntryType.Error);
}
catch
{
}
}
Since I switch to Elmah:
try
{
//ExceptionPolicy.HandleException(ex, "myWebApp Error Handling");
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
catch (Exception exApplicationBlockError)
{
try
{
EventLog log = new EventLog("Application");
log.Source = "Application Error";
log.WriteEntry(exApplicationBlockError.ToString(), EventLogEntryType.Error);
}
catch
{
}
}
It works very well but the problem now is if there is any error it raises 2 error emails: one is the custom one, and the other the default Elmah one; and of course I only want the custom one.
I haven't added any extra Elmah ErrorFilter in the program but I do need to have the custom exception in my email.
Should I add a custom Elmah filter to filter out ALL the exceptions so Elmah won't send me the default error email? (Or any other suggestions?)
Also attach the elmah config in web.config file if it is any help:
<elmah>
<security allowRemoteAccess="false" />
<errorMail from="xxxx#myorg.au" to="xxxxx#myorg.au" subject="myWebApp error" async="true" />
</elmah>
Thanks in advance. Happy holiday!

If you don't want Elmah to email, then don't configure it to do so in the first place. Remove the module configuration:
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah">
And any other ErrorMail Elmah email related configuration such as
<errorMail from="xxxx#myorg.au" to="xxxxx#myorg.au" subject="myWebApp error" async="true" />

Silly me I should not need to include:
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
It's why the email was sent twice. But thanks for the help.

Related

How do I direct System.Diagnostics.Trace write messages to the ASP.NET trace viewer (trace.axd)?

I have an ASP.NET MVC application which is deployed on an Azure instance.
In this application, I have System.Diagnostics.Trace messages all over the place, including here (quoted simply as an example):
public class ExceptionLogFilterAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
System.Diagnostics.Trace
.TraceError(string.Format("{0}\r\n\r\n",
filterContext.Exception.ToString()));
base.OnException(filterContext);
}
}
In the web.config, I have trace enabled.
However, when I browse to trace.axd after I have been redirected to the default error page of the application because an exception has occurred, I do not see any signs of the exception I have written to the trace above.
Add this configuration in your web.config file:
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener,
Microsoft.WindowsAzure.Diagnostics,
Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
Here is where you can read more about it.

How to implement Google reCaptcha in an MVC3 application?

Can anyone explain how to have reCaptcha functionality like stackoverflow in my MVC3 application.
And how can you customize that?
I use the Google ReCaptcha and it works very well and is very simple to implement.
Note that if you are using Https be sure you have the current version of the dll (1.0.5.0 at this time)
You need to create an account on the Google Recaptcha site and get a set of public and private keys. Add the keys to your web project main web.config file:
<appSettings>
<add key="webpages:Version" value="1.0.0.0"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
<add key="ReCaptchaPrivateKey" value="put your private key value here" />
<add key="ReCaptchaPublicKey" value="put your public key value here" />
</appSettings>
Now use NuGet and install the reCAPTCHA plugin for .NET
Then, go to your web.config file inside of your VIEWS folder. Add this line:
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Recaptcha"/>
</namespaces>
Then, in your view that you want to show the captcha, add the using statement at the top of your file
#using Recaptcha;
then add this to your view:
<div class="editor-label">
Are you a human?
</div>
<div class="editor-field">
#Html.Raw(Html.GenerateCaptcha("captcha", "clean"))
#Html.ValidationMessage("captcha")
</div>
In your controller action you will need to modify the signature to accept the captcha results:
[HttpPost]
[RecaptchaControlMvc.CaptchaValidator]
public ActionResult ForgotPassword(CheckUsernameViewModel model, bool captchaValid, string captchaErrorMessage) {
if (!Membership.EnablePasswordReset)
throw new Exception("Password reset is not allowed\r\n");
if(ModelState.IsValid) {
if(captchaValid) {
return RedirectToAction("AnswerSecurityQuestion", new { username = model.Username });
}
ModelState.AddModelError("", captchaErrorMessage);
}
return View(model);
}
Following those steps have allowed me to implement captcha on several pages and it works smoothly. Note that the parameter names on the controller action MUST BE NAMED CORRECTLY:
bool captchaValid, string captchaErrorMessage
If you changed these parameter names you WILL get an error at runtime when your form posts back to the controller action.
I would recommend using a Honeypot Captcha. The experience for your users is MUCH better. There is one fore ASP.NET MVC here http://nuget.org/packages/SimpleHoneypot.MVC
PM> Install-Package SimpleHoneypot.MVC4
There is a WiKi on how to get it up here: https://github.com/webadvanced/Honeypot-MVC/wiki
Just start out with the Getting Started section.
You can read more about the general idea of a Honeypot Captcha here: http://haacked.com/archive/2007/09/11/honeypot-captcha.aspx

MVC - Users must reauthenticate on IIS Recycle

I need an app pool recycle to be completely transparent to the users of my web app.
Currently, upon an IIS 7 App Pool recycle all users logged into my web app are kicked out and are required to log back in (Context.User.Identity.IsAuthenticated is set to false). I employ SQL State Server, I use forms authentication and both are configured to use cookies. I was under the impression that .NET and/or IIS handles authentication of cookies.
However, every time the app pool is recycled Context.User.Identity.IsAuthenticated is set to false (and I've no idea where this occurs) my users are kicked out and are required to log back in. I can see that the session id remains the same throughout logins, I can also view this session information in the database/state server.
I can't tell if this is a session or a cookie problem.
Please Help!
Logon method:
public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
{
if (!ValidateLogOn(userName, password))
{
return View();
}
FormsAuth.SignIn(userName, true); // uses FormsAuthentication.SetAuthCookie(username, true);
Session["userName"] = userName;
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
Custom Controller Attribute:
public class CookieAuthorizeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext lvContext = HttpContext.Current;
if (!lvContext.User.Identity.IsAuthenticated)
{
lvContext.Response.Redirect("~/Account/Logon");
}
else
{
FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthentication.RenewTicketIfOld(identity.Ticket);
}
base.OnActionExecuting(filterContext);
}
}
WebConfig:
<authentication mode="Forms">
<forms cookieless="UseCookies" loginUrl="~/Account/LogOn" slidingExpiration="true" name=".ASPXAUTH" requireSSL="false" timeout="2880" />
</authentication>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ScriptModule" />
<remove name="UrlRoutingModule" />
<remove name="Session" />
<remove name="FormsAuthentication" />
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="NHibernateMvcSessionModule" type="EpnNHibernateBase.NHibernateMvcSessionModule, EpnNHibernateBase" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
</modules>
I was able to find a solution on my own. The problem was not with how authentication was handled programmatically or how I was authenticating users. The problem was with how I had configured the authentication in IIS/web.config.
I carefully followed the steps in the links listed below:
Configuring Forms Authentication (IIS 7) (Branching out on every related section)
Configuring Machine Keys in IIS 7 <-- This one in particular
After having followed those steps closely I was able to correctly generate a machine key.
This machine key is as follows (with a fabricated key):
<machineKey decryptionKey="ASDF3WS545AS5D4F8254A12DAFA5SDF7,IsolateApps" validation="3DES" validationKey="A65A6S5DF46ASD4F89WEF6SAD2F4A68EF4AW65F4D3A2F4AS6DF89A98D4F6A5SD4F6A5SDF46ASD8F4A6S5DF46AS5D4F6AS5DF49AS8DF46AS5D4F6AS5DF46SAD5F,IsolateApps" />
Additionally, httpModules and system.webServer:modules sections in the web.config required the addition of the following modules:
<remove name="Session" />
<remove name="FormsAuthentication" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
Summary: From what I gather, cookies were being created and encrypted, but because there was no machine key I was unable to unencrypt the cookie, thus causing the need to reauthenticate.
have you tried storing the sessions in a database so they are persistent even if the process is recycled?
see here for howto
Reading your post closely, it looks like the real issue is that users are not logged back in automatically. This is handled by cookies assuming you are using forms authentication.
Once a user is logged in, their session state will be restored if you are using SQL to persist it.
To debug cookies, you can use Fiddler or other cookie sniffers.
Posting your web.config would be helpful as well.

Error 500 with custom HttpHandler in ASP.NET website (IIS 7.5, Win7)

I'm trying to get custom HttpHandler working in my sample web application. I've been experiencing a lot of issues, but finally got stuck with error 500. Application pool is being run in Classic ASP.NET 2.0 mode. Server is IIS 7.5, OS is Win 7 Pro.
Here's a code of my handler:
public class SampleHandler : IHttpHandler
{
public SampleHandler()
{
}
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.Clear();
context.Response.ContentType = "text/html";
context.Response.Write("This is a sample content.");
context.Response.Expires = 0;
context.Response.End();
}
}
Here is a web.config file content:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.shc" type="SampleHandler"/>
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add resourceType="Unspecified" verb="*" path="*.shc" name="SampleHandler" type="SampleHandler" modules="IsapiModule" scriptProcessor="c:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll\aspnet_isapi.dll"/>
</handlers>
</system.webServer>
</configuration>
Here is a link to the screenshot of an error : http://bit.ly/cmPk4i
Could anybody please tell me what I did wrong? Thanks in advance!
Try setting
<validation validateIntegratedModeConfiguration="false" />
in
<system.webServer>
I had 500 error and this fixed it.
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add .... />
</handlers>
</system.webServer>
From the list of "things you can try", did you install the .Net Extensibility Feature?
You can also enable the Failed Requests logging feature on the application, which provides detailed information on request processing.
The good news, at least, is that your registered handler is recognized as the handler to be executed.

Able to send email through .exe, but not ASP.NET?

I'm trying to send an email to an external address as part of a web app. I can send an email fine when using a simple executable running on the server:
private void button1_Click(object sender, EventArgs e)
{
MailMessage message = new MailMessage(welcomeMessageFrom, toAddress, welcomeMessageSubject, welcomeMessageSubject);
SmtpClient emailClient = new SmtpClient("mail.sortuv.com");
System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential(username, password);
emailClient.UseDefaultCredentials = false;
emailClient.Credentials = SMTPUserInfo;
emailClient.Send(message);
}
However, trying the same code from an ASP.NET page gives the following exception:
Mailbox unavailable. The server response was: 5.7.1 Unable to relay for <user's email>
I'm new to IIS but do you have suggestions on how to debug?
UPDATE: I had to specify the domain for the user as well. Still not sure why a regular .exe was ok without it. Hope this helps someone.
Seems a credential issue. The normal exe runs under your account.
The ASP.NET application run under the NETWORK SERVICE in Windows Server and ASPNET under Windows XP.
You have to use other credentials in order to successfully send email from ASP.NET
Try adding
emailClient .DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
Is this for IIS7 as I had a simular issue I had to enable the smtp service on the server
And set up the mail for each domain on there
Thanks for all the help guys, I just figured it out. I had to specify the domain:
SmtpClient emailClient = new SmtpClient(servername);
System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential(name, pass);
SMTPUserInfo.Domain = domain; // i.e. "foo.com"
emailClient.UseDefaultCredentials = false;
emailClient.Credentials = SMTPUserInfo;
emailClient.Send(message);
Are you setting anything your web.config, relating to mail parameters? IIRC, the web.config will override your code settings.
Also, something else you can do, is to enable logging, to actually see what the SmtpClient is sending.
You need to add some values to your .config file. Here is an example:
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net" >
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log" />
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
<add name="System.Net.Sockets" value="Verbose" />
</switches>
</configuration>
Here is a link with more info:
http://systemnetmail.com/faq/4.10.aspx

Resources