2017-08-16 1 views
0

ce que j'essaie de trouver loin de déplacer la propriété DynamicProperties à la propriété JSONdata à cause de cela j'ai cette fonction de réflexion pour faire le travail quand il s'agit de DynamicProperties il lance exception "System.InvalidCastException: 'Object doit implémenter IConvertible. quelqu'un m'aide?Déplacement de la propriété vers une autre propriété de la classe throws exception "System.InvalidCastException: 'L'objet doit implémenter IConvertible.'"?

public IHttpActionResult Get(ODataQueryOptions<Client> options) 
    { 
     if(queryNew.ElementType == typeof(Client)){} 
     else //if (queryNew.ElementType.Name == "SelectSome`1") 
     { 
      var results = new List<Client>(); 
      try 
      { 
       foreach (var item in queryNew) 
       { 
        var dict = ((ISelectExpandWrapper)item).ToDictionary(); 
        var model = DictionaryToObject<Client>(dict); 
        results.Add(model); 

       } 

       return Ok(results); 
      } 
      catch (Exception) 
      { 

       throw; 
      } 
} 

    private static T DictionaryToObject<T>(IDictionary<string, object> dict) where T : new() 
    { 
     T t = new T(); 
     PropertyInfo[] properties = t.GetType().GetProperties(); 

     foreach (PropertyInfo property in properties) 
     { 
      if (!dict.Any(x => x.Key.Equals(property.Name, StringComparison.InvariantCultureIgnoreCase))) 
       continue; 
      KeyValuePair<string, object> item = dict.First(x => x.Key.Equals(property.Name, StringComparison.InvariantCultureIgnoreCase)); 
      Type tPropertyType = t.GetType().GetProperty(property.Name).PropertyType; 
      Type newT = Nullable.GetUnderlyingType(tPropertyType) ?? tPropertyType; 
      if(dict.Any(x => x.Key.Equals("DynamicProperties", StringComparison.InvariantCultureIgnoreCase))) 
      { 
       object temp = JsonConvert.SerializeObject(item.Value, Formatting.Indented); //Convert.ChangeType(item.Value.ToString(), newT); 
       t.GetType().GetProperty("JsonData").SetValue(t, temp, null); 
      } 
      object newA = Convert.ChangeType(item.Value, newT); 
      t.GetType().GetProperty(property.Name).SetValue(t, newA, null); 
     } 
     return t; 
    } 

classe client

public class Client 
{ 
    public Guid Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    public string ParticipantId { get; set; } 
    public DateTime? BirthDate { get; set; } 
    public int Gender { get; set; } 
    public byte? Age { get; set; } 
    public int Status { get; set; } 
    public string Notes { get; set; } 
    public DateTime CreatedDate { get; set; } 
    public DateTime? UpdatedDate { get; set; } 
    public DateTime? DeletedDate { get; set; } 
    public bool IsDeleted { get; set; } 
    public int? DefaultLanguageId { get; set; } 
    public Guid UserId { get; set; } 
    public string JsonData { get; set; } 

    public virtual ICollection<ClientTag> ClientTags { get; private set; } 

    protected IDictionary<string, object> _dynamicProperties; 
    public IDictionary<string, object> DynamicProperties 
    { 
     get 
     { 
      if (_dynamicProperties == null) 
      { 
       if (this.JsonData == null) 
       { 
        _dynamicProperties = new Dictionary<string, object>(); 
       } 
       else 
       { 
        _dynamicProperties = Mapper.Map<IDictionary<string, object>>(JObject.Parse(this.JsonData)); 
       } 

       //_dynamicProperties.Source.ListChanged += (sender, e) => { this.AssessmentData = _dynamicProperties.Source.ToString(); }; 
      } 

      return _dynamicProperties; 
     } 
    } 
    public void UpdateJsonDataFromDynamicProperties() 
    { 
     this.JsonData = Mapper.Map<JObject>(_dynamicProperties).ToString(); 
    } 
} 

Répondre

3

Lorsque vous obtenez une erreur IConvertable, cela signifie que vous avez essayé d'affecter un type à l'autre. Par exemple, si vous essayez d'affecter une zone de texte à une chaîne, vous obtiendrez une erreur car vous ne pouvez pas affecter un objet à une chaîne, vous devrez utiliser Iconvertible. .: par exemple

String.ToString(); 

qui implémente implicitement Iconvertible.

Je ne peux pas dire exactement où votre code échoue, vous ne l'avez pas mentionné non plus, je peux juste vous dire que quelque part dans les méthodes client, vous essayez d'assigner deux types différents et vous ne pouvez pas le faire.

Utilisez le débogage sur les classes serveur et client et vérifiez où vous essayez d'affecter deux types différents, puis implémentez le Iconvertible souhaité, ce qui signifie effectuer la conversion nécessaire.

Le seul problème dans votre code ici, c'est que vous essayez d'assigner à différents types.

Je pense, est que cette ligne a causé des problèmes:

if (this.JsonData == null) 
       { 
        _dynamicProperties = new Dictionary<string, object>(); 
       } 
       else 
       { 
        _dynamicProperties = Mapper.Map<IDictionary<string, object>>(JObject.Parse(this.JsonData)); 
       } 

Lorsque vous essayez d'assigner _dynamicProperties dans un objet dictionnaire quand, en fait, vous avez déclaré _dynamicProperties comme objet IDictionary.

Il existe une différence subtile entre les objets Idictionary et dictionnaire, ils ne sont pas du même type. c'est le changement à faire:

if (this.JsonData == null) 
        { 
         _dynamicProperties = new IDictionary<string, object>(); 
        } 
        else 
        { 
         _dynamicProperties = Mapper.Map<IDictionary<string, object>>(JObject.Parse(this.JsonData)); 
        }