MVC Can't Access WCF Data Services - asp.net-mvc

I've added a WCF Data Service (v5.6) called test.svc to the root of my MVC app but I can't seem to get my routing figured out so that I can access it. Below are the results I get back in the browser when I go to http:/test.svc along with my route code and test.svc file.
route table entry (first route rule I add):
routes.IgnoreRoute("{resource}.svc/{*pathInfo}");
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class test : DataService<MyEntities>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.UseVerboseErrors = true;
}
Error shown in browser:
The server encountered an error processing the request. The exception
message is 'Expression of type
'System.Data.Entity.Core.Objects.ObjectContext' cannot be used for
return type 'System.Data.Objects.ObjectContext''. See server logs for
more details. The exception stack trace is:
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type
delegateType, Expression& body, ReadOnlyCollection1 parameters) at
System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body,
String name, Boolean tailCall, IEnumerable1 parameters) at
System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body,
Boolean tailCall, IEnumerable1 parameters) at
System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body,
ParameterExpression[] parameters) at
System.Data.Services.Providers.DbContextHelper.CreateDbContextAccessor(Type
type) at
System.Data.Services.Providers.DbContextHelper.GetDbContextAccessor(Type
type) at
System.Data.Services.Providers.DbContextHelper.IsDbContextType(Type
type) at
System.Data.Services.DataService1.CreateMetadataAndQueryProviders(IDataServiceMetadataProvider&
metadataProviderInstance, IDataServiceQueryProvider&
queryProviderInstance, Object& dataSourceInstance, Boolean&
isInternallyCreatedProvider) at
System.Data.Services.DataService1.CreateProvider() at
System.Data.Services.DataService1.EnsureProviderAndConfigForRequest()
at System.Data.Services.DataService1.HandleRequest() at
System.Data.Services.DataService1.ProcessRequestForMessage(Stream
messageBody) at SyncInvokeProcessRequestForMessage(Object , Object[] ,
Object[] ) at
System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object
instance, Object[] inputs, Object[]& outputs) at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&
rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&
rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean
isOperationContextSet)

Looks like WCF DS and EF 6 are incompatible and there's no timeframe for when, or if, they might fix things.
http://social.msdn.microsoft.com/Forums/en-US/4aa92957-22de-4445-aecd-2871982afe28/eta-on-entity-framework-version-6-provider?prof=required

Related

Breeze expand error

