System.ComponentModel.DataAnnotations MethodAccessException in Automated Controller Unit Test, MVC - asp.net-mvc-3

First of all I'd like to say that I wouldn't doubt if this is a configuration error, because it's only happening on our CI build server and not on anyone's local development machine. So if anyone has a seemingly obvious configuration suggestion please feel free to point it out, my team doesn't configure the build server so there could be something simply not set up correctly.
I'm running into an issue with one of my automated tests, I'm having this issue in any test that involves the (System.ComponentModel.)DataAnnotations on the Entity that is being used. It seems to only occur with any test that involves the Controller calling TryUpdateModel.
Before I provide the entire error message, here’s a list of some of the things we’ve already tried:
Adding the main MVC assemblies to the “fullTrustAssemblies” section of the app.config of the Test project
Adding the System.ComponentModel.DataAnnotations assembly to the “partialTrustVisibleAssemblies” section of the app.config of the Test project
Adding the System.ComponentModel.DataAnnotations assembly to the AppDomainSetup PartialTrustVisibleAssemblies in code
Trying to use ReflectionPermission.Demand to see if there was a problem with permissions
Ensuring that .NET Framework 4 and MVC3 were installed on the machine
Checking for the registry key(s) talked about in this article
Here's the full error:
Test method qTrade.UnitTests.Web.Controllers.Maintenance.TypeLookupControllerTest.CreatePostSaveInvalidEntityAndModelState threw exception:
System.MethodAccessException: Attempt by security transparent method 'System.Web.Mvc.TypeDescriptorHelper.Get(System.Type)' to access security critical method 'System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider..ctor(System.Type)' failed.
Assembly 'System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is a conditionally APTCA assembly which is not enabled in the current AppDomain. To enable this assembly to be used by partial trust or security transparent code, please add assembly name 'System.ComponentModel.DataAnnotations, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9' to the the PartialTrustVisibleAssemblies list when creating the AppDomain
Test method qTrade.UnitTests.Web.Controllers.Maintenance.TypeLookupControllerTest.CreatePostSaveInvalidEntityAndModelState threw exception:
System.MethodAccessException: Attempt by security transparent method 'System.Web.Mvc.TypeDescriptorHelper.Get(System.Type)' to access security critical method 'System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider..ctor(System.Type)' failed.
Assembly 'System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is a conditionally APTCA assembly which is not enabled in the current AppDomain. To enable this assembly to be used by partial trust or security transparent code, please add assembly name 'System.ComponentModel.DataAnnotations, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9' to the the PartialTrustVisibleAssemblies list when creating the AppDomain.<br> at System.Web.Mvc.TypeDescriptorHelper.Get(Type type)
at System.Web.Mvc.ModelBinders.GetBinderFromAttributes(Type type, Func`1 errorMessageAccessor)
at System.Web.Mvc.ModelBinderDictionary.GetBinder(Type modelType, IModelBinder fallbackBinder)
at System.Web.Mvc.ModelBinderDictionary.GetBinder(Type modelType, Boolean fallbackToDefault)
at System.Web.Mvc.Controller.TryUpdateModel[TModel](TModel model, String prefix, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider)
at qTrade.UI.Web.Controllers.Maintenance.TypeLookupController.Create(FormCollection collection) in d:\cibuild\qTrade\qTradeCI\Sources\source\UI\qTrade.UI.Web\Controllers\Maintenance\TypeLookupController.cs:line 55
at qTrade.UnitTests.Web.Controllers.Maintenance.TypeLookupControllerTest.CreatePostSaveInvalidEntityAndModelState() in d:\cibuild\qTrade\qTradeCI\Sources\source\Tests\qTrade.UnitTests\Web\Controllers\Maintenance\TypeLookupControllerTest.cs:line 178
at System.Web.Mvc.TypeDescriptorHelper.Get(Type type)
at System.Web.Mvc.ModelBinders.GetBinderFromAttributes(Type type, Func`1 errorMessageAccessor)
at System.Web.Mvc.ModelBinderDictionary.GetBinder(Type modelType, IModelBinder fallbackBinder)
at System.Web.Mvc.ModelBinderDictionary.GetBinder(Type modelType, Boolean fallbackToDefault)
at System.Web.Mvc.Controller.TryUpdateModel[TModel](TModel model, String prefix, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider)
at qTrade.UI.Web.Controllers.Maintenance.TypeLookupController.Create(FormCollection collection) in d:\cibuild\qTrade\qTradeCI\Sources\source\UI\qTrade.UI.Web\Controllers\Maintenance\TypeLookupController.cs:line 55
at qTrade.UnitTests.Web.Controllers.Maintenance.TypeLookupControllerTest.CreatePostSaveInvalidEntityAndModelState() in d:\cibuild\qTrade\qTradeCI\Sources\source\Tests\qTrade.UnitTests\Web\Controllers\Maintenance\TypeLookupControllerTest.cs:line 178
Any suggestions would be greatly appreciated, thanks!

