我的方法有字符串类型参数,返回列表,其中Tasks是我定义的类。
当我想 JSON序列化返回的列表时,它会给我一个例外: InvalidOperationException(“Json可序列化类型必须具有公共的无参数构造函数”);
我该怎么办?
我的班级看起来像这样:
public class Tasks
{
public int _taskReprogramat;
public int TaskReprogramat{ get; set; }
public string TaskName {get; set; }
public string Description{get; set; }
public string IntreOrele{get; set; }
public DateTime AssignDate{get; set; }
public string Status{get; set; }
public Tasks() { }
}
我有以下课程:
public class DataContractJsonSerializerOperationBehavior : DataContractSerializerOperationBehavior
{
public DataContractJsonSerializerOperationBehavior(OperationDescription operation) : base(operation) { }
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
return new DataContractJsonSerializer(type);
}
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
return new DataContractJsonSerializer(type);
}
}
和
public class JsonDataContractBehaviorAttribute : Attribute, IContractBehavior
{
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
this.ReplaceSerializerOperationBehavior(contractDescription);
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
this.ReplaceSerializerOperationBehavior(contractDescription);
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
foreach (OperationDescription operation in contractDescription.Operations)
{
foreach (MessageDescription message in operation.Messages)
{
this.ValidateMessagePartDescription(message.Body.ReturnValue);
foreach (MessagePartDescription part in message.Body.Parts)
{
this.ValidateMessagePartDescription(part);
}
foreach (MessageHeaderDescription header in message.Headers)
{
this.ValidateJsonSerializableType(header.Type);
}
}
}
}
private void ReplaceSerializerOperationBehavior(ContractDescription contract)
{
foreach (OperationDescription od in contract.Operations)
{
for (int i = 0; i < od.Behaviors.Count; i++)
{
DataContractSerializerOperationBehavior dcsob = od.Behaviors[i] as DataContractSerializerOperationBehavior;
if (dcsob != null)
{
od.Behaviors[i] = new DataContractJsonSerializerOperationBehavior(od);
}
}
}
}
private void ValidateMessagePartDescription(MessagePartDescription part)
{
if (part != null)
{
this.ValidateJsonSerializableType(part.Type);
}
}
private void ValidateJsonSerializableType(Type type )
{
if (type != typeof(void))
{
if (!type.IsPublic)
{
throw new InvalidOperationException("Json serialization is supported in public types only");
}
ConstructorInfo defaultConstructor = type.GetConstructor(new Type[0]);
if (!type.IsPrimitive && defaultConstructor == null )
{
throw new InvalidOperationException("Json serializable types must have a public, parameterless constructor");
}
}
}
}
我在使用Tasks类的方法是:
public List<Tasks> GetTask(string admin, DateTime date)
{
List<Tasks> tasks = new List<Tasks>();
string conn = ConfigurationManager.ConnectionStrings["qtmConnectionString"].ConnectionString;
SqlConnection myConn = new SqlConnection(conn);
myConn.Open();
SqlCommand myCommand = new SqlCommand("tasks", myConn);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("@username", SqlDbType.NChar);
myCommand.Parameters["@username"].Value = admin;
myCommand.Parameters.AddWithValue("@date", date);
SqlDataReader reader = myCommand.ExecuteReader();
string status = null;
string intreOrele = null;
Tasks task = new Tasks();
task.TaskName = reader[1].ToString();
task.Description = reader[2].ToString();
task.IntreOrele = intreOrele;
task.AssignDate = Convert.ToDateTime(reader[5]);
task.Status = status;
tasks.Add(task); return tasks;
}
答案 0 :(得分:1)
问题是您要反序列化的类没有公共的无参数构造函数。它可能看起来像这样:
public class Person
{
public Person(int id, string name)
{
this.id = id;
this.person = person;
}
private int id;
private string name;
public string Name { get { return this.name; } }
public int Id { get { return this.id; } }
}
问题是JSON序列化程序需要这样做:
var obj = new Person();
obj.Id = jsonParser.Get<int>("id");
obj.Name = jsonParser.Get<string>("name");
通过这样的构造函数是不够聪明(或设计):
var obj = new Person( jsonParser.Get<int>("id"), jsonParser.Get<string>("name") );
所以改变你的课程来做到这一点:
public class Person
{
public Person(int id, string name)
{
this.Id = id;
this.Person = person;
}
// Parameterless constructor here
public Person()
{
}
public string Name { get ; set; }
public int Id { get;set; }
}