structuremap entity framework 4 connection - asp.net-mvc-2

I am using the following Structuremap bootstrapping code for my entity framework 4 entities:
x.For<XEntities>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(() => new XEntities());
But when I do two nearly simultaneous requests, I get the following exception:
EntityException:The underlying provider failed on Open.
{"The connection was not closed. The connection's current state is connecting."}
I am using ASP.NET MVC 2, en have the following in my Application_Start()
EndRequest += new EventHandler(MvcApplication_EndRequest);
void MvcApplication_EndRequest(object sender, EventArgs e)
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
What can I do to fix this?
[edit]
this happens on a page with several images on it. The images come from the database, served by an Controller Action, which reads the image from the database, and sends it as a file result to the browser. I think that asp.net is breaking down my objectcontext, and closing my db connection when the requests for the images come in, and the exception is thrown.
What I need now, is a correct way to manage the lifetime of the object context in the good way.

Why are you assigning a delegate for EndRequest in Application_Start()?
Just hook directly into the event:
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
Also, i have never used that syntax before, this is how i do it:
For<XEntities>().HybridHttpOrThreadLocalScoped().Use<XEntities>()
Also, at what point do you new up your Data Context? Can you show some code?

Related

C# MVC5 classic ADO.NET when to open connection

I'm using MVC5 with classic ADO.NET objects such as sqldatareader and sqldataadapter and sqlconnection and so on....
My controllers are creating a connection while initializing because I need to send the request object to the class holding the sqlconnection for something irrelevant to the question so my controller has an override void
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
db = new db(Request);
db.Connect();
}
Where db is my class and the method (connect) will create the sqlconnection object and open a connection...
and to close the connection I used the controller's dispose method as follows
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (db != null)
{
db.Close();
db = null;
}
}
and everything works fine then at one moment I got a weird server error (can't connect to db) please notice that my host is smarterasp.net
I can connect to database remotely using my home computer and I can connect to the web host as well so the problem is between my webhost and my database host, or between my application and my database host...
or it could be something related to the connection pooling even though the server error doesn't give me any details or stack trace(hens error is not inside my app thread)....
and I've fixed the problem by opening (remote iis) tab of smarterasp.net's control panel and clicked on (fix ACL) which I have no idea what it does but it fixed my problem.... temporarily :( unfortunately the problem reoccurred many times after that
so my question is in short format
is it good practice to open the connection while I'm initializing the controller and close it while the controller disposing???
and what do you think the error reason is??
finally I want to apologize if the question wasn't clear enough because English is not my first language (obviously)....
thanks a lot
so my question is in short format is it good practice to open the
connection while I'm initializing the controller and close it while
the controller disposing???
I do not think that is a good approach. You shouldn't open / close database connections and / or access the database from your controller. The controller should be as "thin" as possible. Additionally - the connection should be kept open for as short a period of time as possible and let ADO.NET connection pooling handle the details for you.
I also recommend wrapping your connection in a using block as it will implicitly call the close method:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
You did not say what the exact error is. At first glance, you aren't even checking to see if the connection is open before you try closing it. You should check the connection state before you try to explicitly close it and this should happen outside of the controller. Though I recommend that you wrap your SqlConnection in a using block (mentioned above).
EDIT
I read your comment. You are trying to manage the connection within the context of the controller's lifecycle and I suspect this is your issue.
If you were using Entity Framework (or possibly an another ORM), an IoC with "per-request lifestyle" - then the IoC container would properly dispose your context (connection) at the end of each request, and serve a new instance at each new one.
Perhaps this an option you can explore if you want to manage your database connection this way.

Explicit transaction for entire request duration with automatic commit/rollback on errors (EF6, Web API2, NInject)

I'm starting a new Web API application, and I'm unsure how to handle transactions (and subsequent rollbacks in case of exceptions).
My overall goal is so have a single database connection per request, and have the entire thing wrapped in an explicit transaction.
I'll need an explicit transaction since I will be executing stored procedures aswell, and need to rollback any results from those if my application should throw any exceptions.
My plan was to re-use an approach I've used in MVC applications in the past which in rough terms was simply binding my database context to requestscope using ninject and then handling rollback/commit in the ondeactivation event.
Let's say I have a controller with two methods.
public class MyController : ApiController {
public MyController(IRepo repo) {
}
}
public string SimpleAddElement() {
_repo.Add(new MyModel());
}
public string ThisCouldBlowUp() {
// read from context
var foo = _repo.ReadFromDB();
// execute stored prodecure which changes some content
var res = _repo.StoredProcOperation();
// throw an exception due to bug/failsafe condition
if (res == 42)
throw Exception("Argh, an error occured");
}
}
My repo skeleton
public class Repo : IRepo {
public Repo(IMyDbContext context) {
}
}
From here, my plan was to simply bind the repositories using
kernel.Bind<IRepo>().To<Repo>();
and provide a single database context per request using
kernel.bind<IMyDbContext>().To<CreateCtx>()
.InRequestScope()
.OnDeactivate(FinalizeTransaction);
private IMyDbContext CreateCtx(IMyDbContext ctx) {
var ctx = new DbContext();
ctx.Database.BeginTransaction();
}
private void FinalizeTransaction(IMyDbContext ctx) {
if (true /* no errors logged on current HttpRequest.AllErrors */)
ctx.Commit();
else
ctx.Rollback();
}
Now, if I invoke SimpleAddElement from my browser FinalizeTransaction never gets invoked... So either I'm doing something wrong suddently, or missing something related to WebAPI pipeline
So how should I go about implementing a transactional "single DB session per request"-module?
What is best practise ?
If possible, I'd like the solution to support ASP vNext aswell
I suppose one potential solution could dropping the "ondeactivation" handler and implementing an HTTP module which will commit in Endrequest and rollback in Error... but there's just something about that I dont like.
You are missing an abstraction in your code. You execute business logic inside your controller, which is the wrong place. If you extract this logic to the business layer and hide it behind an abstraction, it will be trivial to wrap all business layer operations inside a transaction. Take a look at this article for some examples of this.

EF7 alpha connection state problems

I'm trying to use EF in a asp.net vNext SPA application.
I'm registering the context class with the build in dependency injection container using AddScoped() (just like they have it in the examples) but when I try to perform a delete operation on an entity I get weird errors.
Sometimes the delete works, sometimes I get a
Invalid operation. The connection is closed.
and sometimes I get a
The connection was not closed. The connection's current state is open.
This only happens for delete operations and I can't find a pattern on when the 'connection is open' and 'connection is closed' appear.
Here's my delete method body (the method is virtual because this is a base controller, though no overrides exist for it yet):
public virtual async Task<IActionResult> Delete(int id)
{
var t = await Items.SingleOrDefaultAsync(i => i.ID == id);
if (t == null)
return new HttpStatusCodeResult((int)HttpStatusCode.NoContent);
Items.Remove(t);
AppContext.SaveChanges();
return new HttpStatusCodeResult((int)HttpStatusCode.OK);
}
Problem disappeared after migrating to alpha3

EF + UnitOfWork + SharePoint RunWithElevatedPrivileges

In our SharePoint application we have used the UnitOfWork + Repository patterns together with Entity Framework. To avoid the usage of the passthrough authentication we have developed a piece of code that impersonate a single user before creating the ObjectContext instance in a similar way that is described in "Impersonating user with Entity Framework" on this site.
The only difference between our code and the referred question is that, to do the impersonation, we are using RunWithElevatedPrivileges to impersonate the Application Pool identity as in the following sample.
SPSecurity.RunWithElevatedPrivileges(delegate() {
using (SPSite site = new SPSite(url)) {
_context = new MyDataContext(ConfigSingleton.GetInstance().ConnectionString);
}
});
We have done this way because we expected that creating the ObjectContext after impersonation and, due to the fact that Repositories are receiving the impersonated ObjectContext would solve our requirement.
Unfortunately it's not so easy. In fact we experienced that, even if the ObjectContext is created before and under impersonation circumstances, the real connection is made just before executing the query, and so does not use impersonation, which break our requirement.
I have checked the ObjectContext class to see if there was any event through which we can inject the impersonation but unfortunately found nothing.
Any help?
We had a simillar problem when we used LinqToSharePoint. The DataContext is created from the HttpContext.Current and did not consider the RunWithElevatedPrivileges method. We did a nasty workaround that we backed up the original HttpContext, created a new dummy HttpContext in the RunWithElevatedPrivileges method and the problem went away. Obviously we set the context to the original afterwards.
Edit:
You can use the method below to create new dummy HttpContext.Call this method as first in your RunWithElevatedPrivileges. In the normal context just backup your currenct context with var backupContext = HttpContext.Current and after everything is done just set the context back.
private void SetNewContextWeb(SPWeb oWeb)
{
HttpRequest httpRequest = new HttpRequest(string.Empty, oWeb.Url, string.Empty);
HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new System.IO.StringWriter()));
SPControl.SetContextWeb(HttpContext.Current, oWeb);
}

