EF Core 5 Add-migration error object reference not set to an instance of an obejct - ef-core-5.0

We are having issues with Add-Migration in EF core.
Nothing major has changed since we did a sucessfully migration 3 weeks ago.
Now we are getting the following error:
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Initialize(ColumnOperation columnOperation, IColumn column, RelationalTypeMapping typeMapping, Boolean isNullable, IEnumerable`1 migrationsAnnotations, Boolean inline)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(IColumn source, IColumn target, DiffContext diffContext)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(ITable source, ITable target, DiffContext diffContext)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable`1 operations, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IRelationalModel source, IRelationalModel target)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.
I have tried to delete the DbContextSnapshot file and run Add-Migration again, this creates a huge migration file. Then I deleted the newly created migration file manually and run Add-Migration again but same error occurs.
Does anyone have any suggestions on how to troubleshoot this error?
Best regards

Related

Unable to cast object of type 'System.Int32' to type 'System.Collections.ArrayList'."

We have a replicated cache with 2 nodes, from time to time, we received this error and we aren't able to resolve: "Unable to cast object of type 'System.Int32' to type 'System.Collections.ArrayList'."
The stacktrace:
at Alachisoft.NCache.Web.Command.CommandResponse.ParseResponse()
at Alachisoft.NCache.Web.Caching.RemoteCache.Add(String key, Object value, CacheDependency dependency, CacheSyncDependency syncDependency, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, Int16 removeCallback, Int16 updateCallback, Int16 dsItemAddedCallback, Boolean isResyncExpiredItems, String group, String subGroup, Hashtable queryInfo, BitSet flagMap, String providerName, String resyncProviderName, EventDataFilter updateCallbackFilter, EventDataFilter removeCallabackFilter, Int64 size, String clientId)
at Alachisoft.NCache.Web.Caching.Cache.AddOperation(String key, Object value, CacheDependency dependency, CacheSyncDependency syncDependency, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, DSWriteOption dsWriteOption, CacheItemRemovedCallback onRemoveCallback, CacheItemUpdatedCallback onUpdateCallback, DataSourceItemsAddedCallback onDataSourceItemAdded, Boolean isResyncExpiredItems, String group, String subGroup, Tag[] tags, String providerName, String resyncProviderName, NamedTagsDictionary namedTags, CacheDataNotificationCallback cacheItemUdpatedCallback, CacheDataNotificationCallback cacheItemRemovedCallaback, EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter, Int64& size, Boolean allowQueryTags, String clientId, Int16 updateCallbackID, Int16 removeCallbackID, Int16 dsItemAddedCallbackID)
at Alachisoft.NCache.Web.Caching.Cache.Add(String key, CacheItem item, DSWriteOption dsWriteOption, DataSourceItemsAddedCallback onDataSourceItemAdded)
at Alachisoft.NCache.Web.Caching.Cache.Add(String key, CacheItem item)
In the log files we see:
...received response for request 118849, sender=<IP_Server_1>:7800, val=System.Byte[]
...received response for request 118849, sender=<IP_Server_2>:7800, val=Alachisoft.NCache.Common.DataStructures.Clustered.ClusteredArrayList
How can we resolve this problem?
The casting exception that you are getting is rather strange. This usually thrown on Cache get calls where you may be using an invalid cast. However, in this particular case it is on adding item to the cache which makes me believe this is on server side. Will need to review this - can you share some more details on this.
Please share complete application code snippet along with the flow on _cache.Add API within your code. Also share NCache version and edition information in order to review this in detail. You can run the "verifylicense.exe" tool (located at "C:\Program Files\NCache\bin\tools\verifylicense.exe") to check the current NCache version.
I think you should contact NCache support - support#alachisoft.com - their support is excellent - they should be able to expedite this for you.

Visual Studio and IIS Express randomly stops working

