NuGet Gallery and EntityFramework throws Failed to open provider error - asp.net-mvc-3

We have a weird situation going on here. We have setup a local installation of NuGet gallery (the same code that powers http://Nuget.org). The IIS and the DB are on the same box. The IIS App pool has been configured to run under a domain user who is the local admin on the box as well and has the "right to logon as a service" rights. Now when someone (after succesfully logging in) tries and upload a package, the upload package business takes ages and eventually throws up the "The underlying provider failed to open" error
[TimeoutException: Transaction Timeout]
[TransactionException: The operation is not valid for the state of the transaction.]
System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction) +53
System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification) +241
System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx) +273
System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction) +150
System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +2647
System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +89
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6372062
System.Data.SqlClient.SqlConnection.Open() +300
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +67
[EntityException: The underlying provider failed on Open.]
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +11109230
System.Data.EntityClient.EntityConnection.Open() +142
System.Data.Objects.ObjectContext.EnsureConnection() +97
System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal(String commandText, String entitySetName, MergeOption mergeOption, Object[] parameters) +109
System.Data.Objects.ObjectContext.ExecuteStoreQuery(String commandText, Object[] parameters) +87
System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(String sql, Object[] parameters) +118
System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable(String sql, Object[] parameters) +85
System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] parameters) +241
System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator() +34
System.Data.Entity.Internal.InternalSqlQuery`1.GetEnumerator() +28
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +382
System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
NuGetGallery.LuceneIndexingService.GetPackages(DbContext context, Nullable`1 dateTime) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Infrastructure\Lucene\LuceneIndexingService.cs:55
NuGetGallery.LuceneIndexingService.UpdateIndex() in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Infrastructure\Lucene\LuceneIndexingService.cs:32
NuGetGallery.PackageService.CreatePackage(IPackage nugetPackage, User currentUser) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Services\PackageService.cs:61
NuGetGallery.PackagesController.VerifyPackage(Nullable`1 listed) in C:\Source\DotNetDevEng.CitiNuGet\Gallery\DEV\Website\Controllers\PackagesController.cs:503
lambda_method(Closure , ControllerBase , Object[] ) +121
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +248
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +125
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +691
System.Web.Mvc.Controller.ExecuteCore() +162
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +305
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375
Interestingly if I switch IIS App Pool to run under the built in "LocalSystem" account all these problems goes away. The domain user we want to use has been temporarily setup as the database owner for NuGetGallery database but it isn't helping.
Can anyone suggest what setting/configuration we might be missing here?

This was due to ambient transactions going on within the code. The code relied on TransactionScope classes to manage various transactions which were getting in a jam when they got nested. Things turned particularly bad if someone tried uploading a package which was more than around 10MB in size. Once we tweaked the MSDTC on the boxes the application started behaving slightly properly. However it was still intermittently getting deadlocked within its own transactions so for now we have decided to remove transactions from the package upload bit.
For anyone else who gets into this problem I would recommend either of these two
Comment out any reference to TransactionScope in
Services\PackageService.cs (method CreatePackage, line 48)
using (var tx = new TransactionScope())
{
using (var stream = nugetPackage.GetStream())
{
UpdateIsLatest(packageRegistration);
packageRegistrationRepo.CommitChanges();
packageFileSvc.SavePackageFile(package, stream);
tx.Complete();
}
}
And in Controller\PackageController.cs method VerifyPackage(bool? Listed) line 501
using (var tx = new TransactionScope())
{
package = packageSvc.CreatePackage(nugetPackage, currentUser);
packageSvc.PublishPackage(package.PackageRegistration.Id, package.Version);
if (listed.HasValue && listed.Value == false)
packageSvc.MarkPackageUnlisted(package);
uploadFileSvc.DeleteUploadFile(currentUser.Key);
tx.Complete();
}
2 Uncomment those lines and follow the approach mentioned here http://blogs.msdn.com/b/dbrowne/archive/2010/05/21/using-new-transactionscope-considered-harmful.aspx
Basically create a transactionscope which can work well with SQL Server. Create a new class in the InfraStructureFolder, call it TranscationUtils and copy the code in there. Then the using blocks would look like
using (var tx = new TransactionUtils.CreateTransactionScope()){
//cod here
tx.Complete();
}
However this second approach can result in another server error which again relates to the default time outs you can specify for TransactionScope. We have personally decided to go with approach 1 and comment out all TransactionScope references for now.

Related

Sitecore MVC Unity Solr issue

I am new to Sitecore,SoleNet. I have installed and configured Solr to work with Sitecore and I am able to see results.
I am now using code.
I added the connection string to UnityMVCActivator.cs in the Start()
Startup.Init("http://localhost:8983/solr/sitecore_web_index");
In my controller - Actionresults Index()
var solr = ServiceLocator.Current.GetInstance>();
I get this error
[InvalidOperationException: The type ISolrOperations1 does not have an
accessible constructor.]
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForNullExistingObject(IBuilderContext
context) +226 lambda_method(Closure , IBuilderContext ) +39
Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.b__0(IBuilderContext
context) +33
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext
context) +337
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext
context) +396 Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type
t, Object existing, String name, IEnumerable1 resolverOverrides) +238
[ResolutionFailedException: Resolution of the dependency failed, type
= "SolrNet.ISolrOperations`1[Niddk.Model.SearchResultsViewModel]", name = "(none)". Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type ISolrOperations`1 does not have an accessible constructor.
At the time of the exception, the container was:
Resolving
SolrNet.ISolrOperations1[Niddk.Model.SearchResultsViewModel],(none) ]
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object
existing, String name, IEnumerable1 resolverOverrides) +500
Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name,
ResolverOverride[] resolverOverrides) +20
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type
serviceType, String key) +55
[ActivationException: Activation error occured while trying to get
instance of type ISolrOperations1, key ""]
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type
serviceType, String key) +156
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance()
+62 Niddk.Web.Controllers.SearchController.Index() in C:\Users\ksivanandan\Source\Repos\web\Niddk\Niddk.Web\Controllers\SearchController.cs:23
lambda_method(Closure , ControllerBase , Object[] ) +87
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext
controllerContext, IDictionary2 parameters) +229
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor actionDescriptor, IDictionary2
parameters) +35
System.Web.Mvc.<>c__DisplayClass15.b__12()
+80 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext preContext, Func1 continuation) +453
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext preContext, Func`1 continuation) +453
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName) +533
My ViewModel
public class SearchResultsViewModel
{
[SolrField("headline_t")]
public string Headline { get; set; }
}
Any help is greatly appreciated.
Thank you!
Edit: this thread was also raised in GitHub in SolrNet and the project maintainer provided the right answer.
The problem is that for registering he is using the built in IoC but then resolving via Unity.
Original response
I may be reading your code wrong or something might be missing from the post but you are not passing the type:
In my controller - Actionresults Index()
var solr = ServiceLocator.Current.GetInstance<[you are missing this part]>();
When using generics you need to specify the type. I thinks this part would not even compile because of the .GetInstance>() being incomplete.

NullReferenceException in MvcSiteMapProvider at production

The problem is I regularly get the error at the production site (ASP.NET MVC 3) but can't reproduce this error locally.
The text of exception is:
ExceptionType: System.NullReferenceException
Message: Object reference not set to an instance of an object.
StackTrace:
at System.Collections.Specialized.NameObjectCollectionBase.BaseGetAllKeys()
at System.Collections.Specialized.NameValueCollection.get_AllKeys()
at MvcSiteMapProvider.MvcSiteMapNode.get_MetaAttributes()
at MvcSiteMapProvider.Web.Html.SiteMapNodeModelMapper.MapToSiteMapNodeModel(SiteMapNode node, MvcSiteMapNode mvcNode, IDictionary`2 sourceMetadata)
at MvcSiteMapProvider.Web.Html.SiteMapPathHelper.BuildModel(MvcSiteMapHtmlHelper helper, SiteMapNode startingNode)
at MvcSiteMapProvider.Web.Html.SiteMapPathHelper.SiteMapPath(MvcSiteMapHtmlHelper helper, String templateName)
at ASP._Page_Views_Shared__LoggedInLayout_cshtml.Execute() in c:\Solution\Sites\Project2Site\Views\Shared\_LoggedInLayout.cshtml:line 86
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.WebPages.WebPageBase.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
at System.Web.WebPages.WebPageBase.PopContext()
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
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.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
I have no such errors locally. Here is where I invoke MvcSiteMap().SiteMapPath() method:
May be somebody had the same problem before. If so please share your solution.
Thanks in advance.
This won't answer your question directly, but may help you on your path to debugging the issue, seeing as it happens only in production and not in dev/debug.
Consider replacing your line:
#Html.MvcSiteMap().SiteMapPath()
With something like:
#SafeBreadCrumb()
#helper SafeBreadCrumb() {
MvcHtmlString output;
try
{
output = Html.MvcSiteMap().SiteMapPath();
}
catch (Exception e)
{
output = new MvcHtmlString(e.Message);
}
<text>#output</text>
}
Feels a little dirty, but it's easier than grabbing the source of MvcSiteMapProvider and sticking in some logging! If it happened in debug, you wouldn't need to try this. Plus it's just a view change, so won't need a recompile.

