如何使用WebRequest.Create发布对象?

时间:2013-10-18 13:10:38

标签: asp.net httpwebrequest webrequest

我正在使用Balanced Payments API并试图找出如何创建客户。

https://docs.balancedpayments.com/current/api.html?language=bash#creating-a-customer

地址作为对象传递,但我不熟悉如何传递除字符串以外的任何内容。这是我到目前为止成功传递名称和电子邮件地址的代码:

    Dim request As WebRequest = WebRequest.Create("https://api.balancedpayments.com/v1/customers")
    request.Method = "POST"

    ' get this information from settings in your web config.
    Dim userName As String = "API KEY GOES HERE"

    Dim credentials As String = Convert.ToString(userName & Convert.ToString(":"))
    request.Headers("Authorization") = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials))

    Dim postData As String = "name=John Doe&email=jdoe@domain.com"
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
    request.ContentType = "application/x-www-form-urlencoded"
    request.ContentLength = byteArray.Length
    Dim dataStream As Stream = request.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()

    Dim response As WebResponse = request.GetResponse()

    ' create a data stream.
    dataStream = response.GetResponseStream()

    ' create a stream reader.
    Dim reader As New StreamReader(dataStream)

    ' read the content into a string
    Dim serverResponse As String = reader.ReadToEnd()

    ' clean up.
    reader.Close()
    dataStream.Close()
    response.Close()

1 个答案:

答案 0 :(得分:2)

我偷看了API文档,从它的外观来看,你实际上并没有在请求中传递一个对象。您传递了一个标记/值对字符串列表。

以下摘自API文档,其中显示了创建银行帐户的示例:

curl https://api.balancedpayments.com/v1/bank_accounts \
    -u ak-test-oAm876JsVLRmHwrswIGZ1kaelufk8Cmy: \
    -d "routing_number=121000358" \
    -d "type=checking" \
    -d "name=Johann Bernoulli" \
    -d "account_number=9900000001"

为了理解这个例子,你需要curl的引用,找到here

-u传递用户ID“ak-test-oAm876JsVLRmHwrswIGZ1kaelufk8Cmy”,没有密码。

-d表示HTTP POST正文中的标记/值对。如您所见,有四行,每行代表一个银行帐户的一个属性。

因此,除非出现严重错误,否则以下代码应该这样做:

Dim postData As String = "routing_number=121000358&type=checking&name=Johann+Bernoulli&account_number=9900000001"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = byteArray.Length
Dim dataStream As Stream = request.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()

如果这对您不起作用,请发布有关此问题的其他详细信息。

顺便说一句,将一个结构良好的标签值对列表放在一起是一个技巧。如果使用ParseQueryString静态方法创建NameValueCollection,则它在内部创建为HttpValueCollection,可用于呈现查询字符串。看看:

Dim myCollection as NameValueCollection = HttpUtility.ParseQueryString(""); //Create empty collection
myCollection["routing_number"] = "121000358";
myCollection["type"] = "checking";
myCollection["name"] = "Johann Bernoulli";
myCollection["account_number"] = "99900000001";
Dim postData as String = myCollection.ToString();  //Magic!!
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)

当你的对象有很多属性和/或包含需要转义的数据时,这比自己构建字符串要容易得多。


使用JSON传递对象

API文档缺少任何演示对象传递的示例。似乎我们不得不猜测。 BOO!

我在网上讨论过,使用一种称为json string(JavaScript Object Notation)的格式来传递复杂数据结构似乎非常典型和标准的RESTful服务看起来像这样:

“地址”:{“line1”:“这是地址的第1行”,“城市”:“西雅图”,“州”:“WA”}

这是一个更多的elaborate example但我建议开始简单,以确保这是API想要的。

尝试按照此模式对一个简单的json字符串进行硬编码,并将其传递给服务,以查看它是否有效。

如果它成功,我们可以看看构建json的更简单方法。如果您使用的是.NET 4.5,请检查here。否则,您只需做更多的工作并实现自己的功能like this onethis article中所述。

但第一个技巧是验证我的猜测。这是一个非常好的猜测,因为Balanced Payments API在响应消息中使用了json(在示例中可以清楚地看到)。尝试一下,让我知道你发现了什么。


使用Balanced Payments API的有趣语法传递对象

好的,我一直在寻找那个API文档并找到good example of passing an object

curl https://api.balancedpayments.com/v1/marketplaces/TEST-MP5is34cQM5VCKcHcIfXxLGw/credits \
    -u ak-test-oAm876JsVLRmHwrswIGZ1kaelufk8Cmy: \
    -d "amount=10000" \
    -d "bank_account[routing_number]=121000358" \
    -d "bank_account[type]=checking" \
    -d "bank_account[name]=Johann Bernoulli" \
    -d "bank_account[account_number]=9900000001"

我从这个例子中推断,传递“对象”的方法是提供对象名称,并在方括号中逐个包含它的属性。

所以在你的情况下它应该是

Dim postData as String = "name=John Doe&address[line1]=123 Main St&address[city]=Baltimore&address[state]=MD&address[postal_code]=21224&email=jdoe@domain.com"

试一试。第三次是魅力?