I have been using this machine for development since a year and its a brand new one. Now from 2-3 days my visual studio stops working while I am running my asp.net MVC application and restarts. Sometimes IIS Express stops working and even the browser exits.
I have checked activitylog.xml
Source: Editor or Editor Extension
System.ComponentModel.Win32Exception (0x80004005): Not enough storage
is available to process this command at
MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d) at
MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32
exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name,
IntPtr parent, HwndWrapperHook[] hooks) at
System.Windows.Interop.HwndSource.Initialize(HwndSourceParameters
parameters) at
System.Windows.Interop.HwndSource..ctor(HwndSourceParameters
parameters) at
System.Windows.Controls.Primitives.Popup.PopupSecurityHelper.BuildWindow(Int32
x, Int32 y, Visual placementTarget, Boolean transparent,
HwndSourceHook hook, AutoResizedEventHandler handler) at
System.Windows.Controls.Primitives.Popup.BuildWindow(Visual
targetVisual) at
System.Windows.Controls.Primitives.Popup.CreateWindow(Boolean
asyncCall) at
System.Windows.Controls.Primitives.Popup.OnIsOpenChanged(DependencyObject
d, DependencyPropertyChangedEventArgs e) at
System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs
e) at
System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs
e) at
System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs
args) at
System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex
entryIndex, DependencyProperty dp, PropertyMetadata metadata,
EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean
coerceWithDeferredReference, Boolean coerceWithCurrentValue,
OperationType operationType) at
System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp,
Object value, PropertyMetadata metadata, Boolean
coerceWithDeferredReference, Boolean coerceWithCurrentValue,
OperationType operationType, Boolean isInternal) at
System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object
value) at
Microsoft.VisualStudio.Language.Intellisense.Implementation.MouseTrackingQuickInfoPresenter.Render()
at
Microsoft.VisualStudio.Language.Intellisense.Implementation.IntellisenseSessionStack.OnSessionPresenterChanged(Object
sender, EventArgs e) at
Microsoft.VisualStudio.Language.Intellisense.Implementation.IntellisenseSession.RaisePresenterChanged()
at
Microsoft.VisualStudio.Language.Intellisense.Implementation.QuickInfoSession.Recalculate()
at
Microsoft.VisualStudio.Language.Intellisense.Implementation.QuickInfoSession.Start()
at
Microsoft.VisualStudio.Language.Intellisense.Implementation.DefaultQuickInfoController.OnTextView_MouseHover(Object
sender, MouseHoverEventArgs e) at
Microsoft.VisualStudio.Text.Editor.Implementation.WpfTextView.RaiseHoverEvents()
Some logs Before this error are as follows
Begin package load [Microsoft.VisualStudio.Debugger.Parallel]
End package load [Microsoft.VisualStudio.Debugger.Parallel]
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Entering function VBDispatch::GetTypeLib
Leaving function VBDispatch::GetTypeLib
Then error (pasted in the start) occurs.
Also where else should i look to trace the real cause as this is yesterday's log only.
UPDATE
My event log actually gives devenv error
Application: devenv.exe
Framework Version: v4.0.30319
Description: The
process was terminated due to an unhandled exception. Exception Info:
System.ComponentModel.Win32Exception at
MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D) at
MS.Win32.HwndWrapper..ctor(Int32, Int32, Int32, Int32, Int32, Int32,
Int32, System.String, IntPtr, MS.Win32.HwndWrapperHook[])
The issue was (totally code related) due to RichTextBox control. Microsoft has given a work around for this bug here

Caching LINQ-SQL objects and DataContext thread safety

