-2

我在键值对字符串中使用贝宝 NVP 和 NVP 响应

例子

TOKEN=EC-3XXXXXXXXXXX154J&BILLINGAGREEMENTACCEPTEDSTATUS=1&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2012-07-10T11:45:59Z&CORRELATIONID=ecf9bfe9b1168&ACK=Success&VERSION=64.0&BUILD=3242673&EMAIL=govind_1341920205_per@gmail.com&PAYERID=3V85HKW32SXKG&PAYERSTATUS=verified&FIRSTNAME=Govind&LASTNAME=Malviya&COUNTRYCODE=US&SHIPTONAME=Govind Malviya&SHIPTOSTREET=1 Main St&SHIPTOCITY=San Jose&SHIPTOSTATE=CA&SHIPTOZIP=95131&SHIPTOCOUNTRYCODE=US&SHIPTOCOUNTRYNAME=United States&ADDRESSSTATUS=Confirmed&CURRENCYCODE=USD&AMT=30.90&SHIPPINGAMT=0.00&HANDLINGAMT=0.00&TAXAMT=0.00&DESC=test EC payment&INSURANCEAMT=0.00&SHIPDISCAMT=0.00&PAYMENTREQUEST_0_CURRENCYCODE=USD&PAYMENTREQUEST_0_AMT=30.90&PAYMENTREQUEST_0_SHIPPINGAMT=0.00&PAYMENTREQUEST_0_HANDLINGAMT=0.00&PAYMENTREQUEST_0_TAXAMT=0.00&PAYMENTREQUEST_0_DESC=test EC payment&PAYMENTREQUEST_0_INSURANCEAMT=0.00&PAYMENTREQUEST_0_SHIPDISCAMT=0.00&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Govind Malviya&PAYMENTREQUEST_0_SHIPTOSTREET=1 Main St&PAYMENTREQUEST_0_SHIPTOCITY=San Jose&PAYMENTREQUEST_0_SHIPTOSTATE=CA&PAYMENTREQUEST_0_SHIPTOZIP=95131&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=US&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United States&PAYMENTREQUESTINFO_0_ERRORCODE=0PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Govind Malviya&PAYMENTREQUEST_0_SHIPTOSTREET=1 Main St&PAYMENTREQUEST_0_SHIPTOCITY=San Jose&PAYMENTREQUEST_0_SHIPTOSTATE=CA&PAYMENTREQUEST_0_SHIPTOZIP=95131&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=US&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United States&PAYMENTREQUESTINFO_0_ERRORCODE=0PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Govind Malviya&PAYMENTREQUEST_0_SHIPTOSTREET=1 Main St&PAYMENTREQUEST_0_SHIPTOCITY=San Jose&PAYMENTREQUEST_0_SHIPTOSTATE=CA&PAYMENTREQUEST_0_SHIPTOZIP=95131&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=US&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United States&PAYMENTREQUESTINFO_0_ERRORCODE=0

我想在强类型数据中反序列化它,就像 JavaScriptSerializer 对 json 字符串所做的那样。请不要使用字典提供解决方案我想避免使用魔术字符串,我可以在每个属性上添加属性。

