简体   繁体   English

C#JSON反序列化:Type是接口或抽象类,无法实例化

[英]C# JSON Deserialization : Type is an interface or abstract class and cannot be instantiated

I'm using this C# project which uses APIs to communicate with the online trading platform Poloniex . 我正在使用这个C#项目,该项目使用API与在线交易平台Poloniex进行通信

This code is supposed to get balances in a wallet: 此代码应该在钱包中获得余额:

var x = await polo_client.Wallet.GetBalancesAsync();

Although this code gives this error: 虽然此代码提供此错误:

Error getting wallet:Could not create an instance of type Jojatekok.PoloniexAPI.WalletTools.IBalance. 获取钱包时出错:无法创建Jojatekok.PoloniexAPI.WalletTools.IBalance类型的实例。
Type is an interface or abstract class and cannot be instantiated. Type是接口或抽象类,无法实例化。
Path '1CR.available', line 1, position 20. 路径'1CR.available',第1行,第20位。

in Helper.cs here: 在Helper.cs这里:

[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
internal static T DeserializeObject<T>(this JsonSerializer serializer, string value)
{ 
    using (var stringReader = new StringReader(value))
    {
        using (var jsonTextReader = new JsonTextReader(stringReader))
        {
            return (T)serializer.Deserialize(jsonTextReader, typeof(T));
        }
    } 
}

The code to call this is: 调用它的代码是:

public T GetData<T>(string command, params object[] parameters)
{
    var relativeUrl = CreateRelativeUrl(command, parameters);
    var jsonString = QueryString(relativeUrl);
    var output = JsonSerializer.DeserializeObject<T>(jsonString);
    return output;
}

Can someone tell me why I'm getting an error deserializing this JSON response? 有人能告诉我为什么我在反序列化这个JSON响应时出错了吗?

The response is JSON, here is a sample of it: 响应是JSON,以下是它的示例:

{
"1CR":{"available":"0.00000000","onOrders":"0.00000000","btcValue":"0.00000000"},
"ABY":{"available":"0.00000000","onOrders":"0.00000000","btcValue":"0.00000000"}
}

JSON or not, the error is self-describing. 是不是JSON,错误是自我描述的。 You can not instantiate an interface or abstract class. 您无法实例化接口或抽象类。 They are just blue-prints of what functionality or object structure they'd represent. 它们只是他们所代表的功能或对象结构的蓝图。

For example, you can not do this: 例如,你不能这样做:

var something = new ISomething();

but, you can do this: 但是,你可以这样做:

ISomething something = new Something();

All you need is just some concrete implementation of that interface. 您只需要该接口的一些具体实现。 Something like: 就像是:

public JsonReceived : IBalance
{
// rest of the implementation
}

Or that might already be provided by the third-party, check their SDK documentation. 或者可能已由第三方提供,请检查其SDK文档。

This is what i have done to get it working. 这就是我为使其工作所做的工作。 Thanks to Chris from Guru.com for getting this working. 感谢来自Guru.com的Chris让这个工作。 Great guy and very well priced. 伟大的家伙,非常好的价格。 You can find him here: http://www.guru.com/freelancers/deatc 你可以在这里找到他: http//www.guru.com/freelancers/deatc

private IDictionary<string, IBalance> GetBalances()
{
    var postData = new Dictionary<string, object>();
    var data = PostData<IDictionary<string, Balance>>("returnCompleteBalances", postData);
    var returnData = new Dictionary<string, IBalance>();

    foreach (string key in data.Keys)
    {
        returnData.Add(key, data[key]);
    }

    return returnData;
}

The error causing due to DeSerialization of an object, that internally creates an Jobject and Cast it as a input Generic, in the above scenario since we cannot create an object of Interface it is throwing an error, we can achieve in the below ways according to your solution that is posted in GitHub 由于对象的DeSerialization导致的错误,内部创建一个Jobject并将其作为输入Generic投射,在上面的场景中,因为我们无法创建一个Interface的对象,所以它抛出一个错误,我们可以通过以下方式实现根据您在GitHub中发布的解决方案

  • add a Hashtable as a generic input to PostData method 添加Hashtable作为PostData方法的通用输入
  • change your wallet.cs as ex: 改变你的wallet.cs如下:

     IBalance CreateFactory(string typeOfBalance, string jsonString) { IBalance balance = null; switch (typeOfBalance) { case "balanceClassIdentification": balance = new Balance(); balance = Newtonsoft.Json.JsonConvert.DeserializeObject<Balance>(jsonString); break; case "": // write logic if Ibalance interface implemented in any childClass ex: class stockBalance: IBalance , then balance = new StockBalance();balance = Newtonsoft.Json.JsonConvert.DeserializeObject<stockBalance>(jsonString); default: balance = new Balance(); balance = Newtonsoft.Json.JsonConvert.DeserializeObject<Balance>(jsonString); break; } return balance; } private IDictionary<string, IBalance> GetBalances() { IDictionary<string, IBalance> data = null; var postData = new Dictionary<string, object>(); //var data = PostData<IDictionary<string, object>>("returnCompleteBalances", postData); Hashtable output = PostData<Hashtable>("returnCompleteBalances", postData); if (output.Count > 0) { data = new Dictionary<string, IBalance>(); } foreach (string jsonObjKey in output.Keys) { IBalance balace = CreateFactoty("balanceClassIdentification", output[jsonObjKey].ToString()); // this "balanceClassIdentification" just used as a string but we can add the condition in createFactory according to the type of object that wallet data.Add(jsonObjKey, balace); } return data; } 

  • Create another intermediate class that implemented Ibalance 创建另一个实现Ibalance的中间类
  • like 喜欢

     public class BalanceBase: IBalace { } 

    need to change the balance class 需要改变平衡等级

     private IDictionary<string, Balance> GetBalances()
            {
    
                var postData = new Dictionary<string, object>();
                var data = PostData<IDictionary<string, Balance>>("returnCompleteBalances", postData);
    
                return data;
            }
    

  • if No other classes are implemented for IBalance except balance 如果除了余额之外没有为IBalance实施其他类别
  • you can directly use return type for GetBalance() method as IDictionary and change the implementaion 您可以直接将GetBalance()方法的返回类型用作IDictionary并更改实现

      private IDictionary<string, Balance> GetBalances() { var postData = new Dictionary<string, object>(); var data = PostData<IDictionary<string, Balance>>("returnCompleteBalances", postData); return data; } 

    暂无
    暂无

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

    相关问题 类型是接口或抽象类,无法实例化。 c#发送一个包含抽象对象列表的对象 - Type is an interface or abstract class and cannot be instantiated. c# send a object with contain a list of abstract object 类型是接口或抽象类,不能被实例化 - Type is an interface or abstract class and cannot be instantiated Json.NET - 反序列化接口属性抛出错误“类型是接口或抽象 class,无法实例化” - Json.NET - Deserialising interface property throws error "type is an interface or abstract class and cannot be instantiated" 无法创建类型的实例。 类型是接口或抽象类,不能被实例化 - Could not create an instance of type . Type is an interface or abstract class and cannot be instantiated ReadAsAsync - 错误:“Type是一个接口或抽象类,无法实例化。” - ReadAsAsync - Error : “Type is an interface or abstract class and cannot be instantiated.” 为什么不能实例化抽象类和接口? - Why abstract class and interface cannot be instantiated? 具有动态类型的C#接口/抽象类 - C# Interface/Abstract Class with Dynamic Type 无法创建类型 X 的实例。类型是接口或抽象类,无法实例化 - Could not create an instance of type X. Type is an interface or abstract class and cannot be instantiated C#声明类型定义无法创建抽象类或接口的实例 - C# Declaring Type Definition Cannot create an instance of the abstract class or interface C#接口和抽象类 - C# interface and abstract class
     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM