在C#中将JSON列表反序列化为ICollection时出错

时间:2014-06-18 10:03:50

标签: c# interface json-deserialization icollection

我有三个项目:

  1. App.Models:包含对象接口。
  2. App.WebAPIService:使用JSON的RESTFul API服务。
  3. App.Client:与RESTful API服务通信的WPF应用程序。
  4. 我使用 Entity Framework 来创建接口和模型。

    App.Models在其他两个项目中用于创建对象。

    public interface ISheet
    {
        int ID { get; set; }
        string Name { get; set; }
        Nullable<System.DateTime> CreatedDate { get; set; }
        string CreatedUser { get; set; }
    
        ICollection<ICategory> Category { get; set; }
    }
    
    public interface ICategory
    {
        int ID { get; set; }
        string Name { get; set; }
    }
    

    App.WebAPIService:

    [DataContract(IsReference = true)]
    [KnownType(typeof(Category))]
    public partial class Sheet : ISheet
    {
        #region Primitive Properties
        [DataMember]
        public int ID
        {
            get;
            set;
        }
        [DataMember]
        public Nullable<System.DateTime> CreatedDate
        {
            get;
            set;
        }
        [DataMember]
        public string CreatedUser
        {
            get;
            set;
        }
        [DataMember]
        public string Name
        {
            get;
            set;
        }
        #endregion
        #region Navigation Properties
        [DataMember]
        public ICollection<ICategory> Category
        {
            get
            {
                if (_category == null)
                {
                    var newCollection = new FixupCollection<ICategory>();
                    newCollection.CollectionChanged += FixupCategory;
                    _category = newCollection;
                }
                return _category;
            }
            set
            {
                if (!ReferenceEquals(_category, value))
                {
                    var previousValue = _category as FixupCollection<ICategory>;
                    if (previousValue != null)
                    {
                        previousValue.CollectionChanged -= FixupCategory;
                    }
                    _category = value;
                    var newValue = value as FixupCollection<ICategory>;
                    if (newValue != null)
                    {
                        newValue.CollectionChanged += FixupCategory;
                    }
                }
            }
        }
        private ICollection<ICategory> _category;
    
        #endregion
        #region Association Fixup
        private void FixupCategory(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (ICategory item in e.NewItems)
                {
                    if (!item.Sheet.Contains(this))
                    {
                        item.Sheet.Add(this);
                    }
                }
            }
    
            if (e.OldItems != null)
            {
                foreach (ICategory item in e.OldItems)
                {
                    if (item.Sheet.Contains(this))
                    {
                        item.Sheet.Remove(this);
                    }
                }
            }
        }
    
        #endregion
    }
    
    public class SheetController : ApiController
    {
        private TORDBEntities db = new TORDBEntities();
    
        /// <summary>
        /// GET api/Sheet/5
        /// </summary>
        /// <param name="id">int</param>
        /// <returns>Sheet</returns>
        public Sheet GetSheet(int id)
        {
            Sheet sheet = db.Sheet.Include("Category").Single(s => s.ID == id);
            if (sheet == null)
            {
                throw new HttpResponseException
                    (Request.CreateResponse(HttpStatusCode.NotFound));
            }
    
            return sheet;
        }
    }
    

    App.Client:

    public class Sheet : ISheet
    {
        public int ID { get; set; }
        public DateTime? CreatedDate { get; set; }
        public string CreatedUser { get; set; }
        public string Name { get; set; }
    
        public ICollection<ICategory> Category { get; set; }
    }
    
    class ServiceSheet
    {
        public Sheet sheet = new Sheet();
    
        public Sheet GetSheet(int id)
        {
            string url = ConfigurationManager.AppSettings["UrlWebService"];
            url += @"api/sheet/" + id;
            HttpWebRequest requete = WebRequest.Create(url) as HttpWebRequest;
            requete.Method = WebRequestMethods.Http.Get;
    
            requete.BeginGetResponse(new AsyncCallback(this.GetSheetResponseCallback), 
                requete);
    
            return sheet;
        }
    
        private void GetSheetResponseCallback(IAsyncResult ar)
        {
            //Récupération de l'objet HttpWebRequest 
            HttpWebRequest requete = (HttpWebRequest)ar.AsyncState;
    
            try
            {
                using (HttpWebResponse reponse = requete.EndGetResponse(ar) 
                    as HttpWebResponse)
                {
                    using (StreamReader streamReader = new
                        StreamReader(reponse.GetResponseStream()))
                    {
                        string Text = streamReader.ReadToEnd();
                        sheet = JsonConvert.DeserializeObject<Sheet>(Text);
                        //Newtonsoft.Json.JsonSerializer serializer = new 
                            Newtonsoft.Json.JsonSerializer();
                        //serializer.Converters.Add(new DTOJsonConverter());
                        //Sheet maSheet = serializer.Deserialize(streamReader);
                    } 
                }
            }
            catch (WebException we)
            {
                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    HttpWebResponse r = (HttpWebResponse)we.Response;
                    if (r.StatusCode == HttpStatusCode.NotFound)
    
                        MessageBox.Show("Code d'erreur: " + r.StatusCode.ToString());
                    r.Close();
                }
                else
                    MessageBox.Show(we.Message + " " + we.Status.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Erreur");
            }
        }
    }
    

    我的反序列化类别出错了。我尝试过以下方法:

    public class Sheet : ISheet
    {
        public int ID { get; set; }
        public DateTime? CreatedDate { get; set; }
        public string CreatedUser { get; set; }
        public string Name { get; set; }
    
        [JsonConverter(typeof(ConcreteTypeConverter<Category>))]
        public ICollection<ICategory> Category { get; set; }
    }
    public class ConcreteTypeConverter<TConcrete> : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            //assume we can convert to anything for now
            return true;
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer)
        {
            //explicitly specify the concrete type we want to create
            return serializer.Deserialize<TConcrete>(reader);
        }
    
        public override void WriteJson(JsonWriter writer, object value, 
            JsonSerializer serializer)
        {
            //use the default serialization - it works fine
            serializer.Serialize(writer, value);
        }
    }
    

    错误:

      

    无法转换类型&#39; System.Collections.Generic.List 1[App.Client.Models.Category]' to type 'System.Collections.Generic.ICollection 1 [App.Models.ICategory]&#39;。

    的对象

    而且:

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
        {
            //explicitly specify the concrete type we want to create
            List<TConcrete> liste = serializer.Deserialize<List<TConcrete>>(reader);
            ICollection<TConcrete> coll = new Collection<TConcrete>();
            liste.ForEach(delegate(TConcrete obj)
            {
                coll.Add(obj);
            });
    
            return coll;
        }
    

    错误:

      

    无法投射类型的对象   &#39; {System.Collections.Generic.Collection {1}} 1 [App.Models.ICategory]&#39;

    我认为问题只是1[App.Client.Models.Category]' to type 'System.Collections.Generic.ICollection;你有没有遇到过这个问题,或者你有更好的解决方案吗?

    答案:

    好的,这是我的错!

    我忘了添加代码客户端的这一部分:

    ICollection

    没有FixupCategory,它就无法工作。

    希望,这会对一些人有所帮助。 感谢那些帮助过我的人。

0 个答案:

没有答案