Entity Framework Timeout Expired

I recently publish my ASP.Net MVC 3 web application (Entity Framework 4.1 for Data Persistence) to a live server. The application is located on one web server and the database (SQL Server 2008) is located on another separate server.
The site has only been live a few days with very few hits, and because of this there are very few records contained within the database tables (10- 20 max).
I also have ELMAH (Error Logging Modules and Handlers for ASP.NET) integrated into the site and I have received a few instances of the following error already
System.Data.SqlClient.SqlException: Timeout expired. The timeout
period elapsed prior to completion of the operation or the server is
not responding.
Below shows the full details as supplied by ELMAH
System.Data.EntityException: The underlying provider failed on Open.
---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is
not responding. at
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException
exception, Boolean breakConnection) at
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() at
System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject
stateObj, UInt32 error) at
System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult
asyncResult, TdsParserStateObject stateObj) at
System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() at
System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(Boolean
encrypt, Boolean trustServerCert, Boolean& marsCapable) at
System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo,
SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout,
Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean
integratedSecurity) at
System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo
serverInfo, String newPassword, Boolean ignoreSniOpenTimeout,
TimeoutTimer timeout, SqlConnection owningObject) at
System.Data.SqlClient.SqlInternalConnectionTds.LoginWithFailover(Boolean
useFailoverHost, ServerInfo primaryServerInfo, String failoverHost,
String newPassword, Boolean redirectedUserInstance, SqlConnection
owningObject, SqlConnectionString connectionOptions, TimeoutTimer
timeout) at
System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection
owningObject, TimeoutTimer timeout, SqlConnectionString
connectionOptions, String newPassword, Boolean redirectedUserInstance)
at
System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity
identity, SqlConnectionString connectionOptions, Object providerInfo,
String newPassword, SqlConnection owningObject, Boolean
redirectedUserInstance) at
System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions
options, Object poolGroupProviderInfo, DbConnectionPool pool,
DbConnection owningConnection) at
System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection
owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection
owningObject) at
System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection
owningObject) at
System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection
owningObject) at
System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection
owningConnection) at
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection
outerConnection, DbConnectionFactory connectionFactory) at
System.Data.SqlClient.SqlConnection.Open() at
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean
openCondition, DbConnection storeConnectionToOpen, DbConnection
originalConnection, String exceptionCode, String attemptedOperation,
Boolean& closeStoreConnectionOnFailure) --- End of inner exception
stack trace --- at
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean
openCondition, DbConnection storeConnectionToOpen, DbConnection
originalConnection, String exceptionCode, String attemptedOperation,
Boolean& closeStoreConnectionOnFailure) at
System.Data.EntityClient.EntityConnection.Open() at
System.Data.Objects.ObjectContext.EnsureConnection() at
System.Data.Objects.ObjectQuery1.GetResults(Nullable1
forMergeOption) at
System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext
controllerContext, IDictionary2 parameters) at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor actionDescriptor, IDictionary2
parameters) at
System.Web.Mvc.ControllerActionInvoker.<>c_DisplayClass15.b_12()
at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext preContext, Func1 continuation) at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext
controllerContext, IList1 filters, ActionDescriptor actionDescriptor,
IDictionary`2 parameters) at
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName)
The occasions where this error has happened have been due to SELECT queries. These select queries are very simple, ie,
Select col1, col2, col3 from table where col1 = 1
And as I have stated, there is very little data within the database, so it isn’t as if the queries are pulling back 100’s of records.
I have done some research into this using both the Internet and Stackoverflow. Some people suggest to increase the dbContext CommandTimeout Property, however, I don’t understand why I should need to do this. Yes, if I were pulling back loads of records, but as I have said, these are simple SELECT statements pulling back 1-5 records at the most.
I also know that developers need to keep an eye on the SQL generated by the Entity Framework, so, I downloaded and ran this trial version http://www.datawizard.com in order to get a look at the SQL being created for the Entity Framework SELECT queries that were causing a problem. Again, the profiler showed these queries to be very simple syntax, so I don’t think that is the problem.
I am beginning to think maybe it has something to do with my database and web application being on separate servers, however, I am out of ideas!
Please if anyone can help or advise me with this issue, it would be greatly appreciated.
Thanks everyone.

ExecuteReader requires open Connection. Current state: Broken

I'm using StructureMap to inject a LINQ data context (DB class) into my repositories for read queries on a HTTP-context basis, which are queried via a service layer. Everything works fine for a few hours until I get a "Broken" Connection ExecuteReader error (see below for full dump).
Write queries (not read queries) are wrapped in a using (var db = new DB()) {...} statement, which I don't think cause the problem.
I've added MultipleActiveResultSets=true; to my connection string, which seemed to solve the problem for a while, but the error returns until I recycle my application pool, which temporarily solves the problem. Presumably recycling the pool frees all the "broken" data contexes.
StructureMap is configured to inject a data context and repository for each HTTP context:
For<DB>().HttpContextScoped().Use(new DB());
For<IUserRepository>().HttpContextScoped().Use<SqlUserRepository>();
The data context is consumed by my user repository like so:
private DB _db;
public SqlUserRepository(DB db)
{
_db = db;
}
which, in turn conveniently queries the data context like so:
public IQueryable<User> GetUsers()
{
var users = from u in _db.Users
select u; // omitted the rest
}
Which after a few hours ends up with this horrible error:
System.InvalidOperationException: ExecuteReader requires an open and available
Connection. The connection's current state: Broken. at
System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) at
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior
runBehavior, Boolean returnStream, String method, DbAsyncResult result) at
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior
runBehavior, Boolean returnStream, String method) at
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at
System.Data.Common.DbCommand.ExecuteReader() at
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo,
IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[]
subQueries, Object lastResult) at
System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos,
IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) at
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expressi
on query) at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression
expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source) at
MyApp.Data.SqlUserRepository.GetUser(String username) at
MyApp.Services.BranchService.GetUser(String username) at
MyApp.Controllers.BranchController.get_CurrentUser() at
MyApp.Controllers.BranchController.OnActionExecuting(ActionExecutingContext filterContext)
at
System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuting(ActionExecutingCon
text filterContext) at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter,
ActionExecutingContext preContext, Func`1 continuation) at
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<>c__DisplayClassf.b__c() at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext
controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2
parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName)
How do I solve this? I really don't want to have to manually wrap every query in a using-statement.
It looks like you're unintentionally are creating a singleton of the Context:
For<DB>().HttpContextScoped().Use(new DB());
In order to create a new context per request, use this instead:
For<DB>().HttpContextScoped().Use(() => new DB());
I would just use a new DataContext for each repository unless you can't for some reason. See this question: Strange behaviour with StructureMap / ASP.MVC / Visual Studio / LinqToSql
Your GetUsers method is returning an IQueryable, meaning the data will not be retrieved from the database until something iterates over it. If you return the IQueryable, close your data reader, and then attempt to iterate over the data, you will get an error, because the connection is closed.
One reason for this would be that your connection could not be opening at all. What ever exception that is coming at the "SqlConnection.Open" statement is being suppressed. If the problem is not in your application it could be that server is unable to grant you a connection. Could be because of a connection leak in your app or in some other database hosted on the same server.

