Как передать массив из Android в WCF?
Ну, то что из Android практически невозможно передать сложный тип веб-сервису на WCF, понятно. Ведь кроме Microsoft для Microsoft ничего не существует. Тут даже и вопросов никаких не возникает: "так надо". А вот почему нужны такие пляски с бубнами для передачи простого массива из приложения на Android в WCF-сервис, непонятно. Этот ваш любимый ksoap2 тоже не особо-то помогает в виде "из коробки". Приходится смотреть логи, сравнивать сообщения и подстраиваться. А что, замечательный способ разработки. Если некуда спешить.
Короче.
Полностью завершённый код C#, делающий то, что нужно
Теперь то же самое из Android. Просто так передать массив не получится, его надо передавать изощрённо (извращённо?). Потому что в противном случае WCF не сможет десериализовать сообщение.
Делай раз
1. Сделать вид, что передаём не какой-то там паршивый int[], но настоящий Объект! настоящего Класса! Со всеми атрибутами такого. А именно
2. Полный код "взрослого класса"
public class MyIds extends Vector implements KvmSerializable {
private static final long serialVersionUID = -1143242342342342265L;
@Override
public Object getProperty(int i) {
return this.get(i);
}
@Override
public int getPropertyCount() {
return this.size();
}
@Override
public void setProperty(int i, Object o) {
this.add(Integer.parseInt(o.toString()));
}
@Override
public void getPropertyInfo(int i, Hashtable hashtable, PropertyInfo propertyInfo) {
propertyInfo.name = "int";
propertyInfo.namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; propertyInfo.type = PropertyInfo.INTEGER_CLASS;
}
}
Самый цимес в жирной строчке. Хотите неприятно провести время - уберите её.
После этого вызов метода GetSomething в Android становится очень простым
3. public static int getSomething(int[] args)
{
final String MethodName = "GetSomething";
final String SoapAction = "http://mydomain.ru/MyService/IInterface/GetSomething";
SoapObject req = new SoapObject(Namespace, MethodName);
MyIds myIds = new MyIds();
for(Integer i : args)
myIds.add(i);
PropertyInfo pi = new PropertyInfo();
pi.setName("WCFParam");
pi.setValue(myIds);
pi.setType(myIds.getClass());
req.addProperty(pi);
SoapSerializationEnvelope se = getEnvelope(req);
SoapPrimitive p = initializeTransportAndCall(SoapAction, se);
if (null == p)
return 0;
return Integer.parseInt(p.toString());
}
Всё. WCF SOAP WS принимает массив целых чисел. Ну и дальше дело техники.
Короче.
Полностью завершённый код C#, делающий то, что нужно
class Program
{
static void Main(string[] args)
{
ServiceReference1.ServiceClient sr = new ServiceReference1.ServiceClien();
sr.GetSomething(new []{10, 20, 30});
sr.Close();
}
}
Вызывает и работает.Теперь то же самое из Android. Просто так передать массив не получится, его надо передавать изощрённо (извращённо?). Потому что в противном случае WCF не сможет десериализовать сообщение.
Делай раз
1. Сделать вид, что передаём не какой-то там паршивый int[], но настоящий Объект! настоящего Класса! Со всеми атрибутами такого. А именно
2. Полный код "взрослого класса"
public class MyIds extends Vector
private static final long serialVersionUID = -1143242342342342265L;
@Override
public Object getProperty(int i) {
return this.get(i);
}
@Override
public int getPropertyCount() {
return this.size();
}
@Override
public void setProperty(int i, Object o) {
this.add(Integer.parseInt(o.toString()));
}
@Override
public void getPropertyInfo(int i, Hashtable hashtable, PropertyInfo propertyInfo) {
propertyInfo.name = "int";
propertyInfo.namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"; propertyInfo.type = PropertyInfo.INTEGER_CLASS;
}
}
Самый цимес в жирной строчке. Хотите неприятно провести время - уберите её.
После этого вызов метода GetSomething в Android становится очень простым
3. public static int getSomething(int[] args)
{
final String MethodName = "GetSomething";
final String SoapAction = "http://mydomain.ru/MyService/IInterface/GetSomething";
SoapObject req = new SoapObject(Namespace, MethodName);
MyIds myIds = new MyIds();
for(Integer i : args)
myIds.add(i);
PropertyInfo pi = new PropertyInfo();
pi.setName("WCFParam");
pi.setValue(myIds);
pi.setType(myIds.getClass());
req.addProperty(pi);
SoapSerializationEnvelope se = getEnvelope(req);
SoapPrimitive p = initializeTransportAndCall(SoapAction, se);
if (null == p)
return 0;
return Integer.parseInt(p.toString());
}
Всё. WCF SOAP WS принимает массив целых чисел. Ну и дальше дело техники.
Комментариев нет:
Отправить комментарий