我的课是

 public class GetExpressCheckoutDetailsResponse : IPaypalResponse
    {
        public string Token { get; set; }
        public string BillingAgreementAcceptedStatus { get; set; }
        public string CheckoutStatus { get; set; }
        public string Timestamp { get; set; }
        public string CorrelationID { get; set; }
        public Status Acknowledgement { get; set; }
        public string Version { get; set; }
        public string Build { get; set; }
        public string Email { get; set; }
        public string PayerID { get; set; }
        public string PayerStatus { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string CountryCode { get; set; }
        public string ShiptoName { get; set; }
        public string ShiptoStreet { get; set; }
        public string ShipToCity { get; set; }
        public string ShipToState { get; set; }
        public string ShipToZip { get; set; }
        public string ShipToCountryCode { get; set; }
        public string ShipToCountryName { get; set; }
        public string AddressStatus { get; set; }
        public string CurrencyCode { get; set; }
        public string Amount { get; set; }
        public string ShippingAmount { get; set; }
        public string HandlingAmount { get; set; }
        public string TaxAmount { get; set; }
        public string Description { get; set; }
        public string InsuranceAmount { get; set; }
        public string ShipdiscAmount { get; set; }
        public string PaymentRequestCurrencycode { get; set; }
        public string PaymentRequestAmount { get; set; }
        public string PaymentRequestShippingAmount { get; set; }
        public string PaymentRequestHandlingAmount { get; set; }
        public string PaymentRequestTaxAmount { get; set; }
        public string PaymentRequestDescription { get; set; }
        public string PaymentRequestInsuranceAmount { get; set; }
        public string PaymentRequestShipdiscAmount { get; set; }
        public string PaymentRequestInsuranceOptionOffered { get; set; }
        public string PaymentRequestShipToName { get; set; }
        public string PaymentRequestShipToStreet { get; set; }
        public string PaymentRequestShipToCity { get; set; }
        public string PaymentRequestShipToState { get; set; }
        public string PaymentRequestShipToZip { get; set; }
        public string PaymentRequestShipToCountryCode { get; set; }
        public string PaymentRequestShipToCountryName { get; set; }
        public string PaymentRequestInfoErrorCode { get; set; }
    }
4

4 回答 4

3

您可以使用 LINQ 将您的数据提取到一个Dictionary<TKey, TValue>然后您可以使用它来映射您的类中的数据,例如

var paypalResponse = "...";
var data = paypalResponse.Split('&') 
                         .Select(x => x.Split('=')) 
                         .ToDictionary(x => x[0], x => x[1]);

然后,您可以将其传递给您的GetExpressCheckoutDetailsResponse类的构造函数,甚至可以在其中执行此操作,例如

public class GetExpressCheckoutDetailsResponse : IPaypalResponse
{
    public GetExpressCheckoutDetailsResponse(Dictionary<string, string> data)
    {
        this.Token = data["TOKEN"];
        this.BillingAgreementAcceptedStatus = data["BILLINGAGREEMENTACCEPTEDSTATUS"];
        ...
    }
}

对这样的事情使用反射可能比它的价值更麻烦,因为您的属性不完全匹配,因此您需要为每个属性添加元数据属性。

于 2012-07-10T12:47:52.880 回答
2

您可以使用HttpUtility.ParseQueryString将您的字符串转换为NameValueCollection. 剩下的只是reflection

string responseString = "TOKEN=EC......";
var dict = HttpUtility.ParseQueryString(responseString);
GetExpressCheckoutDetailsResponse respObj = new GetExpressCheckoutDetailsResponse();
foreach (var p in respObj.GetType().GetProperties())
{
    p.SetValue(respObj, dict[p.Name]);
}

//respObj is ready to use
于 2012-07-10T18:31:38.473 回答
1

因此,由于您的问题没有现成的反序列化器,您应该执行以下操作:

  1. 向代表贝宝响应的每个属性添加属性。
  2. 反映类实例的属性并将它们缓存到 中Dictionary<string, PropertyInfo>,其中字符串是属性的值。
  3. 在贝宝响应中迭代"some string".Split(..)方法的结果,收集字符串和值,然后将它们存储到您应该在字典中查找的相应属性中。
于 2012-07-10T12:40:47.623 回答
0

在您的特定情况下,而不是重新发明轮子;你如何使用 PayPal SDK?

http://paypal.github.io/sdk/

您想要的是用于 C# 的 Express Checkout SDK

它已经具有正确数据类型所需的所有字段,并且具有在几个简单函数调用之后自动执行所有调用/解析响应的额外好处。

手动构建您自己的 API 调用并解析响应并不是解决此问题的最佳方法。当然,最终你会让它工作,但在你这样做之前,这将是一个耗时且容易出错的过程......

于 2012-07-11T04:13:22.643 回答