Intermittent "Specified cast is invalid" with StructureMap injected data context

I am intermittently getting an System.InvalidCastException: Specified cast is not valid. error in my repository layer when performing an abstracted SELECT query mapped with LINQ.
The error can't be caused by a mismatched database schema since it works intermittently and it's on my local dev machine.
Could it be because StructureMap is caching the data context between page requests? If so, how do I tell StructureMap v2.6.1 to inject a new data context argument into my repository for each request?
Update: I found this question which correlates my hunch that something was being re-used. Looks like I need to call Dispose on my injected data context. Not sure how I'm going to do this to all my repositories without copypasting a lot of code.
Edit: These errors are popping up all over the place whenever I refresh my local machine too quickly. Doesn't look like it's happening on my remote deployment box, but I can't be sure.
I changed all my repositories' StructureMap life cycles to HttpContextScoped() and the error persists.
Code:
public ActionResult Index()
{
// error happens here, which queries my page repository
var page = _branchService.GetPage("welcome");
if (page != null)
ViewData["Welcome"] = page.Body;
...
}
Repository:
GetPage boils down to a filtered query mapping in my page repository.
public IQueryable<Page> GetPages()
{
var pages = from p in _db.Pages
let categories = GetPageCategories(p.PageId)
let revisions = GetRevisions(p.PageId)
select new Page
{
ID = p.PageId,
UserID = p.UserId,
Slug = p.Slug,
Title = p.Title,
Description = p.Description,
Body = p.Text,
Date = p.Date,
IsPublished = p.IsPublished,
Categories = new LazyList<Category>(categories),
Revisions = new LazyList<PageRevision>(revisions)
};
return pages;
}
where _db is an injected data context as an argument, stored in a private variable which I reuse for SELECT queries.
Calling code:
public Page GetPage(string slug)
{
return _pageRepository.GetPages()
.WithSlug(slug).FirstOrDefault();
}
WithSlug is just a pipeline filter that adds a where clause to the query.
Error:
Specified cast is not valid.
Exception Details: System.InvalidCastException: Specified cast is not valid.
Stack Trace:
[InvalidCastException: Specified cast is not valid.]
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +4539
System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries) +207
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +500
System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute(Expression expression) +50
System.Linq.Queryable.FirstOrDefault(IQueryable`1 source) +383
Manager.Controllers.SiteController.Index() in C:\Projects\Manager\Manager\Controllers\SiteController.cs:68
lambda_method(Closure , ControllerBase , Object[] ) +79
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +258
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
System.Web.Mvc.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() +125
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +709
System.Web.Mvc.Controller.ExecuteCore() +162
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +58
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371
Messing around with disposing repositories didn't help, but setting MultipleActiveResultsets to true in my SQL connection string solved the problem.

Resources