So i am trying to get a simple system working where i have an asp.net mvc web app with the forms authentication already up and running with a user created. i can login with no problem using the mvc controller/view.
I then added a silverlight app to the solution, using the existing web app as the host. I created a silverlight-enabled web service and added an operation contract with the following code:
[OperationContract]
public bool Authenticate(string username, string password)
{
if (FormsAuthentication.Authenticate(username, password))
{
FormsAuthentication.SetAuthCookie(username, false);
return true;
}
return false;
}
In the silverlight app, i added two text boxes and a button, and a service reference to the WCF service. In the button click event, i have this code:
void login_Click(object sender, RoutedEventArgs e)
{
AuthenticationService.AuthenticationClient client = new AuthenticationClient();
client.AuthenticateCompleted += new EventHandler<AuthenticateCompletedEventArgs>(client_AuthenticateCompleted);
client.AuthenticateAsync(username.Text, password.Text);
}
void client_AuthenticateCompleted(object sender, AuthenticateCompletedEventArgs e)
{
if (e.Result)
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show("Error");
}
}
So the problem is, when i enter my login info and click the button, all i get is the error box. I can't seem to get it to authenticate the user.
What am i missing?
UPDATE:
Here is the error i get in the async complete handler:
Line: 86
Error: Unhandled Error in Silverlight Application
Code: 4004
Category: ManagedRuntimeError
Message: System.NullReferenceException: Object reference not set to an instance of an object.
at UserPortal.MainPage.client_AuthenticateCompleted(Object sender, AuthenticateCompletedEventArgs e)
at UserPortal.AuthenticationService.AuthenticationClient.OnAuthenticateCompleted(Object state)
UPDATE 2:
So the error i posted above is because the e.Error property is null. So i am not getting any specific error from the authentication service. Is there something i need to change in the web.config to get this to work via silverlight?
<authentication mode="Forms">
<!-- forms loginUrl="~/Account/LogOn" timeout="2880"/ -->
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
<add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</roleManager>
Ok, so i got it to work, kinda.
Following the content here i managed to get a service up and running that would allow me to successfully login. The problem is i had to change the RequireSSL to false. I could not get the service to work running on https.
Anyone know what i need to do to get it to work on SSL? i am using the ASP.NET development server right now, do i need to configure a real version of IIS on this box for that to work?
When using WCF and running on an development server, you need to have proper certificates installed. its not silverlight its the wcf client proxy that tries to verify your vertificate and fail I think. What happens when you try to hit it from asp or the browser?
Related
EDIT: Can anyone explain why I am getting "/" for the username? See my "Answer" below
I created a new WebForms application in VS2013 (.NET 4.51) which included the "new" Identity membership provider. I wanted to use the older Membership provider so did as follows.
Populated the necessary entries in web.config as follows:
:
<membership defaultProvider="DefaultMembershipProvider">
<providers><add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
and
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<roleManager defaultProvider="DefaultRoleProvider" enabled="true">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
I doubled checked the authentication node:
<authentication mode="Forms">
<forms loginUrl="Account/Login" timeout="120" defaultUrl="/">
</forms>
</authentication>
My login code is as follows:
if (Membership.ValidateUser(txtUserName.Text, txtPassword.Text))
{
FormsAuthentication.RedirectFromLoginPage("/", chkRememberMe.Checked);
}
and my logout code:
FormsAuthentication.SignOut();
Session.Abandon();
FormsAuthentication.RedirectToLoginPage();
however HttpContext.Current.User.Identity.IsAuthenticated always returns TRUE, which means that even after I logout I can access any page in the site even through I have the following restriction:
<!-- Entire site is secured -->
<location path=".">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
What am I missing here? I am guessing there is still some legacy from the original Identity provider which I have not eradicated which is causing this issue. At this point security is not working at all for me and I need to get it working without using the new Identity membership provider which is the default for new applications generated via the new application template in VS2013.
All pointers and suggestions greatly appreciated.
I came back to this today and now pages are authenticating as expected (WT....). So I am guessing that there must have been a cookie somewhere that was not being cleared. However something is still not right.
Once the user has authenticated when I inspect:
System.Web.HttpContext.Current.User.Identity.Name
I am getting:
"/"
as the result instead of the name the user entered when they logged in via:
Membership.ValidateUser(txtUserName.Text, txtPassword.Text)
ie. why am I not getting the value of txtUserName.Text instead of /
I guess a related question is, is there a HOWTO on how to revert a project from Identity to the previous Membership system?
I am using client application services to authenticate users for windows app. (SqlMembershipProvider) Login works fine and I can grab the user name by using the following code:
userName = System.Threading.Thread.CurrentPrincipal.Identity.Name.ToString();
I want to grab a bit more info about the user such as the email address. I have tried the following line to get the user.
MembershipUser mu = Membership.GetUser();
The above line gives me a "specified method is not supported" message. Same result if I pass in the userName as well.
Is there a way to get more detailed user info using client application services as you would in an asp.net app? If not, I wonder if I should just create my own Web Service wrapper instead?
I'm using the 4.0 Framework.
Update: A slice of the app.config file
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="http://PC-03/FAAppServices/Authentication_JSON_AppService.axd" credentialsProvider="BillingFormsApplication.LoginForm, BillingFormsApplication" savePasswordHashLocally="True" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="http://PC-03/FAAppServices/Role_JSON_AppService.axd" cacheTimeout="1209600" honorCookieExpiry="True" />
</providers>
</roleManager>
</system.web>
Update 2: Stack Trace
at System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider.GetUser(String username, Boolean userIsOnline)
at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
at BillingFormsApplication.MDIMain.MDIMain_Load(Object sender, EventArgs e) in C:\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.cs:line 340
SimpleMembership, as the name implies, is very simple and does not implement all of the MembershipProvider methods; just those required for MVC basic authentication and authorization. If you try to use a method that is not implemented you will get that exception. You can either create your own MembershipProvider from scratch or you can inherit from SimpleMembership and implement the methods that are not implemented.
The exception is by design
The class ClientAuthenticationMembershipProvider does not use the method GetUser.
If your app.config is configured to use ClientAuthenticationMembershipProvider, and you call Membership.GetUser, then you will always get a NotSupportedException.
ref: https://learn.microsoft.com/en-us/dotnet/api/system.web.clientservices.providers.clientformsauthenticationmembershipprovider.getuser
Currently whenever I try to register a user or login using the default membership services built into ASP.Net MVC4 on my host provider DiscountASP I receive the error
To call this method, the "Membership.Provider" property must be an instance of "ExtendedMembershipProvider".
This doesn't happen locally.
Here is my InitializeSimpleMembershipAttribute.cs:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
{
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Ensure ASP.NET Simple Membership is initialized only once per app start
LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
}
private abstract class SimpleMembershipInitializer
{
protected SimpleMembershipInitializer()
{
Database.SetInitializer<UsersContext>(null);
try
{
using (var context = new UsersContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
}
}
}
Here is a full screenshot of the error:
Does anyone know how I can fix this or know an article that addresses it?
Try setting the following up in your web.config within the <system.web> node:
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear />
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
</providers>
</roleManager>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear />
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>
Sounds like SimpleMembership isn't recognized when you go to use it.
Also, it may be worth including, the WebMatrix.webData library can be installed via NuGet:
PM> Install-Package Microsoft.AspNet.WebPages.WebData
Try to change the Login function under AccountController.cs
//
// POST: /Account/Login
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Did steps above but that didn't help. What helped was changing web.config:
<dependentAssembly>
<assemblyIdentity name="WebMatrix.Data" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebMatrix.WebData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
I had the same error, but it was 100% references for me. I have had trouble getting WebMatrix.WebSecurity working several times...each time is because I did not create the project using the MVC 4 Internet template.
The key is that the references and config work by default in the template, so just recreate your project and it will be fine.
My fix is:
1. Back up my project to another folder.
2. Check out all files
3. Create a new MVC 4 Internet project, under the exact same name.
4. Copy + Paste (overwrite) the original project.
5. Add any missing references, changed routes, .config settings/DB connections.
I am just fix the same problem.
My problem start after update nuget packages.. My VS 2019 add new lines "membership" and "roleManager" in web.config so it is become duplicated (as previously has been exist).
I am commented the old values, then this "membership.provider" warning shown each time logoff and login.
Just use the old one because more suitable with your code.
Below is the generated code in web.config that I remove :
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
I've implemented a challenge-response scheme as an Ajax handler.
For some reason it stopped working after working fine for a couple months.
Investigating the issue showed that Context.Session[KEY] had lost its value between the challenge and the response calls.
I put Session_Start and Session_End (and a few other) methods in Global.asax.cs with some logging there and I see a new Session_Start event being fired with the same session ID and there was no Session_End event
Question is: why does IIS lose the session values?
Update: I tried switching to SQLServer sessions but there was no change in behavior. On rare occasions sessions work as intended, not sure why. I tried all "session losing variables" troubleshooting guides I could find to no effect
UPDATE 2: I narrowed down the issue to a missing session cookie, but modifying my.browsers config didn't resolve the issue after several attempts. When I call the ajax handler from a browser the session cookie "ASP.NetSessionId" shows up as expected. I changed the cookie name in IIS settings for both the site and the server to "SessionId" but I kept seeing ASP.NET, even after restarting the server. I would still like to give the bounty to someone who has an idea what's going on. In the meanwhile I worked around this problem by setting a session cookie in code.
Pseudo code for Login.ashx:
string login = GetParameter("login", context);
string passhash = GetParameter("pass", context);
string challenge = "" + Context.Session["CHALLENGE"];
if (!string.IsNullOrEmpty(challenge))
{
// this is the 'response' part
string challengeResponse = Crypto.GetChallengeResponse(Challenge, UserFromDB.PassHash);
if (challengeResponse == passhash)
{
// Great success, challenge matches the response
Log.I("Success");
return "SUCCESS";
}
else
{
Log.W("Failed to respond");
return "FAILED TO RESPOND";
}
}
else
{
// if passed login or session-stored challenge are empty - issue a new challenge
challenge = "Challenge: "+ Crypto.GetRandomToken();
Context.Session["CHALLENGE"] = challenge;
Log.I("Sent Challenge"); // this is what's in the log below
return challenge;
}
Here's the log, Session started appears with each call, Session.Keys.Count stays 0 even though Session["CHALLENGE"] should have been set:
// This is the challenge request:
[] **Session started**: sr4m4o11tckwc21kjryxp22i Keys: 0 AppDomain: /LM/W3SVC/1/ROOT-4-130081332618313933 #44
[] Processing: <sv> **MYWEBSITE/ajax/Login.ashx** SID=sr4m4o11tckwc21kjryxp22i
[] Sent Challenge #Login.ashx.cs-80
// this is the response, note that there's another Session started with the same id
// and the session didn't keep the value ["CHALLENGE"], there are no session-end events either
[] **Session started**: sr4m4o11tckwc21kjryxp22i Keys: 0 AppDomain: /LM/W3SVC/1/ROOT-4-130081332625333945 #93
[] Processing: <sv> **MYWEBSITE/ajax/Login.ashx?login=MYLOGIN&pass=RuhQr1vjKg_CDFw3JoSYTsiW0V0L9K6k6==**
[] Sent Challenge #Login.ashx.cs-80 >Session: sr4m4o11tckwc21kjryxp22i
web config, sanitized
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="IncludeStackTraceInErrors" value="false" />
</appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
<add name="MYConnection" connectionString="metadata=res://*…. and a bunch of other stuff that works" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
<pages controlRenderingCompatibilityVersion="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>
What is the default value for Idle Time-out ? If the app pool times out your session goes bye bye
See Application Pool (Advanced Settings) -> Idle Time-out
I think it defaults to five minutes.
See this link for advice on setting the idle timeout
You could also experience your issue if your running as a webgarden when it's not needed; look at Maximum Worker Processes, try setting it to 1 and retest
I can see you are using handler for that purpose which would always return null.
You need to implement IReadOnlySessionState.
Check out http://www.hanselman.com/blog/GettingSessionStateInHttpHandlersASHXFiles.aspx
Add IRequiresSessionState to your handler implimentation
ex
public class handler_name:IHttpHandler, IRequiresSessionState
I am hosting a site through godaddy.com and this is the link:
http://floridaroadrunners.com/
and this is my web.config file:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>
<customErrors mode="Off"/>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I am getting runtime error:
Runtime Error
Description: An application error
occurred on the server. The current
custom error settings for this
application prevent the details of the
application error from being viewed
remotely (for security reasons). It
could, however, be viewed by browsers
running on the local server machine.
I have also set the customErrors mode = "off". What is wrong here? I am using Visual Studio 2010 with 4.0 framework in it. Thanks!
If your host has enabled customErrors, you might consider catching and logging the exception yourself so you can see what's going on.
There are a couple options. First, try Elmah
Second, you could use your logging library (I like NLog, but any will work), and catch the Application_Error event in Global.asax.cs.
protected void Application_Error(object sender, EventArgs e)
{
//first, find the exception. any exceptions caught here will be wrapped
//by an httpunhandledexception, which doesn't realy help us, so we'll
//try to get the inner exception
Exception exception = Server.GetLastError();
if (exception.GetType() == typeof(HttpUnhandledException) && exception.InnerException != null)
{
exception = exception.InnerException;
}
//get a logger from the container
ILogger logger = ObjectFactory.GetInstance<ILogger>();
//log it
logger.FatalException("Global Exception", exception);
}
This is a good feature to have no matter what, even if you're able to get customErrors turned off.
The server's machine.config or applicationHost.config is likely overriding your web.config settings. Unfortunately there's nothing you can really do if that's the case, short of contacting GoDaddy's support line.
customErrors mode value Off is case sensitive I think. Please check that you have the first character capitalized.
You can catch the error in you Global.asax and sending an email with the exception.
In Global.asax.cs:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception ex = Server.GetLastError();
ExceptionHandler.SendExceptionEmail(ex, "Unhandled", this.User.Identity.Name, this.Request.RawUrl);
Response.Redirect("~/ErrorPage.aspx"); // So the user does not see the ASP.net Error Message
}
My method in My ExceptionHandler Class:
class ExceptionHandler
{
public static void SendExceptionEmail(Exception ex, string ErrorLocation, string UserName, string url)
{
SmtpClient mailclient = new SmtpClient();
try
{
string errorMessage = string.Format("User: {0}\r\nURL: {1}\r\n=====================\r\n{2}", UserName, url, AddExceptionText(ex));
mailclient.Send(ConfigurationManager.AppSettings["ErrorFromEmailAddress"],
ConfigurationManager.AppSettings["ErrorEmailAddress"],
ConfigurationManager.AppSettings["ErrorEmailSubject"] + " = " + ErrorLocation,
errorMessage);
}
catch { }
finally { mailclient.Dispose(); }
}
private static string AddExceptionText(Exception ex)
{
string innermessage = string.Empty;
if (ex.InnerException != null)
{
innermessage = string.Format("=======InnerException====== \r\n{0}", ExceptionHandler.AddExceptionText(ex.InnerException));
}
string message = string.Format("Message: {0}\r\nSource: {1}\r\nStack:\r\n{2}\r\n\r\n{3}", ex.Message, ex.Source, ex.StackTrace, innermessage);
return message;
}
}