NullReferenceException on XML Deserialization in dynamically loaded assembly - c#

I'm writing a plugin for a CMS that loads plugin assemblies dynamically using Assembly.load.
Note: For reasons that are irrelevant to go into, the frontend loads the assembly statically, whilst the admin environment loads it dynamically.
My plugin has its own xml configuration file that loads the first time the plugin class is used. The config file is deserialized into an object object using XmlSerializer.
This deserialization works fine when I load the assembly statically through the frontend, however when the admin tries to load it dynamically I get a NullReferenceException from the reader.
I have tried pre-generating the serialization assembly using Sgen and adding it to the "Bin" directory of the admin environment, but this seems to have no effect.
Stack trace:
[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAccessibilityConfig..cctor() +1156
[TypeInitializationException: The type initializer for 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAccessibilityConfig' threw an exception.]
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAccessibilityConfig..ctor() +0
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract.get_Reader() +44
System.Xml.Serialization.TempAssembly.InvokeReader(XmlMapping mapping, XmlReader xmlReader, XmlDeserializationEvents events, String encodingStyle) +69
System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) +101
[InvalidOperationException: There is an error in XML document (0, 0).]
System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) +613
System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) +30
CoA.WebUI.Controls.AccessibilityObjects.AccessibilityConfigBase`1.Deserialize(String xml) +196
CoA.WebUI.Controls.AccessibilityObjects.AccessibilityConfigBase`1.LoadFromFile(String fileName) +256
CoA.WebUI.Controls.Accessibility.Configure(Boolean isAdmin) +725
CoA.WebUI.Controls.Accessibility.GetProperties() +118
CMS.Admin.WebUI.CustomControlCreator.GetCustomControlProperties() +194
CMS.Admin.WebUI.CustomControlCreator.BindPropertyControls() +146
CMS.Admin.WebUI.CustomControlCreator.PageLoad() +164
CMS.Admin.WebUI.CustomControlCreator.Page_Load(Object sender, EventArgs e) +47
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
Oddly, the stack trace seems to indicate that the XML document is empty, but I'm passing in a StringReader which I have debugged and confirmed is populated with the correct document - it isn't empty.

I figured it out!!!
If anyone else comes across this problem, here is a way of solving it.
Take your serializable object and put it in its own assembly (i.e. its own project in VS). Now you have two dlls. One with your assembly to be dynamically loaded and the other containing your serializable object.
Take the one with your serializeable object and put it in the bin directory of any application that dynamically loads your plugin assembly.
Now when your dynamically loaded assembly tries to create an object, the assembly for creating that object is already available in memory - having been loaded statically.
I don't know why XmlSerializer doesn't like to work when working with a dynamically loaded assembly, but this workaround seems to work well.
Hope this helps someone some day.

Related

Same function with same arguments, from same dll reference (same path, same file), working for one .NET project, but not for an other