We are querying database using LINQ-SQL and then storing resulting master table objects in HTTP cache.
Later, the master objects are being used to query its children, using lazy loading. Here are the relevant pieces of code - I have recreated the scenario in a new proof-of-concept app:
if (HttpRuntime.Cache["c"] == null)
{
LockApp.Models.DBDataContext db = new Models.DBDataContext();
var master = db.Masters.ToList();
HttpRuntime.Cache.Add("c", master,
null, DateTime.Now.AddMonths(1),
TimeSpan.Zero, CacheItemPriority.Normal, null);
}
ViewBag.Data = (List<LockApp.Models.Master>)HttpRuntime.Cache["c"];
And here's the razor view that is iterating over master and detail objects:
#foreach(var m in ViewBag.Data){
#m.Id<nbsp></nbsp>
foreach(var d in m.Details){
#d.Id<nbsp></nbsp>
}
<br />
}
It works perfectly fine and caches the data correctly. However, it fails when there are multiple requests trying to hit the web site after cache is cleared - I am testing this using JMeter, basically hitting the site with many (50) parallel threads, and then touching web.config - I immediately start seeing one of the following two errors:
Index was outside the bounds of the array
at foreach(var d in m.Details)
this error never goes away, i.e. some data gets corrupted in cache
with following stack:
System.Collections.Generic.List`1.Add(T item) +34
System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user) +305
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +59
System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) +118
System.Data.Linq.SqlClient.CompiledQuery.Execute(IProvider provider, Object[] arguments) +99
System.Data.Linq.DeferredSourceFactory`1.ExecuteKeyQuery(Object[] keyValues) +402
System.Data.Linq.DeferredSourceFactory`1.Execute(Object instance) +888
System.Data.Linq.DeferredSource.GetEnumerator() +51
System.Data.Linq.EntitySet`1.Load() +107
System.Data.Linq.EntitySet`1.GetEnumerator() +13
System.Data.Linq.EntitySet`1.System.Collections.IEnumerable.GetEnumerator() +4
ASP._Page_Views_Home_Index_cshtml.Execute() in c:\Users\prc0092\Documents\Visual Studio 2012\Projects\LockApp\LockApp\Views\Home\Index.cshtml:16
or this error
ExecuteReader requires an open and available Connection. The connection's current state is open.
at the same line foreach(var d in m.Details)
this error does go away after a while if I stop hitting the site with parallel requests
with following stack
System.Data.SqlClient.SqlConnection.GetOpenConnection(String method) +5316460
System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +7
System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +155
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +82
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +53
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +134
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +41
System.Data.Common.DbCommand.ExecuteReader() +12
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +1306
System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) +118
System.Data.Linq.SqlClient.CompiledQuery.Execute(IProvider provider, Object[] arguments) +99
System.Data.Linq.DeferredSourceFactory`1.ExecuteKeyQuery(Object[] keyValues) +402
System.Data.Linq.DeferredSourceFactory`1.Execute(Object instance) +888
System.Data.Linq.DeferredSource.GetEnumerator() +51
System.Data.Linq.EntitySet`1.Load() +107
System.Data.Linq.EntitySet`1.GetEnumerator() +13
System.Data.Linq.EntitySet`1.System.Collections.IEnumerable.GetEnumerator() +4
ASP._Page_Views_Home_Index_cshtml.Execute() in c:\Users\prc0092\Documents\Visual Studio 2012\Projects\LockApp\LockApp\Views\Home\Index.cshtml:16
Different things I tried
Double locking
Doesn't help
private static object ThisLock = new object();
public ActionResult Index()
{
if (HttpRuntime.Cache["c"] == null)
{
lock (ThisLock)
{
if (HttpRuntime.Cache["c"] == null)
{
Loading child data upfront
Works, but requires constant maintenance as not all children should be loaded upfront, plus see next note
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Master>(b => b.Details);
db.LoadOptions = dlo;
Locking the master object while trying to access its children
Again, requires maintenance as all initial places where child is accessed need to be found - we are struggling with this as there are different entry paths into the site
#foreach(var m in ViewBag.Data){
#m.Id<nbsp></nbsp>
lock (m){
foreach(var d in m.Details){
#d.Id<nbsp></nbsp>
}
}
<br />
}
Switching to entity framework
This seems to still have (sometimes - much better than linq-sql) the "open connection" issue at certain number of parallel requests (50+ on core i7) - it does go away after a while as I mentioned and I haven't seen data corruption yet.
We may end up switching to EF completely as this seems to be the only viable path - assuming data corruption doesn't show up - that is to be tested on my actual project.
I am not optimistic though, as EF data context is not thread safe either, and I think the EF data objects carry their context with them. This is probably the only question that I don't have answer to yet.
Theories on why it's broken
It looks like storing LINQ-SQL object in http cache carries the data context with it. When this context is later used by multiple threads to access children, there is some type of concurrency issue that manifests itself in either temporary connectivity issue or complete data corruption of the child object. As there's no way to disconnect/reconnect the context from the LINQ object, it looks like the only suggestion is not to cache LINQ objects that need lazy-loading of their children - a substantial number of google searches I did does not seem to give you that advice, in fact sometimes it's opposite.
I have uploaded the complete project (for Visual Studio 2012 and SQL Server 2012)
https://docs.google.com/file/d/0B8CQRA9dD8POb3U5RGtCV3BMeU0/edit?usp=sharing
and a simple JMeter script that will hit your local machine with parallel requests:
https://docs.google.com/file/d/0B8CQRA9dD8POd1VYdGRDMEFQbEU/edit?usp=sharing
to test, start the site and run the test - then touch the web.config on the site
LockApp.Models.DBDataContext db = new Models.DBDataContext();
var master = db.Masters.ToList();
You should have a call to db.ObjectTrackingEnabled = false in between these two calls. Otherwise all of the objects will be tracked by the datacontext so that changes can be written back into the database. Since you're caching these objects to be read by multiple threads, you do not want this. (It's also more expensive even in single-threaded cases to track objects you won't change, so worth doing in other places).
Also, use LoadWith to eagerly load any properties you might want to access of these cached entities, so they are all loaded on the initial caching thread, rather than with (potentially mulitple) threads that try to access them.

All MVC pages fail with the message an item with the same key has already been added

Ultimately I am trying to address the same issue that is referenced in Loading any MVC page fails with the error “An item with the same key has already been added.” and An item with the same key has already been added. A duplicate of the first link is All MVC pages fail with the message an item with the same key has already been added but it has some additional pertinent information, confirming that it only effects MVC pages, while webforms and other aspects of the application that deal with appSettings continue to work without error.
I have now seen this four times in production and it has not been seen in any other environment (dev, test, UAT). I have closely examined and debugged through the source code of System.Web.WebPages and the relevant sections of the MVC stack but did not run into anything that stood out. This problem has persisted through a migration from MVC3 to MVC4, and the latest changeset from aspnetwebstack.codeplex.com does not appear to address this issue.
A quick summary of the issue:
Every MVC page is affected and completely unusable
WebForms and other aspects of the application that use appSettings continue to work just fine
Only an appPool restart will correct this issue
At least once and as referenced in an article above, this has happened after a regular time interval recycle of the appPool by IIS
This has happened during both low and high volume traffic periods
This has happened on multiple production servers, but the issue only affects a single server at any given time, as other servers continue serving MVC pages
The offending line of code is var items = new Lazy<Dictionary<object, object>>(() => appSettings.AllKeys.ToDictionary(key => key, key => (object)appSettings[key], comparer));, but it occurs when the lazy initialization is forced by requesting a value from items The appSettings variable is from System.Web.WebConfigurationManager.AppSettings which is a direct static reference to System.Configuration.ConfigurationManager.AppSettings. So I beleive the line is equivalent to: var items = new Lazy<Dictionary<object, object>>(() => System.Configuration.ConfigurationManager.AppSettings.AllKeys.ToDictionary(key => key, key => (object)appSettings[key], comparer));
I rarely suspect framework issues, but it appears that appSettings has two distinct keys that are the same (not the same as a NameValueCollection supporting multiple values for the same key). The comparer being used in the MVC stack is the StringComparer.OrdinalIgnoreCase which appears to match what is used by the configuration system. If this is a framework issue, the MVC stack appears to be very unforgiving when it forces the NameValueColleciton into a dictionary using the ToDictionary() extension method. I believe using appSettings.AllKeys.Distinct().ToDictionary(...) would probably allow the MVC stack to operate normally as the rest of the application does and be oblivious to the possibility of duplicate keys. This unforgiving nature appears to also contribute to the issue described in NullReferenceException in WebConfigScopeDictionary
Server stack trace:
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at System.Web.WebPages.Scope.WebConfigScopeDictionary.<>c__DisplayClass4.<.ctor>b__0()
at System.Lazy`1.CreateValue()
Exception rethrown at [0]:
at System.Lazy`1.get_Value()
at System.Web.WebPages.Scope.WebConfigScopeDictionary.TryGetValue(Object key, Object& value)
at System.Web.Mvc.ViewContext.ScopeGet[TValue](IDictionary`2 scope, String name, TValue defaultValue)
at System.Web.Mvc.ViewContext.ScopeCache..ctor(IDictionary`2 scope)
at System.Web.Mvc.ViewContext.ScopeCache.Get(IDictionary`2 scope, HttpContextBase httpContext)
at System.Web.Mvc.ViewContext.GetClientValidationEnabled(IDictionary`2 scope, HttpContextBase httpContext)
at System.Web.Mvc.Html.FormExtensions.FormHelper(HtmlHelper htmlHelper, String formAction, FormMethod method, IDictionary`2 htmlAttributes)
at ASP._Page_Areas_Client_Views_Equipment_Index_cshtml.Execute()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
To separate my question from the questions already asked, I will ask has anyone seen the configuration system be corrupted with multiple duplicate keys or where a NameValueCollection.AllKeys returns two identical keys? I know you can have multiple keys defined in the config file, but the last key wins, and that scenario does not reproduce this issue.
Although I am not alone in seeing this behavior multiple times, there are relatively few posts describing this issue, so I also suspect that it might be a configuration/environmental issue, but again, servers will run for months without experiencing this issue, and an appPool restart immediately corrects the problem.
I have mitigated this issue by forcing an appPool restart if a server starts seeing this error, but management is not happy about this "hacky" solution because some user will still experience an error.
Help?!?!?
EDIT:
Here is a contrived, cheezy test that can reproduce the scenario, but doesn't help in solving the issue. It happens during approx. 20% of the test runs. The code will blow up for other threading reasons, but it is the "Same key has already been added" error that is of interest.
[TestClass]
public class UnitTest1
{
readonly NameValueCollection _nameValueCollection = new NameValueCollection();
private Lazy<Dictionary<object, object>> _items;
[TestMethod]
public void ReproduceSameKeyHasAlreadyBeenAdded()
{
Thread[] threads = new Thread[1000];
for (int i = 0; i < 1000; i++)
{
ThreadStart threadStart = AddEntry;
Thread thread = new Thread(threadStart);
threads[i] = thread;
}
foreach (var thread in threads)
thread.Start();
Thread.Sleep(100);
_items = new Lazy<Dictionary<object, object>>(() => _nameValueCollection.AllKeys.ToDictionary(key => key, key => (object)_nameValueCollection[key], ScopeStorageComparer.Instance));
object value;
_items.Value.TryGetValue("4", out value); // approx. 20% of time, blows up here with mentioned error
Assert.IsTrue(value != null);
}
private int _counter;
private void AddEntry()
{
_counter++;
try
{ // add a bunch of even keys, every other one a duplicate
_nameValueCollection.Add((_counter%2) == 0 ? _counter.ToString() : (_counter + 1).ToString(), "some value");
}
catch {}
}
}
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at UnitTestProject1.ReproduceSameKeyHasAlreadyBeenAdded.<TestMethod1>b__0() in c:\Git\AspNetWebStack\aspnetwebstack\UnitTestProject1\UnitTest1.cs:line 37
at System.Lazy`1.CreateValue()
We came across this same issue and finally tracked it down to dynamic updating of the ConfigurationManager.AppSettings collection. I have posted a full answer here: https://stackoverflow.com/a/17415830/2423407
Are you absolutely positive the error is occurring on the line where you are initializing items and not the line on which items is being used to add to some other dictionary (Static I would presume).
To me the most likely way this would occur is if the code was executed in parallel (by two concurrent users) and the second one executing causing the exception.
As a general workaround I usually initialize a strongly typed class with all configuration parameters as an auto-start provider (and add some strongly-typed type checking of the values as well, such as checking that an int is an int, etc) to avoid run-time errors.
This has the double benefit of loading these at warmup, not when the users want the info (better response performance) and thread-safety is supposedly guaranteed with them as well.
See if that doesn't fix your issue. If you do not want to do that I would at the very least try to execute the code that is failing for you with multiple threats hitting it, as my guess would be that you will see your error occur fairly reliably.

Exception when handling multiple hostnames in Composite C1

I have a problem configuring multiple hostnames in Composite C1.
Background:
I have two websites in C1: site1 and site2. The C1 installation is mainly for site1 and works with the host www.site1.com (and alias site1.com).
Now I've added another site, site2, to C1. When browsing to site1.com/site2 I end up on the site2 website. All fine. Then I try to add another hostname, www.site2.com, to URL Configuration -> Hostnames. After adding www.site2.com and browsing to www.site2.com I get the following exception: "Item has already been added. Key in dictionary: '' Key being added: ''"
The stacktrace looks as follows:
[ArgumentException: Item has already been added. Key in dictionary: '' Key being added: '']
System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) +9353115
System.Collections.Hashtable.Add(Object key, Object value) +11
Composite.Core.Collections.Generic.Hashtable`2.Add(TKey key, TValue value) +105
Composite.Plugins.Routing.Pages.PageUrlBuilder.BuildUrlSet(IPage page, Guid parentPageId) +1935
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.BuildFolderPaths(SitemapBuildingData pagesData, IEnumerable`1 elements, IDictionary`2 urlToIdLookup, IPageUrlBuilder builder) +253
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.BuildMap(UrlSpace urlSpace) +2200
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.GetMap(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace) +482
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.GetPageUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace) +9
Composite.Plugins.Routing.Pages.DefaultPageUrlProvider.ParseUrl(String relativeUrl, UrlSpace urlSpace, UrlKind& urlKind) +311 Composite.Plugins.Routing.Pages.DefaultPageUrlProvider.ParseUrl(String absoluteUrl, UrlKind& urlKind) +306 Composite.Core.Routing.Pages.C1PageRoute.GetRouteData(HttpContextBase context) +156
System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +287
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +60
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +86
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Does anyone have a solution for this?
Thanks in advance...
UPDATE:
After changing the dll suggested by Dmitry Dzygin I get the following stack trace:
[ArgumentException: Item has already been added. Key in dictionary: '' Key being added: '']
System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) +9353115
System.Collections.Hashtable.Add(Object key, Object value) +11
Composite.Core.Collections.Generic.Hashtable`2.Add(TKey key, TValue value) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\Collections\Generic\Hashtable.cs:28
Composite.Plugins.Routing.Pages.PageUrlBuilder.BuildUrlSet(IPage page, Guid parentPageId) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Plugins\Routing\Pages\PageUrlBuilder.cs:190
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.BuildFolderPaths(SitemapBuildingData pagesData, IEnumerable`1 elements, IDictionary`2 urlToIdLookup, IPageUrlBuilder builder) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\WebClient\Renderings\Page\PageStructureInfo.cs:630
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.BuildFolderPaths(SitemapBuildingData pagesData, IEnumerable`1 roots, IPageUrlBuilder pageUrlBuilder, IDictionary`2 urlToIdLookup) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\WebClient\Renderings\Page\PageStructureInfo.cs:612
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.BuildMap(UrlSpace urlSpace) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\WebClient\Renderings\Page\PageStructureInfo.cs:559
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.GetMap(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\WebClient\Renderings\Page\PageStructureInfo.cs:277
Composite.Core.WebClient.Renderings.Page.PageStructureInfo.GetPageUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\WebClient\Renderings\Page\PageStructureInfo.cs:342
Composite.Plugins.Routing.Pages.DefaultPageUrlProvider.ParseUrl(String relativeUrl, UrlSpace urlSpace, UrlKind& urlKind) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Plugins\Routing\Pages\DefaultPageUrlProvider.cs:249
Composite.Plugins.Routing.Pages.DefaultPageUrlProvider.ParseUrl(String absoluteUrl, UrlKind& urlKind) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Plugins\Routing\Pages\DefaultPageUrlProvider.cs:206
Composite.Core.Routing.Pages.C1PageRoute.GetRouteData(HttpContextBase context) in c:\Builds\1\Freja\CodeplexBuild\Sources\Public\Composite\Core\Routing\Pages\C1PageRoute.cs:90
System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +287
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +60
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +86
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Looks like some of kind of a url collision when 2 C1 pages received the same url or something like that. As a solution I recommend you to copy debug version Composite.dll file and Composite.pdf files to the /bin folder of your website. You can find those at Codeplex in "Other available downloads section" of the release page ( http://compositec1.codeplex.com/releases/view/80764 ) After that you will see the exact line in the code that caused it. Once you have it, I'll be able to either fix it or to add some code assertions/validation logic.
Update.
Looking through code it appears that the exception is possible only if you have 2 websites with empty "UrlTitle" field. Normally there's validation logic that prevents this situation from happenning. Try to edit both website's roots, give them not empty "Url Title" fields, and publish them afterwards, that should solve the issue. If the bug is still persists, I either need a better repro (I failed to reproduce it with the provided one), or if you send me a copy of a website, I'll debug it.

Resources