SaveTempData called even though session is disabled

I've disabled sessionState in my mvc2 app via the web.config and also created my own controllerfactory and dummy tempdata provider, as described here:
How can I disable session state in ASP.NET MVC?
Only I've made it so that SaveTempData throws an exception:
public void SaveTempData(ControllerContext controllerContext,
IDictionary<string, object> values)
{
throw new NotImplementedException(
"Cannot set tempdata, no session state is available.");
}
I've made sure that no code is ever using either the Session or the TempData objects, but I still see this exception getting thrown after the "OnResultExecuted" event has been raised. I used to use this very same pattern on my mvc1 site and never saw the exception. Any ideas?
If I change my "SaveTempData" implementation to this:
public void SaveTempData(ControllerContext controllerContext,
IDictionary<string, object> values)
{
if (values.Count != 0)
{
throw new NotImplementedException(
"Cannot set tempdata, no session state is available.");
}
}
Everything works as expected - I'm just hoping to learn why SaveTempData is called at all when I'm not using it anywhere.
Update
Discovered this article: http://www.gregshackles.com/2010/07/asp-net-mvc-do-you-know-where-your-tempdata-is/
Which explains that ExecuteCore calls PossiblyLoadTempData and PossiblySaveTempData around an action - which is what was causing my issue. Is this a new addition in mvc2 vs. mvc1?
That's how it is implemented in the Controller.ExecuteCore method. The LoadTempData and SaveTempData methods will always be called before and after each action so make sure that they do not throw an exception. In order to disable the session effectively I would recommend you putting the following in your web.config:
<sessionState mode="Off" />
Discovered this article: http://www.gregshackles.com/2010/07/asp-net-mvc-do-you-know-where-your-tempdata-is/
Which explains that ExecuteCore calls PossiblyLoadTempData and PossiblySaveTempData around an action - which is what was causing my issue. Is this a new addition in mvc2 vs. mvc1?