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?
Related
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
my environment:
- RequestFactory (GWT 2.5rc2, before 2.5rc1 and 2.4 - makes no difference regarding the question)
- Hibernate
- Spring's OpenSessionInView Filter (Session per Request)
I want to persist an EntityProxy with basically a Structure like follows:
EntityProxy_A
... other properties ...
--> Set<EntityProxy_B setEntProxB;
--> EntityProxy_C entProxC;
--> EntityProxy_D entProxC;
My request methods are implemended in a class separate from my domain class (locator concept). Therefore I don't use InstanceRequest persist().
Solution/Question 1 - should the following approach work:
I have request methods like
Request<EntityProxy_A> save(EntityProxy_A);
Request<EntityProxy_A> createNew();
I use createNew() to get an instance of EntityProxy_A (initialized with values regarding "... other properties ..." and already persisted in the db) to the client. Important to mention no Set of EntityProxy_B is created at that point.
In the OnSuccess of createNew() I do
public void onSuccess(EntityProxy_A response) {
MyRequest request = myRequestFactory.getMyRequest();
EntityProxy_A editableA = request.edit(response);
...
I then with "request" create my EntityProxy_B,C,D and assemble everything (like listed above).
Now i call
request.save(editableA)
.with("setEntProxB",
"setEntProxB.entProxC",
"setEntProxB.entProxD")
.fire(Receiver<EntityProxy_A>() {
#Override
public void onSuccess(EntityProxy_A response) {
.......
}
The parameter Entity_A arrives at my request method impl at the server with all its childs, is then persisted, everything shows up in the db fine.
If I call on the hibernate session a forced flush (remember I use OpenSessionInView, so normally everything is persisted after I leave the request method impl) I can even see all the ID's for the newly created/persisted instances of EntityProxy_B,C,D.
When I look at the JSON returned to the client I can even find data which is stored as attribute of entProxC, so I assume the object graph is built correctly and sent to the client.
BUT what happens now in my OnSuccess of the "save" call is like follows
public void onSuccess(EntityProxy_A response) {
MyRequest request = myRequestFactory.getMyRequest();
EntityProxy_A editableA = request.edit(response);
...
On calling "edit" I get an error
" ... error Unfrozen bean with null RequestContext ..."
which happens because EntityProxy_C and EntityProxy_D (not the EntityProxy_B in the Set!) return as "frozen = false" and of course at that point also there is no request context. When I look into the JSON I see like entProxC: {} (everything empty in there - no payload).
I found exactly that situation documented in Link, but I can't see a solution there in the code ... just the error mentioned.
Now my question - should I be able to use RequestFactory like that?
Solution/Question 2 - my solution for now and is it ok to use requestfactory like that:
I have now request methods like
Request<Void> save(EntityProxy_A);
Request<EntityProxy_A> createNew();
Calling createNew() like in the 1st approach. Now I also have a Instance Variable
EntityProxy_A myWorkA;
....
public void onSuccess(EntityProxy_A response) {
MyRequest request = myRequestFactory.getMyRequest();
myWorkA = request.edit(response);
...
then I do editing on my "myWorkA" and finally.
request.save(myWorkA)
.fire(Receiver<Void>() {
#Override
public void onSuccess(Void response) {
.....
}
Here I get no EntityProxy_A back from the server - anyways I thought why transport everything back to the client (except the newly created ID's from the persisted EntityProxy_B,C,D). So as found I now use EntityProxy.stableId() when I need to have a pointer to a specific EntityProxy on the Client side - which perhaps is anyways better.
In OnSuccess I do
public void onSuccess(Void response) {
MyRequest request = myRequestFactory.getMyRequest();
myWorkA = request.edit(myWorkA);
...
I have already my "myWorkA" so why not make it editable within a new RequestContext and continue editing and save and save and save ...
This works perfectly for me ... my question ... is that a good thing to do?
When I re-save my "myWorkA" which of course has still NULL Entity ID's in it, because I never loaded an up-to-date version from the server - I have no problems, the corresponding entites are updated on the server and not created over and over again (as could be guessed because of the NULL ID's).
If someone could please clear up, why Solution 1 doesn't work (or is not expected to work anyways) and if it's ok to work like shown in Solution 2.
My only other approach left then would be to have something like:
Request<Void> save(EntityProxy_A);
Request<EntityProxy_A> load(Long entProxId);
Request<EntityProxy_A> createNew();
But I don't like that ... traffic ...
Anyways for now - if that is correct usage of RequestFactory - by far I would prefer Solution 2.
Looking forward to your answers.
Greetings, Andreas.
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);
}
GWT 2.4 brings service inheritance on the client (issue 6234, issue 6035).
I've been waiting for this future for a long time, as it saves a lot of duplicated code on the client. I've started implementing it, but so for with mixed success.
This is my code:
public interface BaseEntityRequest<T>
{
Request<Void> put(T entity);
Request<List<T>> getAllOrderBy(String propertyName);
Request<List<T>> getRangeAndFilter(int limit,int offset, QueryInfoProxy queryInfo);
}
#Service(value = EgdDao.class, locator = DaoServiceLocator.class)
public interface EgdRequest extends RequestContext, BaseEntityRequest<EgdProxy>
{
Request<Void> exportToExcel(QueryInfoProxy queryInfo, String userName);
}
So far getAllOrderBy and getRangeAndFilter work fine, but put(T entity) does not.
I get the following error in the console:
[ERROR] Unexpected error
java.util.NoSuchElementException
and this gets returned in the receiver onFailure ServerFailure message:
Error 500 INTERNAL_SERVER_ERROR
HTTP ERROR 500
Problem accessing /gwtRequest. Reason:
INTERNAL_SERVER_ERROR
The only cause, that I can see, for the put method not to work, when the others do, is that it uses the generic parameter T. When I move the put method in the EgdRequest interface (using EgdProxy as a parameter instead of T) it starts to work, so I know my server code is fine.
Does anybody have any idea how to implement this correctly?
Thanks!
It's a GWT bug. See http://code.google.com/p/google-web-toolkit/issues/detail?id=6794
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?