如何使用 C# CSharpCodeProvider 和 BinaryFormatter 在运行时编译可序列化对象
How to compile a serializable object at runtime using C# CSharpCodeProvider and BinaryFormatter
所以,
我有以下代码作为文本:
using digitracktest.DigiTrack.CoreLogic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Runtime.Serialization;
namespace EntityModels
{
[Serializable()]
public class ActionInstance : IAction
{
private string _id;
public string id {
get { return _id; }
set { _id = value; }
}
public void execute()
{
//Rest of the codes
}
}
}
我想在运行时使用 CSharpCodeProvider 编译上面的代码。
以下是我的编译方式:
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
parameters.ReferencedAssemblies.Add("mscorlib.dll");
parameters.GenerateInMemory = false; // True - memory generation, false - external file generation
parameters.GenerateExecutable = false; // True - exe file generation, false - dll file generation
CompilerResults results = provider.CompileAssemblyFromSource(parameters, a.src);
_CompileResults = results;
if (results.Errors.HasErrors)
{
List<string> errors = new List<string>();
results.Errors.Cast<CompilerError>().ToList().ForEach(error => errors.Add(error.ErrorText));
return new { isSuccess = false, errors = errors };
}
else
{
Assembly assembly = results.CompiledAssembly;
IAction act = (IAction)assembly.CreateInstance("EntityModels.ActionInstance");
act.id = a.actionId;
Stream stream = new FileStream(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/a/") + a.id + ".dat", FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(stream, a);
stream.Close();
return new { isSuccess = true };
}
问题是在编译后,我需要使用 BinaryFormatter 将其序列化并保存到文件中。
虽然我已经用 Serializable
标记标记了 class,但我仍然收到以下错误:
Type 'EntityModels.ActionInstance' in Assembly
'3k0rfezm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is
not marked as serializable.
我真的不知道如何从这里开始。不幸的是,CSharpCodeProvider 和 BinaryFormatter 是要求的一部分。非常感谢任何帮助。
干杯!
我找到了罪魁祸首!
显然,因为我在循环中调用了这个编译方法,所以显然有一些旧的蓝图代码我还没有标记为 [Serializable()]
。这导致某些对象编译时没有 Serializable
标记。我检查了:
Type x = act.GetType();
Console.WriteLine("Is Object Serializable: " + x.IsSerializable);
其中一些返回 false
。
希望有一天这对某些人也有帮助。
干杯!
所以,
我有以下代码作为文本:
using digitracktest.DigiTrack.CoreLogic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Runtime.Serialization;
namespace EntityModels
{
[Serializable()]
public class ActionInstance : IAction
{
private string _id;
public string id {
get { return _id; }
set { _id = value; }
}
public void execute()
{
//Rest of the codes
}
}
}
我想在运行时使用 CSharpCodeProvider 编译上面的代码。
以下是我的编译方式:
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
parameters.ReferencedAssemblies.Add("mscorlib.dll");
parameters.GenerateInMemory = false; // True - memory generation, false - external file generation
parameters.GenerateExecutable = false; // True - exe file generation, false - dll file generation
CompilerResults results = provider.CompileAssemblyFromSource(parameters, a.src);
_CompileResults = results;
if (results.Errors.HasErrors)
{
List<string> errors = new List<string>();
results.Errors.Cast<CompilerError>().ToList().ForEach(error => errors.Add(error.ErrorText));
return new { isSuccess = false, errors = errors };
}
else
{
Assembly assembly = results.CompiledAssembly;
IAction act = (IAction)assembly.CreateInstance("EntityModels.ActionInstance");
act.id = a.actionId;
Stream stream = new FileStream(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/a/") + a.id + ".dat", FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(stream, a);
stream.Close();
return new { isSuccess = true };
}
问题是在编译后,我需要使用 BinaryFormatter 将其序列化并保存到文件中。
虽然我已经用 Serializable
标记标记了 class,但我仍然收到以下错误:
Type 'EntityModels.ActionInstance' in Assembly '3k0rfezm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
我真的不知道如何从这里开始。不幸的是,CSharpCodeProvider 和 BinaryFormatter 是要求的一部分。非常感谢任何帮助。
干杯!
我找到了罪魁祸首!
显然,因为我在循环中调用了这个编译方法,所以显然有一些旧的蓝图代码我还没有标记为 [Serializable()]
。这导致某些对象编译时没有 Serializable
标记。我检查了:
Type x = act.GetType();
Console.WriteLine("Is Object Serializable: " + x.IsSerializable);
其中一些返回 false
。
希望有一天这对某些人也有帮助。
干杯!