将 CookComputing XMLRpcStruct (IEnumerable<Object>) 转换为实际的 C# class
Convert CookComputing XMLRpcStruct (IEnumerable<Object>) to an actual C# class
所以,我正在使用 CookComputings XMLRPC
库来与 InfusionSoft
交谈(这是一个非常流行的在线 CRM)。主要方法是:
[XmlRpcMethod("DataService.query")]
IEnumerable<object> QuerySubscriptionStatus(string apiKey,
string table, int limit, int page,
IDictionary queryData, string[] selectedFields);
很遗憾,我需要使用 IEnumerable<object>
,因为 InfusionSoft XML/RPC API 需要它。我希望不是这样,但遗憾的是。
自从我使用 .NET 4.5,我想我可以做一个动态转换:
var subStatus = proxy.QuerySubscriptionStatus(
_key, "RecurringOrder", 500, 0, dict, sarray);
var result = subStatus.Cast<SubscriptionStatus>();
不幸的是,这不起作用,我收到了一个来自 C# 的非常令人沮丧的错误:
Unable to cast object of type 'CookComputing.XmlRpc.XmlRpcStruct' to type 'WBI.Model.SubscriptionStatus'.`
我试过将我的 class 指定为 struct
;哎呀我什至尝试用 XMLRpcMember()
标签指定它,但是不,它只是不会转换。
如何与 IEnumerable
中的数据进行交互?
Class/Struct 我试过的类型
public struct SubStatus
{
public int AffiliateId;
public int AutoCharge;
public double BillingAmt;
public string BillingCycle;
public int CC1;
public int CC2;
public int ContactId;
public DateTime EndDate;
public int Frequency;
public int Id;
public DateTime LastBillDate;
public int LeadAffiliateId;
public int MaxRetry;
public int MerchantAccountId;
public DateTime NextBillDate;
public int NumDaysBetweenRetry;
public int OriginatingOrderId;
public DateTime PaidThruDate;
public int PaymentGatewayId;
public int ProductId;
public int ProgramId;
public string PromoCode;
public int Qty;
public string ReasonStopped;
public int ShippingOptionId;
public DateTime StartDate;
public string Status;
public int SubscriptionPlanId;
}
我也刚刚尝试了一个简单的 class 和 XMLRpcMember
标签:
public class SubscriptionStatus
{
[XmlRpcMember("AffiliateId")]
public int AffiliateId { get; set; }
[XmlRpcMember("AutoCharge")]
public int AutoCharge { get; set; }
[XmlRpcMember("BillingAmt")]
public double BillingAmt { get; set; }
[XmlRpcMember("BillingCycle")]
public string BillingCycle { get; set; }
[XmlRpcMember("CC1")]
public int CC1 { get; set; }
[XmlRpcMember("CC2")]
public int CC2 { get; set; }
[XmlRpcMember("ContactId")]
public int ContactId { get; set; }
[XmlRpcMember("EndDate")]
public DateTime EndDate { get; set; }
[XmlRpcMember("Frequency")]
public int Frequency { get; set; }
[XmlRpcMember("Id")]
public int Id { get; set; }
[XmlRpcMember("LastBillDate")]
public DateTime LastBillDate { get; set; }
[XmlRpcMember("LeadAffiliateId")]
public int LeadAffiliateId { get; set; }
[XmlRpcMember("MaxRetry")]
public int MaxRetry { get; set; }
[XmlRpcMember("MerchantAccountId")]
public int MerchantAccountId { get; set; }
[XmlRpcMember("NextBillDate")]
public DateTime NextBillDate { get; set; }
[XmlRpcMember("NumDaysBetweenRetry")]
public int NumDaysBetweenRetry { get; set; }
[XmlRpcMember("OriginatingOrderId")]
public int OriginatingOrderId { get; set; }
[XmlRpcMember("PaidThruDate")]
public DateTime PaidThruDate { get; set; }
[XmlRpcMember("PaymentGatewayId")]
public int PaymentGatewayId { get; set; }
[XmlRpcMember("ProductId")]
public int ProductId { get; set; }
[XmlRpcMember("ProgramId")]
public int ProgramId { get; set; }
[XmlRpcMember("PromoCode")]
public string PromoCode { get; set; }
[XmlRpcMember("Qty")]
public int Qty { get; set; }
[XmlRpcMember("ReasonStopped")]
public string ReasonStopped { get; set; }
[XmlRpcMember("ShippingOptionId")]
public int ShippingOptionId { get; set; }
[XmlRpcMember("StartDate")]
public DateTime StartDate { get; set; }
[XmlRpcMember("Status")]
public string Status { get; set; }
[XmlRpcMember("SubscriptionPlanId")]
public int SubscriptionPlanId { get; set; }
}
查看其返回的 IEnumerable 的 QuerySubscriptionStatus 签名。如果您再次查看实现 IDictionary、ICollection、IEnumerable 的 XmlRpcStruct (Fork of XML.Rpc.Net) 的定义。因此,如果我们假设 QuerySubscriptionStatus 正在返回实现 IEnumerable 的 XmlRpcStruct,那么您将获得 Enumeration 作为响应,它本质上是项目的集合(即使它包含单个项目)。您正在尝试将 Enumeration 类型转换为不是集合的结构 (SubscriptionStatus)。因此错误。
如果 Enumeration 中包含的项目属于 SubscriptionStatus 结构类型,那么下一行应该可以解决问题。
var resultList = subStatus.ToList<SubscriptionStatus();
然后遍历 resultList 以访问来自 QuerySubscriptionStatus 方法的响应。
foreach(var result in resultList)
{
}
或者如果您确定回复列表只有一个条目,那么您也可以使用以下内容
var result = resultList.FirstOrDefault();
希望对您有所帮助。
因此,在另一位高级开发人员的帮助下,我们能够对结构进行一些更改:
private string[] retFlds = { "Id", "ContactId", "OriginatingOrderId", "ProgramId", "SubscriptionPlanId", "ProductId", "StartDate", "NextBillDate", "BillingCycle", "Frequency", "BillingAmt", "Status", "ReasonStopped", "AutoCharge", "CC1", "CC2", "NumDaysBetweenRetry", "MaxRetry", "MerchantAccountId", "AffiliateId", "PromoCode", "LeadAffiliateId", "Qty", "ShippingOptionId" };
private string table = "RecurringOrder";
private DataTable dt = new DataTable();
// here's the query
XmlRpcStruct[] retData = proxy.Query(Auth.key, table, 1000, 0, qryData, returnFields);
dt = StructArrayToDT(retData);
public static DataTable StructArrayToDT(XmlRpcStruct[] data)
{
DataTable dt = new DataTable();
if (data.Length == 0) { return dt; }
// do columns
foreach (DictionaryEntry d in data[0])
{
dt.Columns.Add(d.Key.ToString(), typeof(object));
}
foreach (XmlRpcStruct xmlstruct in data)
{
DataRow dr = dt.NewRow();
foreach (DictionaryEntry d in xmlstruct)
{
try
{
dr[d.Key.ToString()] = d.Value;
}
catch (Exception ex)
{
// handle errors
}
}
dt.Rows.Add(dr);
}
return dt;
}
现在终于可以毫无问题地访问该数据了。
所以,我正在使用 CookComputings XMLRPC
库来与 InfusionSoft
交谈(这是一个非常流行的在线 CRM)。主要方法是:
[XmlRpcMethod("DataService.query")]
IEnumerable<object> QuerySubscriptionStatus(string apiKey,
string table, int limit, int page,
IDictionary queryData, string[] selectedFields);
很遗憾,我需要使用 IEnumerable<object>
,因为 InfusionSoft XML/RPC API 需要它。我希望不是这样,但遗憾的是。
自从我使用 .NET 4.5,我想我可以做一个动态转换:
var subStatus = proxy.QuerySubscriptionStatus(
_key, "RecurringOrder", 500, 0, dict, sarray);
var result = subStatus.Cast<SubscriptionStatus>();
不幸的是,这不起作用,我收到了一个来自 C# 的非常令人沮丧的错误:
Unable to cast object of type 'CookComputing.XmlRpc.XmlRpcStruct' to type 'WBI.Model.SubscriptionStatus'.`
我试过将我的 class 指定为 struct
;哎呀我什至尝试用 XMLRpcMember()
标签指定它,但是不,它只是不会转换。
如何与 IEnumerable
中的数据进行交互?
Class/Struct 我试过的类型
public struct SubStatus
{
public int AffiliateId;
public int AutoCharge;
public double BillingAmt;
public string BillingCycle;
public int CC1;
public int CC2;
public int ContactId;
public DateTime EndDate;
public int Frequency;
public int Id;
public DateTime LastBillDate;
public int LeadAffiliateId;
public int MaxRetry;
public int MerchantAccountId;
public DateTime NextBillDate;
public int NumDaysBetweenRetry;
public int OriginatingOrderId;
public DateTime PaidThruDate;
public int PaymentGatewayId;
public int ProductId;
public int ProgramId;
public string PromoCode;
public int Qty;
public string ReasonStopped;
public int ShippingOptionId;
public DateTime StartDate;
public string Status;
public int SubscriptionPlanId;
}
我也刚刚尝试了一个简单的 class 和 XMLRpcMember
标签:
public class SubscriptionStatus
{
[XmlRpcMember("AffiliateId")]
public int AffiliateId { get; set; }
[XmlRpcMember("AutoCharge")]
public int AutoCharge { get; set; }
[XmlRpcMember("BillingAmt")]
public double BillingAmt { get; set; }
[XmlRpcMember("BillingCycle")]
public string BillingCycle { get; set; }
[XmlRpcMember("CC1")]
public int CC1 { get; set; }
[XmlRpcMember("CC2")]
public int CC2 { get; set; }
[XmlRpcMember("ContactId")]
public int ContactId { get; set; }
[XmlRpcMember("EndDate")]
public DateTime EndDate { get; set; }
[XmlRpcMember("Frequency")]
public int Frequency { get; set; }
[XmlRpcMember("Id")]
public int Id { get; set; }
[XmlRpcMember("LastBillDate")]
public DateTime LastBillDate { get; set; }
[XmlRpcMember("LeadAffiliateId")]
public int LeadAffiliateId { get; set; }
[XmlRpcMember("MaxRetry")]
public int MaxRetry { get; set; }
[XmlRpcMember("MerchantAccountId")]
public int MerchantAccountId { get; set; }
[XmlRpcMember("NextBillDate")]
public DateTime NextBillDate { get; set; }
[XmlRpcMember("NumDaysBetweenRetry")]
public int NumDaysBetweenRetry { get; set; }
[XmlRpcMember("OriginatingOrderId")]
public int OriginatingOrderId { get; set; }
[XmlRpcMember("PaidThruDate")]
public DateTime PaidThruDate { get; set; }
[XmlRpcMember("PaymentGatewayId")]
public int PaymentGatewayId { get; set; }
[XmlRpcMember("ProductId")]
public int ProductId { get; set; }
[XmlRpcMember("ProgramId")]
public int ProgramId { get; set; }
[XmlRpcMember("PromoCode")]
public string PromoCode { get; set; }
[XmlRpcMember("Qty")]
public int Qty { get; set; }
[XmlRpcMember("ReasonStopped")]
public string ReasonStopped { get; set; }
[XmlRpcMember("ShippingOptionId")]
public int ShippingOptionId { get; set; }
[XmlRpcMember("StartDate")]
public DateTime StartDate { get; set; }
[XmlRpcMember("Status")]
public string Status { get; set; }
[XmlRpcMember("SubscriptionPlanId")]
public int SubscriptionPlanId { get; set; }
}
查看其返回的 IEnumerable 的 QuerySubscriptionStatus 签名。如果您再次查看实现 IDictionary、ICollection、IEnumerable 的 XmlRpcStruct (Fork of XML.Rpc.Net) 的定义。因此,如果我们假设 QuerySubscriptionStatus 正在返回实现 IEnumerable 的 XmlRpcStruct,那么您将获得 Enumeration 作为响应,它本质上是项目的集合(即使它包含单个项目)。您正在尝试将 Enumeration 类型转换为不是集合的结构 (SubscriptionStatus)。因此错误。 如果 Enumeration 中包含的项目属于 SubscriptionStatus 结构类型,那么下一行应该可以解决问题。
var resultList = subStatus.ToList<SubscriptionStatus();
然后遍历 resultList 以访问来自 QuerySubscriptionStatus 方法的响应。
foreach(var result in resultList)
{
}
或者如果您确定回复列表只有一个条目,那么您也可以使用以下内容
var result = resultList.FirstOrDefault();
希望对您有所帮助。
因此,在另一位高级开发人员的帮助下,我们能够对结构进行一些更改:
private string[] retFlds = { "Id", "ContactId", "OriginatingOrderId", "ProgramId", "SubscriptionPlanId", "ProductId", "StartDate", "NextBillDate", "BillingCycle", "Frequency", "BillingAmt", "Status", "ReasonStopped", "AutoCharge", "CC1", "CC2", "NumDaysBetweenRetry", "MaxRetry", "MerchantAccountId", "AffiliateId", "PromoCode", "LeadAffiliateId", "Qty", "ShippingOptionId" };
private string table = "RecurringOrder";
private DataTable dt = new DataTable();
// here's the query
XmlRpcStruct[] retData = proxy.Query(Auth.key, table, 1000, 0, qryData, returnFields);
dt = StructArrayToDT(retData);
public static DataTable StructArrayToDT(XmlRpcStruct[] data)
{
DataTable dt = new DataTable();
if (data.Length == 0) { return dt; }
// do columns
foreach (DictionaryEntry d in data[0])
{
dt.Columns.Add(d.Key.ToString(), typeof(object));
}
foreach (XmlRpcStruct xmlstruct in data)
{
DataRow dr = dt.NewRow();
foreach (DictionaryEntry d in xmlstruct)
{
try
{
dr[d.Key.ToString()] = d.Value;
}
catch (Exception ex)
{
// handle errors
}
}
dt.Rows.Add(dr);
}
return dt;
}
现在终于可以毫无问题地访问该数据了。