The .NET project that works is on .NET framework 4.6.1. The one that does not work is on .NET framework 4.7.2.
This is the Function:
return DAL.DALGeneral.SelectScalar("GetYearName", new Dictionary<string, object>() { { "Year", year } }).ToString();
This is the Error message:
[NullReferenceException: Object reference not set to an instance of an object.]
DAL.DALGeneral.GetConnectionString(String DataBase) +83
DAL.DALGeneral.SelectScalar(String spName, Dictionary`2 parameters, String DataBase, String ConnectionString) +123
OnlineYudGimelDaledSignIn.Models.LookUp.GetYearName(Int32 year) in C:\Users\giln\source\repos\OnlineYudGimelDaledSignIn\OnlineYudGimelDaledSignIn\Models\LookUp.cs:58
OnlineYudGimelDaledSignIn.Site.Page_Load(Object sender, EventArgs e) in C:\Users\giln\source\repos\OnlineYudGimelDaledSignIn\OnlineYudGimelDaledSignIn\Site.Master.cs:29
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +52
System.Web.UI.Control.OnLoad(EventArgs e) +97
System.Web.UI.Control.LoadRecursive() +61
System.Web.UI.Control.LoadRecursive() +134
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +693
Im stumped as to why, the same function with the same arguments works from an other project.
I tried sending different arguments to the function and i get different error, but i need it to be these arguments.
Ok, so i had a missing connection string in the web.config file in the second project. I didn't realize dll reference uses the current project config file, and not his own somehow.

Serialization in Sitecore

I have a custom module in Sitecore which works fine if app pool session state is set to In process. When I change it to SQL Server I get error message saying that it is Unable to serialize the session state. All my classes I am using are serializable. My code is triggered by custom ribbon button and this error is thrown when I click on it. It is supposed to display dialog form but it shows error message instead. I thought it has sth to do with Sitecore DialogForm class which my class inherits, but it turned out that this is not the case.
When I debug the code error is thrown once Run(TranslateArgs args) method has finished executing - it is called from public override void Execute(CommandContext context) and is supposed to display dialog by calling SheerResponse.ShowModalDialog(str4.ToString(), true);
I also thought that it was because I used ClientPipelineArgs in Run method, but after creating custom class (and making it serializable) that inherits ClientPipelineArgs error didn't go away.
Any ideas what might be causing it?
Stack Trace:
[SerializationException: Type 'Sitecore.Data.Database' in Assembly 'Sitecore.Kernel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +14210117
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +408
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +420
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +532
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +969
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +633
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +322
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1487
[HttpException (0x80004005): 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.]
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +2252727
System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +49
System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +729
System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +336
System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +99
System.Web.SessionState.SqlSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +3538900
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +1021
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165
Well the stack trace tells us, that some code is trying to put a Sitecore.Data.Database onto SessionState, and that won't work. It has no public constructor, but that is the very least of the problems. It can happen if trying to put an instantiated Item onto SessionState as well.
The stack trace appears to be incomplete. It should show you, which line of code in your Run method, is the root source of the exception.
What isn't clear to me; which exact version of Sitecore are you on?
Currently out-of-process session state mode is experimental feature in Sitecore. InProc is the best option for the Client. Find more details here.
If you still think that out-of-process is the right way to go, make sure you set it in accordance with this article.
[Update] Out-of-process session states are not supported on Content Management instance anymore. Link.

Debugging compiled function in ASP .NET

I have a website I believe to be in ASP .NET, which is throwing an exception System.NullReferenceException: Object reference not set to an instance of an object.. Stack trace shows as follows:
[NullReferenceException: Object reference not set to an instance of an object.]
SomeScript.getConnection() +32
SomeScript.buildGridData() +299
SomeScript.Page_Load(Object sender, EventArgs e) +92
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +43
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74
System.Web.UI.Control.LoadRecursive() +163
System.Web.UI.Control.LoadRecursive() +163
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2603
Same error is occurring for basically all pages of the site which request data, with just the SomeScript in above stack trace alternating for the loading script.
Environmental changes have only been in changing password for a remote SMTP server the site uses for mailing out, but site was continuing to load fine after that change was made.
My feeling is that these errors with the getConnection() method started occurring after a user tried to use said SMTP mailing function within the website and received an error (I was not able to capture the error user received).
I'm a bit lost with debugging any further from here as the getConnection() method seems to be within compiled DLLs and not accessible by me.
What is the next step in trying to remove the error?
Firstly, it's unlikely that an SMTP password change has caused the issue from your description of it. But if that password change was made in the Web.config file, I'd say it's possible it was made less carefully than it should have been, and in fact a database connection-related section in there has been inadvertently modified and is no longer valid.
If you want to be able to debug into the DLL, you can disable the option to debug "Just My Code" in Visual Studio (something like Tools/Options/Debugging) - you should then be able to step down into these DLLs and see where the issue lies. Hopefully it won't require any code changes, and you can just fix up the configuration file.

.NET Unhandled Exception from MasterPage

I'm copying and pasting my application from one server (works fine) to another server (it doesn't work fine).
I get this on the new server, even though the code hasn't changed:
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:
[NullReferenceException: Object reference not set to an instance of an object.]
MasterPagePS_Index.Page_Load(Object sender, EventArgs e) +117
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Control.LoadRecursive() +141
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
Are you accessing a database, file, or any external resources? Sounds like you have a configuration difference, check your web.config.
You don't use relative path in oder to access your ressource (File, page, style, assembly , etc...)
so ASP.Net don't find your file, throw null exception.
The error you provided doesn't give much information. I suggest that you perform a remote debugging and check which line is causing the error.
Or you can add the Global.asax file and catch the error in Application_Error and email the error to yourself.
Dim ex As Exception = Server.GetLastError()
Dim hue As System.Web.HttpUnhandledException = New System.Web.HttpUnhandledException(ex.Message, ex)
Dim html As String = hue.GetHtmlErrorMessage()
' TODO: Send the html string. This will send you the formatted html of the exception including the source of the error and stacktrace.

ASP + EF loading assembly problem

I have a big problem. When I'm running asp SOMETIMES the application is craching with the following error message:
Schema specified is not valid. Errors:
The types in the assembly 'Data.EF,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' cannot be loaded
because the assembly contains the
EdmSchemaAttribute, and the closure of
types is being loaded by name.
Loading by both name and attribute is
not allowed.
Stack Trace:
[MetadataException: Schema specified
is not valid. Errors: The types in
the assembly 'Data.EF,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' cannot be loaded
because the assembly contains the
EdmSchemaAttribute, and the closure of
types is being loaded by name.
Loading by both name and attribute is
not allowed.]
System.Data.Metadata.Edm.ObjectItemCollection.LoadAssemblyFromCache(ObjectItemCollection
objectItemCollection, Assembly
assembly, Boolean
loadReferencedAssemblies,
EdmItemCollection edmItemCollection,
Action1 logLoadMessage) +480
System.Data.Metadata.Edm.ObjectItemCollection.ExplicitLoadFromAssembly(Assembly
assembly, EdmItemCollection
edmItemCollection, Action1
logLoadMessage) +53
System.Data.Metadata.Edm.MetadataWorkspace.ExplicitLoadFromAssembly(Assembly
assembly, ObjectItemCollection
collection, Action1 logLoadMessage)
+93 System.Data.Metadata.Edm.MetadataWorkspace.LoadFromAssembly(Assembly
assembly, Action1 logLoadMessage)
+130 System.Web.UI.WebControls.EntityDataSourceView.ConstructContext()
+585 System.Web.UI.WebControls.EntityDataSourceView.ExecuteSelect(DataSourceSelectArguments
arguments) +76
System.Web.UI.DataSourceView.Select(DataSourceSelectArguments
arguments,
DataSourceViewSelectCallback callback)
+21 System.Web.UI.WebControls.DataBoundControl.PerformSelect()
+143 Telerik.Web.UI.GridTableView.PerformSelect()
+38 System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
+74 Telerik.Web.UI.GridTableView.DataBind()
+363 Telerik.Web.UI.RadGrid.DataBind() +173
System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
+66 System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
+75 System.Web.UI.Control.EnsureChildControls()
+102 Telerik.Web.UI.GridBaseDataList.get_Controls()
+33 Telerik.Web.UI.RadAjaxControl.PopulatePlainPanels(Control
parent, List`1 list, Control root)
+119 Telerik.Web.UI.RadAjaxControl.OnPagePreRender(Object
sender, EventArgs e) +1802
System.EventHandler.Invoke(Object
sender, EventArgs e) +0
System.Web.UI.Control.OnPreRender(EventArgs
e) +8864486
System.Web.UI.Control.PreRenderRecursiveInternal()
+103 System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint) +2496
I also added LoadFromAssembly before every context call and still the same problem.
context.MetadataWorkspace.LoadFromAssembly(context.GetType().Assembly);
Enviroment: VS 2010, .NET 4.0, C#, EF
Could please somebody help me, to fix this issue?
Thanks in advance,
Best regards.
I was receiving the same error on pages where there was a mixture of EntityDataSource objects and other data access such as ObjectDataSource and/or imperative code.
I took the advice of the MSDN article referenced in the other answer to your question. I.e. to use context.MetadataWorkspace.LoadFromAssembly(...). I actually didn't know how to get a reference to the context instance used by EntityDataSource, and I figured I should DRY it up anyway, so I created a partial class eg:
public partial class YourTypeNameEntities
{
partial void OnContextCreated()
{
this.MetadataWorkspace.LoadFromAssembly(typeof(Full.Namespace.Of.YourTypeNameEntities).Assembly);
}
It still didn't work, but I noticed fairly quickly that when calling DataBind() on a control bound to an EntityDataSource that my OnContextCreated() implementation was not firing!
That was a different issue to which I found a solution... replace the ConnectionString and DefaultContainerName attributes in the EntityDataSource declaration with ContextTypeName. For example:
<asp:EntityDataSource ID="CountrySource" runat="server"
ContextTypeName="Full.Namespace.Of.YourTypeNameEntities" EntitySetName="Country"
OrderBy="it.Name" Where="it.Active==true">
That made sure my OnContextCreated implementation would fire and POOF, the "Loading by both name and attribute is not allowed" problem went away!
It's an old post but I've ran throught this problem twice this week and it seems to, in my case at least, to be related about the fact that I opened a VPN (for a complete other task with no link to this entity projet) and then, this error happened.
I've tried to close my VPN... then close my projet and re-open, completly close my VS without any success. But, restarting my computer make it works back.
Hope this helps if someone get this in same circonstences.
I was seeing the same error message, using EF 5.0 and WCF Data Services 5.2.0. This was a data service using a DbContext-derived class.
The fix for me was to separate code-first EF code from model-first EF code. By moving the code-first code into a separate assembly, the error message went away and things are working. The only way I was able to figure out to try this, is that the [EdmSchema] attribute exists on the code generated from our EDMX; but it doesn't exist on our model (code-first) code.
Hope that helps someone...
I was getting the same error for days. I using was a mixture of EntityDataSource objects and other data access such as ObjectDataSource in the same page. Replaced the EntityDataSource objects with ObjectDataSource. Problem went away!

Categories

Resources