I Fixed the problem !
This is a combination of running in Medium Trust, having MVC installed in the GAC and using "dynamic" (or a shape) as a ViewModel. Only (and only if) these 3 conditions are true you run into this error. The solution is to change your controller code: instead of returning "View(model)", return "View((object)model)".

Related

Debugging a Plugin throws "Could not load type 'Microsoft.Xrm.Sdk.IPluginExecutionContext4' from assembly 'Microsoft.Xrm.Sdk"

I just want to debug a plugin via the PluginRegistrationTool.
I have just updated the plugin with the latest version.
So the deployed plugin and the code are in sync. When I start debugging (Attach VS to PluginRegistrationTool and start execution) I get the following error:
Unhandled Exception: System.TypeLoadException: Could not load type 'Microsoft.Xrm.Sdk.IPluginExecutionContext4' from assembly 'Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
at PluginProfiler.Plugins.ServiceWrappers.ExecutionContextWrapper.Deserialize(OperationType operation, String serializedValue)
at PluginProfiler.Library.AppDomainProxy.Execute(ProfilerExecutionConfiguration configuration, ProfilerExecutionReport report)
at PluginProfiler.Library.AppDomainProxy.Execute(ProfilerExecutionConfiguration configuration, ProfilerExecutionReport report)
at PluginProfiler.Library.ProfilerExecutionEngine.Execute(ProfilerExecutionConfiguration configuration)
at PluginProfiler.Library.ProfilerExecutionUtility.Execute(PluginPermissions permissions, ProfilerExecutionConfiguration configuration)
at PluginProfiler.Library.ProfilerExecutionUtility.Execute(PluginPermissions permissions, OperationConfiguration operation, ProfilerReportingConfiguration reporting, CrmServiceClient administratorProxy, ITracingService tracing, ILogger pluginILoggerService)
at Microsoft.Crm.Tools.DebugPlugin.DebugPluginViewModel.btnExecutionClicked()
I'm confused but does anybody have an idea why it references IPluginExecutionContext4??!
Nowhere in the project IPluginExecutionContext4 is referenced and the project builds without problems.
Any help is highly appreciated!

Elmah logger not working in Web API with Simple Injector

