Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ModelState错误-Newtonsoft.Json.JsonSerializationException:无法填充列表类型System.Net.TrackingString目录_C#_.net_Asp.net Web Api_Json.net - Fatal编程技术网

C# ModelState错误-Newtonsoft.Json.JsonSerializationException:无法填充列表类型System.Net.TrackingString目录

C# ModelState错误-Newtonsoft.Json.JsonSerializationException:无法填充列表类型System.Net.TrackingString目录,c#,.net,asp.net-web-api,json.net,C#,.net,Asp.net Web Api,Json.net,当一个用户试图调用webApi时,标题中出现了错误。 这是我的班级: public class NotificationDTO { public long idCompanyService { get; set; } public DocTypeEnum DocumentType { get; set; } public List<Tuple<string, byte[], System.Net.Mime.ContentType>> Attac

当一个用户试图调用webApi时,标题中出现了错误。 这是我的班级:

public class NotificationDTO
{
    public long idCompanyService { get; set; }

    public DocTypeEnum DocumentType { get; set; }

    public List<Tuple<string, byte[], System.Net.Mime.ContentType>> Attachments { get; set; }
}
这就是电话:

HttpContent content = new StringContent(JsonConvert.SerializeObject(notifDto), Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync(uri, content).Result;
这是一个Json:

{"idCompanyService":1234,"DocumentType":0,"Attachments":[{"Item1":"test.pdf","Item2":"ThisIsABase64Data","Item3":{"Boundary":null,"CharSet":null,"MediaType":"application/pdf","Name":null,"Parameters":[]}}}
附件有问题,因为它是一个
列表

错误消息:

Exception: Newtonsoft.Json.JsonSerializationException: Cannot populate list type System.Net.TrackingStringDictionary. Path 'Attachments.$values[0].Item3.Parameters.$values', line 1, position 105257.
   in Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   in Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id)
   in Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   in Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   in Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   in Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)

试一试: 您可以使用简单的web api控制器再现错误:

[HttpPost]
[Route("api/TestNotification")]
public IHttpActionResult TestNotification(NotificationDTO dto)
{
    return Ok();
}
Post调用程序中的Json如下所示:

{"idCompanyService":1234,"DocumentType":1,"Attachments":[{"Item1":"wqere.pdf","Item2":"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=","Item3":{"Boundary":null,"CharSet":null,"MediaType":"application/pdf","Name":null,"Parameters":[]}},{"Item1":"ewqeqwe.xml","Item2":"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=","Item3":{"Boundary":null,"CharSet":null,"MediaType":"text/xml","Name":null,"Parameters":[]}}]}
最后,一个.Net fiddle演示了将上述JSON字符串反序列化为
NotificationDTO
时的失败,通过:

var dto = JsonConvert.DeserializeObject<NotificationDTO>(json);
var dto=JsonConvert.DeserializeObject(json);

可以在这里找到:。

这里真正的问题是DTO引用类型为的对象,而该对象又有一个声明类型(和实际类型)的成员。 不幸的是,这种古老的类型(来自.NET1.1)甚至没有实现
IDictionary
。由于Json.NET只实现非类型化枚举器
System.Collections.IEnumerable
,因此它无法知道如何对其进行反序列化,并在请求时抛出您看到的异常

因此,有必要编写一个程序来反序列化此类型的对象或从该类型派生的对象:

using System.Collections.Specialized;

public class StringDictionaryConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(StringDictionary).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var tokenType = reader.SkipComments().TokenType;
        if (tokenType == JsonToken.Null)
            return null;

        var dictionary = existingValue as StringDictionary ?? (StringDictionary)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();

        switch (tokenType)
        {
            case JsonToken.StartArray:
                {
                    // StringDictionary serialized without converter
                    var list = serializer.Deserialize<List<KeyValuePair<string, string>>>(reader);
                    foreach (var pair in list)
                        dictionary.Add(pair.Key, pair.Value);
                }
                break;

            case JsonToken.StartObject:
                {
                    // StringDictionary serialized with converter
                    var typedDictionary = serializer.Deserialize<Dictionary<string, string>>(reader);
                    foreach (var pair in typedDictionary)
                        dictionary.Add(pair.Key, pair.Value);
                }
                break;

            default:
                throw new JsonSerializationException(string.Format("Unknown token {0} at path {1}", tokenType, reader.Path));
        }

        return dictionary;
    }

    // Change to false if you want the dictionary written as an array of key/value objects.
    public override bool CanWrite { get { return true; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dictionary = (StringDictionary)value;
        writer.WriteStartObject();
        foreach (DictionaryEntry entry in dictionary)
        {
            writer.WritePropertyName((string)entry.Key);
            writer.WriteValue((string)entry.Value);
        }
        writer.WriteEndObject();
    }
}

