I recently tried to upgrade a .net 2.0 project which had its DAL generated by SubSonic 2.2 to .NET 4.0 under Visual Studio 2010.
The projects converted without error but now I am getting a rather vile error message when I try to launch it.
System.Security.VerificationException: Operation could destabilize the runtime.
at SubSonic.DataProvider.ApplyConfig(NameValueCollection config, Boolean& parameterValue, String configName) in C:\Documents and Settings\Desktop\4.0 Production\rel_1.0\server\Server.DAL\Server.DAL.SubSonic\DataProviders\DataProvider.cs:line 955
at SubSonic.DataProvider.Initialize(String name, NameValueCollection config) in C:\Documents and Settings\Desktop\4.0 Production\rel_1.0\server\Server.DAL\Server.DAL.SubSonic\DataProviders\DataProvider.cs:line 916
at System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType)
The code where it is throwing the exception:
ApplyConfig(config, ref extractClassNameFromSPName, ConfigurationPropertyName.EXTRACT_CLASS_NAME_FROM_SP_NAME);
private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref bool parameterValue, string configName)
{
if(config[configName] != null)
{
parameterValue = Convert.ToBoolean(config[configName]);
}
}
It performs similar calls to here, the only difference being it is strictly a string and not a boolean it is manipulating.
private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref string parameterValue, string configName)
{
if(config[configName] != null)
{
parameterValue = config[configName];
}
}
config is defined as a System.Collections.Specialized.NameValueCollection with 3 keys generateNullableProperties, connectionStringName, generatedNamespace extractClassNameFromSPName == false
EDIT1: The code that kicks off the error is in the Application_Start() method of the Global.asax
System.Data.SqlClient.SqlDependency.Start(SystemSetting.Schema.Provider.DefaultConnectionString);
EDIT2: The error bubbles out to thowing a targetinvocation error referening my web.config
<SubSonicService defaultProvider="appPlan">
<providers>
<clear/>
<add name="appPlan" type="SubSonic.SqlDataProvider, appPlan.Server.DAL.SubSonic" generateNullableProperties="false" connectionStringName="appPlan" generatedNamespace="appPlan.Server.DAL"/>
</providers>
</SubSonicService>
has anybody else ever run across such an issue? I could upgrade to SubSonic3.x but it would be a much greater undertaking I believe.
thanks.
I have seen this exception before when generating assemblies directly from hand-crafted IL. The .NET runtime verifies the raw instructions in an assembly for correctness, especially when loading the assembly into restricted contexts. For example, there is a check to ensure that the required number of arguments are loaded onto the call-stack before executing a method.
An assembly can still be loaded even if verification fails; but it can only be run in full trust. In partial trust scenarios you get this "operation could destabilize the runtime" error. The reason being that the runtime cannot guarantee safe operation of assemblies in partial trust if they do not "behave correctly".
You can manually check an assembly using the PEVERIFY
tool (available via a Visual Studio Command Prompt). Try verifying all of the referenced assemblies to see what is reported. I suspect there was a change in the verification rules between .NET 2.0 and .NET 4.0 that is now causing verification to fail for one of the SubSonic 2.2 assemblies.
Your cheat you mention in response to Fun Mun Pieng also suggests verification is the issue.
Does this fix the problem?
private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref bool parameterValue, string configName)
{
if(config[configName] != null)
{
string val = config[configName];
parameterValue = Convert.ToBoolean(val);
}
}
If not, then try
string val = config[configName];
if (val.ToLower() == "false")
parameterValue = false;
else
parameterValue = true;
There may be 2 reasons why the original code fails. First, earlier version of .NET (probably 1.1) had some type issue. I don't know what exactly, but I suspect it might have failed to identify the type of the value passed straight from the NameValueCollection
into ToBoolean
. The second possibility is that the value is not "true" or "false", but something else. Again, these 2 may or may not be the reason. I can't know for sure because I don't have SubSonic 2.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With