In an ASP.NET Web API project, if you are using Simple Injector for dependency injection, it will register all controllers with this line of code:
container.RegisterWebApiControllers(
System.Web.Http.GlobalConfiguration.Configuration);
If you have Elmah logger in the same project, to access the logger you just use http://yourapp.com/elmah as shown here.
The problem is that Simple Injector thinks elmah is a controller and produces this error:
No registration for type ElmahController could be found.
I thought to configure Simple Injector to avoid construction if the type has elmah but I cannot figure out how.
What do I need to do to fix this?
Here is the full error:
No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: SimpleInjector.ActivationException: No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ActivationException: No registration for type ElmahController could be found. Make sure ElmahController is registered, for instance by calling 'Container.Register();' during the registration phase. An implicit registration could not be made because Container.Options.ResolveUnregisteredConcreteTypes is set to 'false', which is now the default setting in v5. This disallows the container to construct this unregistered concrete type. For more information on why resolving unregistered concrete types is now disallowed by default, and what possible fixes you can apply, see https://simpleinjector.org/ructd. ]
SimpleInjector.Container.ThrowNotConstructableException(Type concreteType) +138
SimpleInjector.Container.ThrowMissingInstanceProducerException(Type type) +88
SimpleInjector.Container.GetInstanceForRootType(Type serviceType) +186
SimpleInjector.Container.GetInstance(Type serviceType) +82
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +64
[InvalidOperationException: An error occurred when trying to create a controller of type 'Elmah.Mvc.ElmahController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +245
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +267
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +77
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +970
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +75
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +158
Ok I think I figured it out.
Some Notes
Since I have configured the container's lifestyle like this:
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
I cannot use LifeStyle.Scoped when registering the ElmahController. The 2 other options are LifeStyle.Singleton and LifeStyle.Transient. We don't want LifeStyle.Singleton because numerous instances are needed, thus we have one option left which is LifeStyle.Transcient.
Solution
You need to register it with Simple Injector:
container.Register<Elmah.Mvc.ElmahController>(Lifestyle.Transient);
The line above will result in a different error:
The configuration is invalid. The following diagnostic warnings were reported:
-[Disposable Transient Component] ElmahController is registered as transient, but implements IDisposable.
To get rid of that error, I first checked to see if the Dispose method for ElmahController has anything useful. It turns out it simply derives from System.Web.Mvc.Controller and here is the Dispose method:
public void Dispose()
{
Dispose(true /* disposing */);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
}
Since it does nothing useful, it is fine if it is not called. Thus the following code is enough:
container.GetRegistration(typeof(Elmah.Mvc.ElmahController)).Registration
.SuppressDiagnosticWarning(
DiagnosticType.DisposableTransientComponent,
"No need to call dispose because it does nothing useful.");
The RegisterWebApiControllers extension method uses ASP.NET Web API's IAssembliesResolver abstraction to get the list of assemblies to look for Controller instances.
Apparently the ElmahController lives in an assembly that is not returned by IAssembliesResolver.GetAssemblies(). To fix this you can do two things:
Call the RegisterWebApiControllers overload that accepts a list of Assembly instances and pass in the application assemblies that contain your controllers + the ELMAH assembly that contains your assembly
Customize Web API's controller discovery mechanism as described here
Especially the first solution is simpler compared to manually registering the controller, because under the covers RegisterWebApiControllers ensures the false-positive diagnostic warning for disposable components is suppressed.

Unable to serialize the session state, which is related to System.Data.Linq. EntitySet

Recently I am playing with the Windows Server 2008,
and would like to make some configuration for my web application.
I have changed the Session State for my application to "State Server" so it can make use of more work process (Now it is set to 4).
Afterwards I have got this error when I attempt to login to the application.
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
I suspect it is related to the EntitySet I have declared because I see this in the Stack Trace when the error occur:
[SerializationException: Type
'System.Data.Linq.EntityRef`1[[CtcSystem.Domain.Entities.Account.Account,
CtcSystem.Domain, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]]' in Assembly 'System.Data.Linq, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as
serializable.]
I have used [Serializable] tag on my classes,
so is there any way I have to do to make the EntitySet serializable so that the application can run under State Server?
Thanks
Best way is to implement the ISerializable interface on a partial class...

System.Collections.Generic.IEnumerable

when trying to query my database with entityframework i get the following error:
The navigation property of type 'System.Collections.Generic.IEnumerable1[[TASK.Warehouses.Domain.NoteProducts.NoteProduct, TASK.Warehouses.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' is not a single implementation of 'System.Collections.Generic.ICollection1[T]'.
what could be the problem and how could i fix it
You wrote Code-First classes that have IEnumerable<T> navigation properties.
Entity Framework requires that your navigation properties be of type ICollection<T>.
Sounds like you have many classes named "TASK.Warehouses.Domain.NoteProducts.NoteProduct, , TASK.Warehouses.Domain]. If this is the case, you are confusing CLR with violations of OO.

Why do I need nhibernate.dll referenced in my asp.net mvc project?

All my data logic is in another data layer project that I reference in my asp.net mvc project.
Now if I call:
CategoryDAO.GetById(1);
Everything works fine.
If I call:
CategoryDAO.GetBlah(1);
VS.NET complains saying
"Error 102: The type 'NHibernate.Criterion.Order' is defined in an assembly
that is not referenced. You must add a reference to assembly 'NHibernate,
Version=2.1.2.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4'."
If I add nhibernate.dll as a reference in my web project, it works.
Why is this? The logic/code is in my data layer, it is return the same as the call to GetById(1), why do I need to add the reference?
I'm guessing it's because of the lazy-loading that comes build into your objects. NHibernate creates proxy objects that inherit from your class (which is why you need to declare your methods as virtual). I'm guessing the reference is needed because of the proxy objects.

Resources