public static partial class JsonExtensions
{
    public static JsonReader SkipComments(this JsonReader reader)
    {
        while (reader.TokenType == JsonToken.Comment && reader.Read())
            ;
        return reader;
    }
}
  • ASP.NET核心MVC:请参阅或。在这里,您将再次访问全局
    JsonSerializerSettings
    ,并添加一个
    StringDictionaryConverter
    ,如上所示

  • 您可能还希望在客户端使用转换器来序列化JSON。如果这样做,您的内容参数将被更紧凑地序列化为JSON对象,而不是键/值数组。(转换器接受两种形式作为输入。)


    小提琴样品。

    请您将问题分享给我们,好吗?在这种情况下,我认为为
    NotificationDTO
    、反序列化代码和示例JSON定义就足够了。您的错误消息似乎很好,在尝试序列化
    System.Net时,在字符位置105257处序列化失败。TrackingStringDictionary
    -并非所有类型都可以转换为JSON。顺便说一下,这是一个相当大的数字,看起来您正在发送文件数据?如果看不到你的结构,很难说。好吧,我编辑了我的问题@dbct,但这不是一个真正的问题。异常发生在哪一行?是在
    HttpContent content=newstringcontent(JsonConvert.SerializeObject(notifDto),Encoding.UTF8,“application/json”)或位于
    httpresponsemessageresponse=client.PostAsync(uri,content.Result)?如何在一个简单的控制台应用程序中重现该问题?消息中没有行号。当我调用WebApi时,在第一行到达之前,将异常抛出到日志文件中。
    
    using System.Collections.Specialized;
    
    public class StringDictionaryConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(StringDictionary).IsAssignableFrom(objectType);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var tokenType = reader.SkipComments().TokenType;
            if (tokenType == JsonToken.Null)
                return null;
    
            var dictionary = existingValue as StringDictionary ?? (StringDictionary)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
    
            switch (tokenType)
            {
                case JsonToken.StartArray:
                    {
                        // StringDictionary serialized without converter
                        var list = serializer.Deserialize<List<KeyValuePair<string, string>>>(reader);
                        foreach (var pair in list)
                            dictionary.Add(pair.Key, pair.Value);
                    }
                    break;
    
                case JsonToken.StartObject:
                    {
                        // StringDictionary serialized with converter
                        var typedDictionary = serializer.Deserialize<Dictionary<string, string>>(reader);
                        foreach (var pair in typedDictionary)
                            dictionary.Add(pair.Key, pair.Value);
                    }
                    break;
    
                default:
                    throw new JsonSerializationException(string.Format("Unknown token {0} at path {1}", tokenType, reader.Path));
            }
    
            return dictionary;
        }
    
        // Change to false if you want the dictionary written as an array of key/value objects.
        public override bool CanWrite { get { return true; } }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var dictionary = (StringDictionary)value;
            writer.WriteStartObject();
            foreach (DictionaryEntry entry in dictionary)
            {
                writer.WritePropertyName((string)entry.Key);
                writer.WriteValue((string)entry.Value);
            }
            writer.WriteEndObject();
        }
    }
    
    public static partial class JsonExtensions
    {
        public static JsonReader SkipComments(this JsonReader reader)
        {
            while (reader.TokenType == JsonToken.Comment && reader.Read())
                ;
            return reader;
        }
    }
    
    protected void Application_Start()
    {
        var config = GlobalConfiguration.Configuration;
        var settings = config.Formatters.JsonFormatter.SerializerSettings;
        settings.Converters.Add(new StringDictionaryConverter());
    }