Not sure if this is possible using Breeze, but we have a situation where we need to return an IQueryable from 2 different sources.
Our business logic called from our controller action checks to see if some data is stored within a database, if so an IQueryable is returned from the repository which uses the EFContextProvider.
Otherwise, a List<T> is created containing default data and turned into an IQueryable, which is then returned.
On the client side, our query contains .expand to ensure the navigation properties are populated with the required data.
This works fine when the IQueryable is coming from the EF, but crashes with the following error when creating the List<T>:
{"$id":"1","$type":"System.Web.Http.HttpError, System.Web.Http","Message":"An error has occurred.","ExceptionMessage":"'System.Linq.EnumerableQuery<MyObject>' does not contain a definition for 'Include'","ExceptionType":"Microsoft.CSharp.RuntimeBinder.RuntimeBinderException","StackTrace":" at CallSite.Target(Closure , CallSite , Object , String )\r\n at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)\r\n at Breeze.WebApi.QueryHelper.<>c__DisplayClass14.<ApplyExpand>b__11(String expand)\r\n at System.Collections.Generic.List`1.ForEach(Action`1 action)\r\n at Breeze.WebApi.QueryHelper.ApplyExpand(IQueryable queryable, String expandsQueryString)\r\n at Breeze.WebApi.QueryHelper.ApplySelectAndExpand(IQueryable queryable, NameValueCollection map)\r\n at Breeze.WebApi.BreezeQueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\r\n at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t)\r\n at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)"}
Is this an issue with Breeze (we're using 1.4.2 at present), or is it something I'm doing wrong?
I think your best bet in this case in this case is remove the 'expand' from the client and move it the server (as an Include). Something like this:
[HttpGet]
public IQueryable<Customer> Customers(someCriteria) {
if (... haveData ...) {
return ContextProvider.Context.Customers.Include("Orders");
} else {
return DefaultCustomerList.AsQueryable()
}
}

Error when serializing byte[]

In our backing database, we have a Data field that is of type varbinary(max). Using Breeze we are able to save data in this field, however, when we want to call it back down we are getting errors. In our generated models, the field gets mapped to a byte[]. But when Breeze tries to serialize that into a string it throws up errors.
$id: "1",
$type: "System.Web.Http.HttpError, System.Web.Http",
Message: "An error has occurred.",
ExceptionMessage: "The specified cast from a materialized 'System.String' type to the 'System.Byte[]' type is not valid.",
ExceptionType: "System.InvalidOperationException",
StackTrace: " at System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal) at System.Data.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling[TColumn](Int32 ordinal) at lambda_method(Closure , Shaper ) at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper) at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Breeze.WebApi.ODataActionFilter.OnActionExecuted(HttpActionExecutedContext actionExecutedContext) at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception) at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response) at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t) at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)"
Any help would be great!
I have been unable to reproduce this.
Breeze is able to take a server side byte[] and convert it to a string on the client. You can see an example of this in the breeze 'DocCode' samples whenever an Employee entity is returned. The Employee type has a Photo property that has a server side datatype of 'byte[]' which is returned to the breeze client as a 'string'.
What I think you are running into is a server side materialization issue where you are trying to materialize a binary blob on the database into a string property. This would occur if your model property was typed as a 'String' instead of as a 'byte[]'.
Hope this helps.

Request timed out while using Post method HttClient in C#

In my application, I am using a code piece to send a content to a web proxy with a URL with an interval of 2 seconds between each post. The message to post in the below code is given as static string, but will be dynamic in the original application code.
for (ic = 0; ic < 30; ic++)
{
using(HttpClient httpClient = new HttpClient())
{
Encoder encoder = new Encoder(); //This is a class which we created
AuthorizationHeaders authorizationHeaders = encoder.getAuthorization(PARTNER_ID, PARTNER_KEY, URL, "POST", "application/xml");
httpClient.DefaultHeaders.Add("Accept", "*/*");
httpClient.DefaultHeaders.Add("Authorization", authorizationHeaders.getAuthorizationHeader());
httpClient.DefaultHeaders.Add("Expires", authorizationHeaders.getExpiresHeader());
httpClient.DefaultHeaders.Add("origPartnerId", "MyWebSite");
httpClient.DefaultHeaders.Add("appId", "440");
httpClient.DefaultHeaders.Add("Content-Type", "application/xml");
string inputUrl = ConfigurationManager.AppSettings["url"];
String detailRequest = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Message><Details><Name>Bob</Name><Age>45</Age></Details></Message>";
var content = HttpContent.Create(detailRequest, Encoding.UTF8, "application/xml");
response = httpClient.Post(inputUrl, content).EnsureStatusIsSuccessful();
Thread.Sleep(2000);
}
}
But I am getting the below exception when contacting the proxy. I am not getting it all the time, the message does go through some time, but eventually, this exception comes.
GetResponse timed out ---> System.TimeoutException: GetResponse timed out ---> System.Net.WebException ---> System.Net.WebException: The operation has timed out
at System.Net.HttpWebRequest.GetResponse()
at Microsoft.Http.HttpWebRequestTransportStage.HttpTransportAsyncResult.PopulateWebResponseSync(WebRequest request, IAsyncResult result)
at Microsoft.Http.HttpWebRequestTransportStage.HttpTransportAsyncResult.PopulateWebResponse(HttpTransportAsyncResult self, IAsyncResult result, Func`3 getResponse)
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at Microsoft.Http.AsyncResult.End[TAsyncResult](IAsyncResult result, Boolean throwException)
at Microsoft.Http.HttpWebRequestTransportStage.EndProcessRequestAndTryGetResponse(IAsyncResult result, HttpResponseMessage& response, Object& state)
at Microsoft.Http.HttpWebRequestTransportStage.ProcessRequestAndTryGetResponse(HttpRequestMessage request, HttpResponseMessage& response, Object& state)
at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self)
--- End of inner exception stack trace ---
at Microsoft.Http.HttpStageProcessingAsyncResult.Complete(HttpStage stage, Exception e)
at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self)
at Microsoft.Http.HttpClient.Send(HttpRequestMessage request)
at Microsoft.Http.HttpClient.Send(HttpMethod method, Uri uri, RequestHeaders headers, HttpContent content)
at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, Uri uri, HttpContent body)
at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, String uri, HttpContent body)
But this proxy is just a redirection to another one. So I tried directly to that one also. There, I was able to do this 2 or 3 times successfully but it generated another exception after that. I tried again, but this time, the exception came for the first try itself. I waited for some time and then tried again, and surprisingly, it did go through 2 or 3 times and then again the exception came. The exception that I am getting this time is different and it is this...
Microsoft.Http.HttpStageProcessingException ---> System.Net.WebException ---> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly. at System.Net.HttpWebRequest.GetResponse() at Microsoft.Http.HttpWebRequestTransportStage.HttpTransportAsyncResult.PopulateWebResponseSync(WebRequest request, IAsyncResult result) at Microsoft.Http.HttpWebRequestTransportStage.HttpTransportAsyncResult.PopulateWebResponse(HttpTransportAsyncResult self, IAsyncResult result, Func3 getResponse) --- End of inner exception stack trace --- at Microsoft.Http.AsyncResult.End[TAsyncResult](IAsyncResult result, Boolean throwException) at Microsoft.Http.AsyncResult.End[TAsyncResult](IAsyncResult result) at Microsoft.Http.AsyncResult1.End(IAsyncResult result) at Microsoft.Http.HttpWebRequestTransportStage.EndProcessRequestAndTryGetResponse(IAsyncResult result, HttpResponseMessage& response, Object& state) at Microsoft.Http.HttpWebRequestTransportStage.ProcessRequestAndTryGetResponse(HttpRequestMessage request, HttpResponseMessage& response, Object& state) at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self) --- End of inner exception stack trace --- at Microsoft.Http.HttpStageProcessingAsyncResult.Complete(HttpStage stage, Exception e) at Microsoft.Http.HttpStageProcessingAsyncResult.NextRequest(HttpStageProcessingAsyncResult self) at Microsoft.Http.HttpStageProcessingAsyncResult..ctor(HttpStageProcessingAsyncState state, AsyncCallback callback, Object user) at Microsoft.Http.HttpClient.Send(HttpRequestMessage request) at Microsoft.Http.HttpClient.Send(HttpMethod method, Uri uri, RequestHeaders headers, HttpContent content) at Microsoft.Http.HttpClient.Send(HttpMethod method, Uri uri, HttpContent content) at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, Uri uri, HttpContent body) at Microsoft.Http.HttpMethodExtensions.Method(HttpClient client, HttpMethod method, String uri, HttpContent body) at Microsoft.Http.HttpMethodExtensions.Post(HttpClient client, String uri, HttpContent body)
Any help in this regard would be greatly appreciated because I am after this for the past few days and I have read some articles and even questions in stackoverflow also, but nothing helped me. Thanks in advance...
The proxy rules of some companies will cause problems with POST requests.
GET requests work fine. Check that your OS proxy setting is disabled.
Windows 7: Control Panel > Internet Options > Connections (Tab).
Then click on the "LAN settings" button and then uncheck "Use a proxy server for your LAN".
Alternatively, try and get your Network Admins to add the connection that you are using to the exclusion list.

Unable to Create DbContext per Request with Simple Injector

Simple Inject is throwing the following exception when attempting to register my DbContext.
The supplied connection string is not valid, because it contains insufficient mapping or metadata information.
Parameter name: connectionString
I'm new to DI and could be missing something fairly obvious. The connection string looks fine. It is the same one that gets used to create the DbContext normally. I was attempting the solution here
public static class SimpleInjectorInitializer
{
/// <summary>Initialize the container and register
// it as MVC3 Dependency Resolver.</summary>
public static void Initialize()
{
var container = new Container();
InitializeContainer(container);
container.RegisterMvcControllers(
Assembly.GetExecutingAssembly());
container.RegisterMvcAttributeFilterProvider();
container.Verify();
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(
Container container)
{
}
}
Update: I still haven't solved my issue, but it is very similar to this issue with Ninject
Stack Trace:
System.InvalidOperationException was unhandled by user code
Message=The configuration is invalid. Creating the instance for type _AccountController failed. Error occurred while trying to get an instance of type _AccountController. The type initializer for 'Web.Controllers._AccountController' threw an exception.
Source=SimpleInjector
StackTrace:
at SimpleInjector.Helpers.Verify(IInstanceProducer instanceProducer, Type serviceType)
at SimpleInjector.Container.ValidateRegistrations()
at SimpleInjector.Container.Verify()
at Web.App_Start.SimpleInjectorInitializer.Initialize() in C:\workspace\BrowsarServer\QARSite\Web\App_Start\SimpleInjectorInitializer.cs:line 24
InnerException: SimpleInjector.ActivationException
Message=Error occurred while trying to get an instance of type _AccountController. The type initializer for 'Web.Controllers._AccountController' threw an exception.
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducers.InstanceProducer.ThrowErrorWhileTryingToGetInstanceOfType(Exception innerException)
at SimpleInjector.InstanceProducers.InstanceProducer.GetInstance()
at SimpleInjector.Helpers.Verify(IInstanceProducer instanceProducer, Type serviceType)
InnerException: System.TypeInitializationException
Message=The type initializer for 'Web.Controllers._AccountController' threw an exception.
Source=Web
TypeName=Web.Controllers._AccountController
StackTrace:
at Web.Controllers._AccountController..ctor()
at lambda_method(Closure )
at SimpleInjector.InstanceProducers.InstanceProducer.GetInstance()
InnerException: System.ArgumentException
Message=The supplied connection string is not valid, because it contains insufficient mapping or metadata information.
Parameter name: connectionString
Source=System.Data.Entity
ParamName=connectionString
StackTrace:
at System.Data.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor)
at System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName)
at Web.Models.BrowsarEntities..ctor() in C:\workspace\BrowsarServer\QARSite\Web\Models\Browsar.Designer.cs:line 90
at Web.Controllers._AccountController..cctor() in C:\workspace\BrowsarServer\QARSite\Web\Controllers\_AccountController.cs:line 15
InnerException: System.InvalidOperationException
Message=Unable to determine application context. The ASP.NET application path could not be resolved.
Source=System.Data.Entity
StackTrace:
at System.Data.Metadata.Edm.AspProxy.GetBuildManagerReferencedAssemblies()
at System.Data.Metadata.Edm.DefaultAssemblyResolver.GetAllDiscoverableAssemblies()
at System.Data.Metadata.Edm.DefaultAssemblyResolver.GetWildcardAssemblies()
at System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(String assemblyName, String resourceName, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Metadata.Edm.MetadataArtifactLoader.Create(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Metadata.Edm.MetadataCache.SplitPaths(String paths)
at System.Data.Common.Utils.Memoizer`2.<>c__DisplayClass2.<Evaluate>b__0()
at System.Data.Common.Utils.Memoizer`2.Result.GetValue()
at System.Data.Common.Utils.Memoizer`2.Evaluate(TArg arg)
at System.Data.EntityClient.EntityConnection.GetMetadataWorkspace(Boolean initializeAllCollections)
at System.Data.Objects.ObjectContext.RetrieveMetadataWorkspaceFromConnection()
at System.Data.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor)
InnerException: System.Reflection.TargetInvocationException
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Data.Metadata.Edm.AspProxy.GetBuildManagerReferencedAssemblies()
InnerException: System.InvalidOperationException
Message=This method cannot be called during the application's pre-start initialization stage.
Source=System.Web
StackTrace:
at System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()
at System.Web.Compilation.BuildManager.GetReferencedAssemblies()
InnerException:
The root cause is burried deep down in the inner exceptions. When inspecting the stack trace, you will be able to find the cause of this. The reason is in the following two inner exceptions:
InvalidOperationException: Unable to determine application context.
The ASP.NET application path could not be resolved.
and:
InvalidOperationException: This method cannot be called during the
application's pre-start initialization stage.
In other words, this exception is caused by a timing problem. I'm not sure if you can change your connection string to solve this, but you can also move your initalization to a later moment in starting the application. You can do this as follows:
Remove the [assembly: WebActivator.PreApplicationStartMethod] (top line) of the SimpleInjectorInitializer.cs class.
Add a call to the SimpleInjectorInitializer.Initialize() method in the Application_Start() event of the global asax.
After doing this, initializing (and especially, verifying) of the object graph is done after the pre-init state, which seems to be too early for EF in an ASP.NET environment.
Another option is to remove the container.Verify(); call from the SimpleInjectorInitializer.Initialize method, since it is the early verification process that is killing you. However, please read this Verify the container’s configuration first, to see alternatives, before doing so.
Although you use a class DbContext it looks like it is derived from ObjectContext. In that case you should use an EntityConnectionStringBuilder to build the connection string.
You may be missing some of the metadata information in your connection string. For example entity framework has some special metadata in the connection string, see sample below:
<add name="MyEntities" connectionString="metadata=res://*/MyEntitiesStore.csdl|res://*/MyEntitiesStore.ssdl|res://*/MyEntitiesStore.msl;provider=System.Data.SqlClient;provider connection string="Data Source=<your server>;Initial Catalog=<your DB>;Integrated Security=False;User ID=<user>;Password=<pass>;MultipleActiveResultSets=True""
providerName="System.Data.EntityClient" />

Don't flush the session after an exception occurs - NHibernate

I am developing a ASP.NET MVC web app under .NET 3.5, NHibernate and hosted on Windows Azure. When, the webapp is run from the local development fabric it works fine. Yet, when I move it to Windows Azure, every insert performed from the MVC web role ends up with the exception listed below.
Any idea what's wrong with my NHibernate logic? (might be the session management, not sure)
[AssertionFailure: null id in Lokad.Translate.Entities.User entry (don't flush the Session after an exception occurs)]
NHibernate.Event.Default.DefaultFlushEntityEventListener.CheckId(Object obj, IEntityPersister persister, Object id, EntityMode entityMode) +292
NHibernate.Event.Default.DefaultFlushEntityEventListener.GetValues(Object entity, EntityEntry entry, EntityMode entityMode, Boolean mightBeDirty, ISessionImplementor session) +93
NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event) +158
NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event) +469
NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +339
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) +85
NHibernate.Impl.SessionImpl.Flush() +275
NHibernate.Transaction.AdoTransaction.Commit() +236
Lokad.Translate.Repositories.PageRepository.Create(Page page)
Lokad.Translate.Controllers.PagesController.Create(Page page)
lambda_method(ExecutionScope , ControllerBase , Object[] ) +69
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +251
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +31
System.Web.Mvc.<>c__DisplayClassa.b__7() +88
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +534
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +856
System.Web.Mvc.Controller.ExecuteCore() +185
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +221
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +586
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +177
Note that I am using _session.FlushMode = FlushMode.Commit; and that the User is used in a custom RoleProvider
public class SimpleRoleProvider : RoleProvider
{
readonly UserRepository Users = new UserRepository();
public override string[] GetRolesForUser(string username)
{
try
{
var user = Users.Get(username);
// no role if user is not registered
if (null == user) return new string[0];
// default role for registered user
return user.IsManager ? new[] { "Manager", "User" } : new[] { "User" };
}
catch (Exception)
{
// role should not fail in case of DB issue.
return new string[0];
}
}
}
You should never catch exceptions and ignore them during a NHibernate transaction.
I try to explain why.
There could be exceptions for instance caused by constraints in the database. (it could also be caused by mapping problems, exceptions thrown by properties or anything else.) NHibernate tries to synchronize the state in memory with the database. This is done on commit - and sometimes before queries to make sure that queries are done on actual data. When this synchronization fails, the state in the database is something random, some changes are persisted, others are not. The only thing you can do in such a case is closing the session.
Consider that decisions and calculations in your code are based on values in memory. But - in case of an ignored exception, this values are not the values in the database, they will never be there. So your logic will decide and calculate on 'fantasy-data'.
By the way, it is never a good idea to catch any exception (untyped) and ignore them. You should always know the exceptions you handle, and be sure that you can continue.
What you're doing here is swallowing programming errors. Believe me, the system will not be more stable. The question is only: do you notice the error when it occurs, or do you ignore it there and even persist the result of the error to the database? When you do the latter, you don't have to be surprised when your database is inconsistent and other error arise when you try to get the data from the database. And you will never ever find the code that is the actual cause of the error.
I have finally found a solution to my own problem. In case people would be interested, I am posting the solution here.
public class SimpleRoleProvider : RoleProvider
{
// isolated session management for the RoleProvider to avoid
// issues with automated management of session lifecycle.
public override string[] GetRolesForUser(string username)
{
using (var session = GlobalSetup.SessionFactory.OpenSession())
{
var users = new UserRepository(session);
var user = users.Get(username);
// no role if user is not registered
if (null == user) return new string[0];
// default role for registered user
return user.IsManager ? new[] {"Manager", "User"} : new[] {"User"};
}
}
}
Basically what was happening is that the RoleProvider repository does not seem to have the same lifecycle than regular in-view / in-controller repositories. As a result, at the time the RoleProvider is called, the NHibernate session has already been disposed causing the exception observed here above.
I have replaced the code by the following one here above. This one has its own NHibernate session management, and ends up working fine.
This exception can occur if your column names include reserved words (e.g. use status as a column name and it will become impossible to Save)

Resources