Microsoft ASP.NET Redis Session State throws an exception - c#

When hooking up an ASP.NET website to Azure Redis Cache (but this error also occurs when using a local redis instance) using the Microsoft ASP.NET Redis Session State provider, I get a Null Reference Exception. Why? Google tells me nothing. I have tried using the Russian Redis Session State provider, but that randomly corrupts the session state, so I can't use that either.
This is the stack trace:
[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Web.Redis.StackExchangeClientConnection.Eval(String script, String[] keyArgs, Object[] valueArgs) +381
Microsoft.Web.Redis.RedisConnectionWrapper.TryUpdateIfLockIdMatch(Object lockId, ISessionStateItemCollection data, Int32 sessionTimeout) +108
Microsoft.Web.Redis.RedisSessionStateProvider.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +1280
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +565
System.Web.SessionState.SessionStateModule.OnEndRequest(Object source, EventArgs eventArgs) +139
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
I have no idea where this problem occurs as the stack trace doesn't touch my code, but it occurs on any url hitting my site after I am logged in, yes using forms authentication.
My redis config looks like this:
<sessionState mode="Custom" customProvider="RedisSessionStateStoreProvider">
<providers>
<clear />
<add name="RedisSessionStateStoreProvider" type="Microsoft.Web.Redis.RedisSessionStateProvider, Microsoft.Web.RedisSessionStateProvider, Version=0.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
host="*******.redis.cache.windows.net"
throwOnError = "true"
connectionTimeoutInMilliseconds = "5000"
retryTimeoutInMilliseconds = "5000"
operationTimeoutInMilliseconds = "5000"
ssl="true"
accessKey="*******************************"
/>
</providers>
... where I have starred out the access key and service uri.
EDIT: I was happy, and thought I had found the solution when I found a post on MSDN Forums (booh!) that dealt with intermittent null reference exceptions where they warned that a nonexistent key being assigned with with a null value will break everything. I found an instance where I was doing this and fixed it,but that didn't actually do the trick and the same problem remains.
I am using Microsoft.Web.RedisSessionStateProvider 0.4.0.0-Pre-121 that allegedly fixes a similar bug

The problem is that I managed to use Null as a key(!!!). What I thought was a properly named constant (like all the other key names) was in fact a variable that was null.
The effects of this mistake differed considerably, so I will post them here if it helps anybody:
Inserting Null as a key caused both the ASP.NET Universal Providers session state provider and RedisAspNetProviders SessionStateProvider to work until the first deserialization after the fatal value with a null key is inserted, after which they blow up with a HttpException (which is correct, probably, although a slightly more helpful error message could be supplied) or an Out Of Memory exception, when I tried storing a List, which is unexpected.
The Microsoft Redis Session State provider blows up with an NRE directly as the idiotic key is inserted and again, us idiots could probably use a better message to save us time.
I tried to use Azure AppFabric as an alternative before I knew what the error was but it was not responding enough to be tested.

Related

SignalR - Decryption key specified has invalid hex characters

I am using SignalR 2.2.0 and MVC 4. When I load my page in Chrome, I receive an error in the console:
http://localhost:8180/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&_=1467627883530 500 (Internal Server Error)
Upon further inspection using Fiddler I can view the stacktrace:
[ConfigurationErrorsException]: Decryption key specified has invalid hex characters. (C:\Users\Foo\web.config line 66)
at System.Web.Security.Cryptography.MachineKeyMasterKeyProvider.GenerateCryptographicKey(String configAttributeName, String configAttributeValue, Int32 autogenKeyOffset, Int32 autogenKeyCount, String errorResourceString)
at System.Web.Security.Cryptography.MachineKeyMasterKeyProvider.GetEncryptionKey()
at System.Web.Security.Cryptography.Purpose.GetDerivedEncryptionKey(IMasterKeyProvider masterKeyProvider, KeyDerivationFunction keyDerivationFunction)
at System.Web.Security.Cryptography.AspNetCryptoServiceProvider.GetNetFXCryptoService(Purpose purpose, CryptoServiceOptions options)
at System.Web.Security.Cryptography.AspNetCryptoServiceProvider.GetCryptoService(Purpose purpose, CryptoServiceOptions options)
at System.Web.Security.MachineKey.Protect(ICryptoServiceProvider cryptoServiceProvider, Byte[] userData, String[] purposes)
at System.Web.Security.MachineKey.Protect(Byte[] userData, String[] purposes)
at Microsoft.Owin.Host.SystemWeb.DataProtection.MachineKeyDataProtector.Protect(Byte[] userData)
at Microsoft.Owin.Security.DataProtection.AppBuilderExtensions.CallDataProtectionProvider.CallDataProtection.Protect(Byte[] userData)
at Microsoft.AspNet.SignalR.Infrastructure.DataProtectionProviderProtectedData.Protect(String data, String purpose)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessNegotiationRequest(HostContext context)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 environment)
at Microsoft.AspNet.SignalR.Owin.Middleware.HubDispatcherMiddleware.Invoke(IOwinContext context)
at Microsoft.Owin.Infrastructure.OwinMiddlewareTransition.Invoke(IDictionary`2 environment)
at Microsoft.Owin.Mapping.MapMiddleware.<Invoke>d__0.MoveNext()
From what I've gathered, SignalR is using the machine key to perform some encryption/decryption.
This is what the machine key looks like:
<machineKey decryptionKey="5E329ED7DE2786FCD906E717C97A09BE26B3564BBE0A2B28,IsolateApps" validationKey="A64F709FB47B282CB8331205BC423D63450B4FFC92FE06EC1E00B3AE8B5B1F529A5CD1064F66C08545FC13B013F84153598B29213D5494DD5EC348B537A51DAE,IsolateApps"/>
I'm guessing it's seeing the "IsolateApps" in the decryptionKey/validationKey and throwing an exception ("...invalid hex characters").
If I remove the "IsolateApps" from the keys, I can't log in anymore since I'm using FormsAuthentication which in turn makes use of the keys to encrypt/decrypt. So removing the "IsolateApps" does not seem to be a solution.
PS. The code I'm using is from this tutorial.
I have already looked at this answer but it does not solve the problem. I have also tried to add compatibilityMode="Framework20SP1" to the machine key but that does not work either.
Is there way to fix this issue without removing the "IsolateApps" value from the keys in the web config?
I have fixed the issue. I decided to remove the ",IsolateApps" attribute from the machine key which stopped giving this exception:
Decryption key specified has invalid hex characters
Removing this attribute meant I could not log in anymore (since the machine key has technically changed) which forced me to reset my account password. Once I reset the password I could continue with logging in.
Once I was able to log in I was receiving this error:
ws://xxxxx/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=xxxxx'
failed: Connection closed before receiving a handshake response.
This exception was only being thrown in Chrome.
SignalR fell back onto server sent events because the web socket handshakes weren't successful. After many hours of debugging I solved the issue by adding this to the web config:
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<pages controlRenderingCompatibilityVersion="4.0" />
</system.web>
Once that was added, SignalR was functioning as excepted.

Who is invoking Error view and why?

I got a MVC4 web application running and functioning properly since almost a year. Lately while reviewing production error logs, I found a lot of mysterious exception entries of same type. I checked logs and found these exceptions occur on both Beta and Production environment but not in local (seems like a hint - see findings 1 below).
There are two subsequent entries:
One is:
Thread Id: 56, Message: Server_Exception - The view 'Error' or its
master was not found or no view engine supports the searched
locations. The following locations were searched:
~/Views/OrganizationUser/Error.cshtml
~/Views/OrganizationUser/Error.vbhtml ~/Views/Shared/Error.cshtml
~/Views/Shared/Error.vbhtml
Second log entry is:
Thread Id: 56, Message: Server_Exception - Stack Trace - at
System.Web.Mvc.ViewResult.FindView(ControllerContext context) at
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at
System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.b__22(IAsyncResult
asyncResult) at
System.Web.Mvc.Controller.<>c__DisplayClass1d.b__18(IAsyncResult
asyncResult) at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult
ar) at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult
asyncResult) at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult
ar) at
System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__3(IAsyncResult
asyncResult) at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult
ar) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step,
Boolean& completedSynchronously)
The exception is logged from Application_Error() in global.asax.cs like so:
var ex = Server.GetLastError();
if (ex != null)
{
logger.Log(string.Format("Server_Exception - {0}", ex.Message), LogCategory.Error);
logger.Log(string.Format("Server_Exception - Stack Trace - {0}", ex.StackTrace), LogCategory.Error);
}
And here is the snapshot of DB log messages:
Finding/Analysis:
Since the errors are logged only on remote server, it tells me it has got to do with how MVC handles remote errors? CustomErrors? - I don't have it defined it in web.config. Should I?
But the main question is, what caused the error to happen? And who is looking for view name Error? I know its hard for you to guess it but just checking my luck.
Another finding is the exceptions are logged after user has logged out. In my Login get form, I check isAuthenticated and if user is not authenticated I log a message 'Request not authenticated, showing login form.' and display login form. I can see this message in logged prior to above exception messages. So what's going on on login.cshtml that causes a contact to server which generates an error? I checked, login page and _Layout which has lots of server side code embedded but could not figure out what could cause server to try to load Error page.
I think internally MVC is calling Error page which does not exist in my source code hence these exception. But why 'Error' page? I thought to get advice on what to check in this case. Please advise if you want me to share anything that could help you understand my problem.
I suspect you are using the System.Web.Mvc.HandleErrorAttribute as this attribute will attempt to look for an Error view under certain conditions when an exception is thrown inside a controller action:
The currently executing action is not a child action
The exception has not already been handled or custom errors are enabled
When wrapped in a HttpException, the exception has a 500 HTTP status code
The exception is an instance of System.Exception
When all of the above are true, System.Web.Mvc.HandleErrorAttribute creates a System.Web.Mvc.HandleErrorInfo instance, sets the ExceptionContext.Result property to a ViewResult which by default has the ViewName property set to Error.
Putting all of this together, In one of your controllers, an exception must be being thrown that meets all of the above points, in a controller action that has the [HandleError] attribute applied (maybe it's applied globally), which is attempting to find the Error view and failing to do so.
To know what the original exception is, you could put an Error view into your solution and write out the Exception message of the HandleErrorInfo model instance passed to the view (if the current user has the appropriate access controls).

Frequent connection aborted exceptions when using CRM 2013 Organization Service

I have a problem running a WCF service that connects to the CRM: It frequently produces CommunicationObjectAbortedExceptions which leave me to wonder if I am doing something wrong. These execptions started occurring after many people started using it, on the test system it worked without problems.
But let's start at the beginning: I wrote two WCF Services that connect to the Microsoft CRM2013 Organization Service using my own library to execute queries on the CRM. These services are regularly called from the CRM which is used by roughly 100-200 people on a daily basis.
This works basically fine, but I frequently get a couple of exceptions which look like the following (see bottom of the Post for the full stacktrace):
System.ServiceModel.CommunicationObjectAbortedException: The HTTP request to 'http://crm/MyOrganization/XRMServices/2011/Organization.svc' was aborted. This may be due to the local channel being closed while the request was still in progress. If this behavior is not desired, then update your code so that it does not close the channel while request operations are still in progress.
By frequently I mean around 100 times a day, most often a couple of those exceptions are thrown every 5-30 minutes in batches of 3-6 exceptions. I have no idea why this is happening. I initialize the connection to the CRM Organization Service using the following class from my library in both services:
public class CrmManager : IDisposable
{
private static CrmConnection s_connection;
public static CrmConnection Connection
{
get
{
if (s_connection == null)
{
s_connection = new CrmConnection("CrmTvTest");
}
return s_connection;
}
}
public static IOrganizationService ServiceProxy
{
get { return s_serviceProxy ?? (s_serviceProxy = new CachedOrganizationService(Connection)); }
}
As can be seen, I connect to the Organization Service once per WCF service, using the CrmConnection to handle the connection details, which is stored in a static variable (acting as a singleton, since establishing the Connection is expensive and should not be done too often to my understanding). It is then passed to the CachedOrganizationService, which is static for the same reasons. The WCF service uses the default instance management (PerSession AFAIK), meaning there is probably 1 connection and organization service per user.
My Connection String looks like this (removed any sensible data, of course):
<connectionStrings>
<add name="CrmTvTest" connectionString="Url=http://crm/MyOrganization; Username=user; Password=pw;"/>
I then use the connection with CrmServiceContext objects to execute queries using this method from my CrmManager class. Which is, of course, always called within a using-statement:
using (CrmServiceContext context = new CrmServiceContext(CrmManager.ServiceProxy))
{
// do some stuff...
}
How can I prevent these exceptions from constantly occuring? I get the feeling this has to do with the Security Tokens used by the CRM connection expiring, but this shouldn't be a problem when I use the CrmConnection class. It should refresh them automatically.
Any advice would be very welcome, since I am pondering this issue for a while now.
UPDATE 1
I switched to using the Developer Extensions and using the CrmConnector class, to no avail (I updated the code above). I also tried passing the CrmConnection class directly to the CrmServiceContext:
using (CrmServiceContext context = new CrmServiceContext(CrmManager.Connection))
which led to the same problems as in this Stackoverflow Question, without using a load-balancer (we initially did, but disabled load-balancing to eliminate the possibility of it causing the problems.
Full Stacktrace:
---> System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.Xrm.Sdk.IOrganizationService.Execute(OrganizationRequest request)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.ExecuteCore(OrganizationRequest request)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceContext.Execute(OrganizationRequest request)
at Microsoft.Xrm.Sdk.Linq.QueryProvider.RetrieveEntityCollection(OrganizationRequest request, NavigationSource source)
at Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute(QueryExpression qe, Boolean throwIfSequenceIsEmpty, Boolean throwIfSequenceNotSingle, Projection projection, NavigationSource source, List1 linkLookups, String& pagingCookie, Boolean& moreRecords)
at Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute[TElement](QueryExpression qe, Boolean throwIfSequenceIsEmpty, Boolean throwIfSequenceNotSingle, Projection projection, NavigationSource source, List1 linkLookups)
at Microsoft.Xrm.Sdk.Linq.QueryProvider.Execute[TElement](Expression expression)
at Microsoft.Xrm.Sdk.Linq.QueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)
at CrmConnector.Entities.Contact.Get(Guid p_id, Boolean p_includeRelatedEntities) in j:\IntDev\Libraries\CrmConnector\Entities\Contact.cs:line 63
at CrmExtensionService.CrmExtension.GetPersonalizedEmailSignature(String p_contactId, String p_systemUserId) in j:\IntDev\Services\CrmExtensionService\CrmExtension.svc.cs:line 460
We had same issue and load balancer was the culprit. Now we resolved this error with load balancer activated by making few configurations in the load balancer. We enabled sticky session with least connection algorithm at the load balancer. So if this is not enabled while load balanced then authenticated connection from one server's request gets routed to different servers even though same session and fails. Once enabling the sticky session (session persistance to be client ip) requests goes to same server (in this case returning connection and not a new connection) it works well.
So, after fiddling around for about two months, we found the issue: The load balancing of the CRM FrontEnd was the culprit. I assumed this was disabled, too, with disabling the load balancing of our CRM Service, but it wasn't. Our CRM Service periodically established a connection with the Organization Service of Server 1, then got switched to Server 2 mid-operation and these exceptions occurred.
We're still trying to figure out how to get this to work with load balancing activated, but for the time being we keep it disabled to prevent these errors from popping up.
There is a similar case here on StackOverflow: Sporadic exceptions calling a web service that is load balanced. We are currently using a webHttpBinding and a quickly attempted to switch over to a basicHttpBinding but didn't get it to work (but as I said, this was just a quick attempt).

sp2010 - Operation is not valid due to the current state of the object

I have a WebApplication which I extended using CA and made the extension anonymous authorization (it's the RO version of the site).
After deploying my solution, whenever I try to access any page on the site (back or front) I get the error:
Operation is not valid due to the current state of the object.
with trace
[InvalidOperationException: Operation is not valid due to the current state of the object.]
Microsoft.SharePoint.WebControls.SPControl.EnsureSPWebRequest(SPWeb web) +218
Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context) +520
Microsoft.SharePoint.ApplicationRuntime.SPRequestModule.GetContextWeb(HttpContext context) +27
Microsoft.SharePoint.ApplicationRuntime.SPRequestModule.PostResolveRequestCacheHandler(Object oSender, EventArgs ea) +918
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +171
However, when accessing a WCF (from the same solution) everything works fine.
Again this only happens on the extended RO version, normal RW WebApplication works perfectly.
When debugging, i stopped at Application_Start and started to go line by line, once I reached the end and pressed F10 to step over the next function, got the error.
Any Ideas?
With kind regards,
Nadav

Failed to Execute URL - any ideas?

I am seeing some entries of the following exception in my logs and dont know why or where its occurring:
Failed to Execute URL.
at System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.BeginExecuteUrl(String url, String method, String childHeaders, Boolean sendHeaders, Boolean addUserIndo, IntPtr token, String name, String authType, Byte[] entity, AsyncCallback cb, Object state)
at System.Web.HttpResponse.BeginExecuteUrlForEntireResponse(String pathOverride, NameValueCollection requestHeaders, AsyncCallback cb, Object state)
at System.Web.DefaultHttpHandler.BeginProcessRequest(HttpContext context, AsyncCallback callback, Object state)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Has anyone come across this before or could shed some light on it? I running a .net 3.5 c# web application on IIS7.
I just ran into this while using Windows Identity Foundation. The problem ended up being resolved by switching the application pool to use Integrated instead of Classic. It was failing when there was a trailing slash on the url and redirecting to the login page. Specifying the full page in the url didn't give the error.
I had the same error when using WIF in classic pipeline mode. Because we unfortunately cannot change the application to integrated pipeline mode, I've implemented a fix for the specific scenario that David Scott describes.
In global.asax.cs:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
// Fix for "Failed to Execute URL" when non-authenticated user
// browses to application root
if ((User == null)
&& (string.Compare(Request.Url.AbsolutePath.TrimEnd('/'),
Request.ApplicationPath, true) == 0))
{
Response.Redirect(Request.ApplicationPath + "/Default.aspx");
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
Before the authentication attempt, Application_AuthenticateRequest is called with a null User object. Only in that case, the code redirects from / to /Default.aspx (my app is Asp.Net web forms). This fixed the problem for us.
I also had this issue when I was using WIF with .NET 4.5 application in Classic mode. User was geting authenticated from ADFS and then user getting this error. Previously I was sending E-Mail-Addresses -> E-Mail-Address as the claim. Adding another claim rule as E-Mail-Addresses -> Name resoled this issue for me.

Categories