序列化和反序列化 AjaxFileUploadEventArgs - 未定义无参数构造函数'

Serialize and Deserialize AjaxFileUploadEventArgs - No parameterless constructor defined'

我正在更改一个网络表单网站以使用 StateServer,现在我正试图找到一种方法来序列化和反序列化 AjaxFileUploadEventArgs,我目前的代码:

在 html 我有:

<ajaxToolkit:AjaxFileUpload
ID="AAA"
runat="server"
OnUploadComplete="OnUploadComplete"
ViewStateMode="Enabled" />

服务器:

protected void OnUploadComplete(object sender, AjaxFileUploadEventArgs file)
        {
            UpdateListInSession(file);
        }

public static void UpdateListInSession(AjaxFileUploadEventArgs file)
{
  var serializer = new JavaScriptSerializer();
  var fileSerialized = serializer.Serialize(file);
}

public static AjaxFileUploadEventArgs GetLeadsListFromSession()
{
    var serializer = new JavaScriptSerializer();
    AjaxFileUploadEventArgs file = null;

    AjaxFileUploadEventArgs deserializeFile = 
         serializer.Deserialize<AjaxFileUploadEventArgs>(
            HttpContext.Current.Session[k_file] as string);

  return deserializeFile;
}

错误:

System.MissingMethodException: 'No parameterless constructor defined for type of 'AjaxControlToolkit.AjaxFileUploadEventArgs'.'

假设你使用的是AjaxFileUploadEventArgs.cs from , the exception message is self-explanatory. The serializer you are using, JavaScriptSerializer, can only construct and deserialize a type with a parameterless constructor, but as shown in its reference sourceAjaxFileUploadEventArgs只有一个构造函数,它是参数化的:

public AjaxFileUploadEventArgs(string fileId, AjaxFileUploadState state, string statusMessage, string fileName, int fileSize, string contentType) {
        // Initialize fields
}

那么,反序列化此类型的选项有哪些?首先,您可以切换到支持开箱即用的参数化构造函数的 。安装 Json.NET 后,如果您这样做:

var deserializeFile = 
    Newtonsoft.Json.JsonConvert.DeserializeObject<AjaxFileUploadEventArgs>(jsonString);

然后就可以了。 JavaScriptSerializer 的样本 fiddle. Note that Microsoft's own documentation 状态:

Json.NET should be used serialization and deserialization.

所以这可能是最好的解决方案。

如果您出于某种原因无法使用 Json.NET,则需要为 AjaxFileUploadEventArgs 编写自定义 JavaScriptConverter,例如:

public class AjaxFileUploadEventArgsConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        var args = new AjaxFileUploadEventArgs
        (
            serializer.ConvertItemToTypeOrDefault<string>(dictionary, "FileId"),
            serializer.ConvertItemToTypeOrDefault<AjaxFileUploadState>(dictionary, "State"),
            serializer.ConvertItemToTypeOrDefault<string>(dictionary, "StatusMessage"),
            serializer.ConvertItemToTypeOrDefault<string>(dictionary, "FileName"),
            serializer.ConvertItemToTypeOrDefault<int>(dictionary, "FileSize"), 
            serializer.ConvertItemToTypeOrDefault<string>(dictionary, "ContentType")
        ) 
        { PostedUrl = serializer.ConvertItemToTypeOrDefault<string>(dictionary, "PostedUrl") };
        return args;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new[] { typeof(AjaxFileUploadEventArgs) }; }
    }
}

public static class JavaScriptSerializerExtensions
{
    public static T ConvertItemToTypeOrDefault<T>(this JavaScriptSerializer serializer, IDictionary<string, object> dictionary, string key)
    {
        object value;

        if (!dictionary.TryGetValue(key, out value))
            return default(T);

        return serializer.ConvertToType<T>(value);
    }
}

然后反序列化如下:

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] { new AjaxFileUploadEventArgsConverter() });
var deserializeFile = serializer.Deserialize<AjaxFileUploadEventArgs>(jsonString);