Передать параметр как объект []
Я хочу использовать этот API с приложением aC#: http://www.affjet.com/2012/11/26/4-4-affjet-api/
После добавления wsdl в мой проект я написал такой простой код: (getTransactions получает объект [] @params и возвращает строку)
Ws_ApiService service = new Ws_ApiService();
string apiKey = "*************";
var response = service.getTransactions(new object[] { apiKey });
Я попробовал еще несколько способов, но не смог получить правильный ответ, я попытался:
var response = service.getTransactions(new object[] { "apiKey:****"});
а также
var response = service.getTransactions(new object[] { "apiKey","******"});
Вот код php, который делает то же самое из своих документов:
<?php
$nameSpace = "https://secure.affjet.com/ws/api";
//Creating AffJet client for SOAP
$client = new SoapClient($nameSpace."?wsdl");
$pageNumber = 0;
//Setting up parameters
$params = array();
$params["apiKey"] = "MY_API_KEY";
//Value for parameters (optional)
//$params["networkId"] = array(1,2);
//$params["pageNumber"] = 0;
//$params["pageSize"] = 10;
//Making Request
$response = $client->getNetworks($params);
//XML to SimpleXMLElement Object
$xmlResponse = new SimpleXMLElement($response);
if ($xmlResponse->success == "true"){
while (isset($xmlResponse->dataList->data)) {
//Iterate the results
foreach ($xmlResponse->dataList->data as $data){
var_dump(xml2array($data));
}
//Requesting next page of data
$pageNumber++;
$params["pageNumber"] = $pageNumber;
//Making Request
$response = $client->getNetworks($params);
//XML to SimpleXMLElement Object
$xmlResponse = new SimpleXMLElement($response);
}
} else {
//Error somewhere
echo $xmlResponse->errorMessage;
}
/**
* Transforms the object SimpleXmlElement into an array, easier to handle
*/
function xml2array($xml) {
$arr = array();
foreach ($xml as $element) {
$tag = $element->getName();
$e = get_object_vars($element);
if (!empty($e)) {
$arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e;
} else {
$arr[$tag] = trim($element);
}
}
return $arr;
}
?>
это был ответ на то, что я пытался:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://secure.affjet.com/ws/api"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getTransactionsResponse>
<return xsi:type="xsd:string">
<response><success>false</success><errorMessage>
API Key not provided</errorMessage><dataList>
</dataList></response>
</return>
</ns1:getTransactionsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
ты можешь видеть:
API Key not provided
И ответ должен быть примерно таким:
<response>
<success>true</success>
<errorMessage></errorMessage>
<dataList>
<data>
<date>2012-11-05 15:02:41</date>//Transaction Date
<amount>81.67</amount>
<commission>15.86</commission>
<status>confirmed</status>//Status, could be: declined, pending, confirmed or paid
<clickDate></clickDate>
<ip></ip>
<custom_id>MyCustomId</custom_id>//Custom Id for the transactions (SID, SubId,clickRef....)
<unique_id>2548462</unique_id>//Unique Id given from the network to this transaction
<merchantId>1</merchantId>//Id for the Merchant on AffJet
<networkId>1</networkId>//Id for the Network on AffJet
</data>
</dataList>
</response>
все, что мне нужно предоставить, это параметр с именем "apiKey" и его значением
РЕДАКТИРОВАТЬ:
после обращения в службу поддержки они сказали, что запрос должен выглядеть так:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://secure.affjet.com/ws/api"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns2="http://xml.apache.org/xml-soap"
xmlns:SOAP- ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getTransactions>
<params xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">apiKey</key>
<value xsi:type="xsd:string">YOURAPIKEY</value>
</item>
</params>
</ns1:getTransactions>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Есть идеи?
3 ответа
Я углубился в эту увлекательную тему и должен сказать, что работа с ассоциативным массивом - это просто боль в реализации.NET SOAP. Ассоциативный массив представлен в виде IDictionary (например, Hashtable) - но отказывается от сериализации (попробуйте!).
Приведенный ниже код является наиболее близким, который я мог получить - и по какой-то причине (ошибка?) Он не работает на.NET Framework, но работает на Mono.
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Text;
public class Test
{
/*
* as per http://stackru.com/a/1072815/2348103
*/
public class Item
{
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public string key;
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public string value;
}
[SoapType(TypeName = "Map", Namespace = "http://xml.apache.org/xml-soap")]
public class Map : List<Item>
{
}
public static void Main()
{
Map map = new Map();
map.Add( new Item { key="foo", value="bar" } );
map.Add( new Item { key="quux", value="barf" } );
XmlTypeMapping mapping =
(new SoapReflectionImporter()).ImportTypeMapping( map.GetType() );
XmlSerializer serializer = new XmlSerializer( mapping );
XmlTextWriter writer = new XmlTextWriter( System.Console.Out );
writer.Formatting = Formatting.Indented;
writer.WriteStartElement( "root" );
serializer.Serialize( writer, map );
writer.WriteEndElement();
writer.Close();
}
}
/*
//
// does not work - but see http://msdn.microsoft.com/en-us/magazine/cc164135.aspx
//
public class Map : IXmlSerializable
{
const string NS = "http://xml.apache.org/xml-soap";
public IDictionary dictionary;
public Map()
{
dictionary = new Hashtable();
}
public Map(IDictionary dictionary)
{
this.dictionary = dictionary;
}
public void WriteXml(XmlWriter w)
{
w.WriteStartElement("Map", NS);
foreach (object key in dictionary.Keys)
{
object value = dictionary[key];
w.WriteStartElement("item", NS);
w.WriteElementString("key", NS, key.ToString());
w.WriteElementString("value", NS, value.ToString());
w.WriteEndElement();
}
w.WriteEndElement();
}
public void ReadXml(XmlReader r)
{
r.Read(); // move past container
r.ReadStartElement("dictionary");
while (r.NodeType != XmlNodeType.EndElement)
{
r.ReadStartElement("item", NS);
string key = r.ReadElementString("key", NS);
string value = r.ReadElementString("value", NS);
r.ReadEndElement();
r.MoveToContent();
dictionary.Add(key, value);
}
}
public System.Xml.Schema.XmlSchema GetSchema() { return null; }
}
*/
Пример вывода из Mono:
<q1:Map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1" d2p1:arrayType="Item[2]" xmlns:d2p1="http://schemas.xmlsoap.org/soap/encoding/" xmlns:q1="http://xml.apache.org/xml-soap">
<Item href="#id2" />
<Item href="#id3" />
</q1:Map>
[...]
Пример вывода из.NET:
<q1:Array xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1" q1:arrayType="Item[2]" xmlns:q1="http://schemas.xmlsoap.org/soap/encoding/">
<Item href="#id2" />
<Item href="#id3" />
</q1:Array>
[...]
Либо вы можете использовать класс пары KeyValue или класс Dictionary следующим образом:
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("apiKey", "******");
var response = new object[] { d };
KeyValuePair<string, string> d = new KeyValuePair<string, string>("apiKey", "******");
var response = new object[] { d };
Похоже, проблема заключается в разнице между массивами в PHP и C#. В PHP это пара ключ-значение. Как он выглядит в сгенерированном классе, который был создан из wdsl? Вот строка к такому вопросу, который связан с вашей проблемой. C# эквивалент PHP ассоциативного массива Один ответ говорит, чтобы попробовать Dictionary<String, String>
, Может быть стоит попробовать использовать KeyValuePair<String, String>
передается как массив объектов.
KeyValuePair<String, String> parm = new KeyValuePair<String, String>("apiKey","******");
var response = service.getTransactions(new object[] { parm });