我正在尝试使用 ksoap2 从 android 访问 wcf soap 服务中的方法。 我能够成功地将简单的类型参数传递给该方法,它工作正常。 但是当我尝试传递对象时,wcf 方法接收到的所有对象值都是 0。
我在 WP7 应用程序中使用了相同的 SOAP 服务,它运行良好。
我的服务中有 2 个方法,ksoapadd 和 addParam。 addParam 接受两个整数并返回它们的总和(这有效)。 ksoapadd 接受类 testadd 的一个对象,它有两个整数元素,ksoapadd 返回它们的总和(这获取并发送 0)。
我认为它与 namespace 有关,但我不知道如何解决它。我一直在反复试验以使 soap 请求正确,但还没有成功。
谁能帮我弄清楚该怎么做?我尝试了很多选择,这些选择以某种方式帮助了其他遇到类似问题但无济于事的人。
这是我的 wsdl:
<?xml version="1.0" encoding="UTF-8"?>
-<wsdl:definitions xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
xmlns:wsa10="http://www.w3.org/2005/08/addressing"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:tns="http://tempuri.org/"
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://tempuri.org/" name="Service1">
-<wsdl:types>
-<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import namespace="http://tempuri.org/" schemaLocation="http://localhost:51086/Service1.svc?xsd=xsd0"/>
<xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" schemaLocation="http://localhost:51086/Service1.svc?xsd=xsd1"/>
<xsd:import namespace="http://schemas.datacontract.org/2004/07/InsertIntoUserWCF" schemaLocation="http://localhost:51086/Service1.svc?xsd=xsd2"/>
</xsd:schema>
</wsdl:types>
-<wsdl:message name="IService1_ksoapAdd_InputMessage">
<wsdl:part name="parameters" element="tns:ksoapAdd"/>
</wsdl:message>
-<wsdl:message name="IService1_ksoapAdd_OutputMessage">
<wsdl:part name="parameters" element="tns:ksoapAddResponse"/>
</wsdl:message>
-<wsdl:message name="IService1_addParam_InputMessage">
<wsdl:part name="parameters" element="tns:addParam"/>
</wsdl:message>
-<wsdl:message name="IService1_addParam_OutputMessage">
<wsdl:part name="parameters" element="tns:addParamResponse"/>
</wsdl:message>
-<wsdl:portType name="IService1">
-<wsdl:operation name="ksoapAdd">
<wsdl:input message="tns:IService1_ksoapAdd_InputMessage" wsaw:Action="http://tempuri.org/IService1/ksoapAdd"/>
<wsdl:output message="tns:IService1_ksoapAdd_OutputMessage" wsaw:Action="http://tempuri.org/IService1/ksoapAddResponse"/>
</wsdl:operation>
-<wsdl:operation name="addParam">
<wsdl:input message="tns:IService1_addParam_InputMessage" wsaw:Action="http://tempuri.org/IService1/addParam"/>
<wsdl:output message="tns:IService1_addParam_OutputMessage" wsaw:Action="http://tempuri.org/IService1/addParamResponse"/>
</wsdl:operation>
</wsdl:portType>
-<wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
-<wsdl:operation name="InsertUserDetails">
<soap:operation style="document"
-<wsdl:operation name="ksoapAdd">
<soap:operation style="document" soapAction="http://tempuri.org/IService1/ksoapAdd"/>
-<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
-<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
-<wsdl:operation name="addParam">
<soap:operation style="document" soapAction="http://tempuri.org/IService1/addParam"/>
-<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
-<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
-<wsdl:service name="Service1">
-<wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1">
<soap:address location="http://localhost:51086/Service1.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
这是我的 xsd2:
<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/InsertIntoUserWCF"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.datacontract.org/2004/07/InsertIntoUserWCF"
elementFormDefault="qualified">
-<xs:complexType name="testadd">
-<xs:sequence>
<xs:element name="number_1" type="xs:int" minOccurs="0"/>
<xs:element name="number_2" type="xs:int" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:element name="testadd" type="tns:testadd" nillable="true"/>
</xs:schema>
这是我的 SOAP 要求:
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<ksoapAdd xmlns="http://tempuri.org/" id="o0" c:root="1">
<n0:num1 xmlns:n0="http://tempuri.org/">
<number_1>25</number_1>
<number_2>25</number_2>
</n0:num1>
</ksoapAdd>
</v:Body>
</v:Envelope>
SOAP react :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ksoapAddResponse xmlns="http://tempuri.org/">
<ksoapAddResult>0</ksoapAddResult>
</ksoapAddResponse>
</s:Body>
</s:Envelope>
这是我使用 ksoap2 的 java 代码:
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://10.0.2.2:51086/Service1.svc?wsdl";
private static final String SOAP_ACTION4 = "http://tempuri.org/IService1/ksoapAdd";
private static final String METHOD_NAME4 = "ksoapAdd";
private static final String SOAP_ACTION5 = "http://tempuri.org/IService1/addParam";
private static final String METHOD_NAME5 = "addParam";
try {
testadd numX = new testadd(25,25);
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME4);
PropertyInfo prop = new PropertyInfo();
prop.setNamespace(NAMESPACE);
prop.setName("num1");
prop.setType(numX.getClass());
prop.setValue(numX);
Request.addProperty(prop);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);
envelope.implicitTypes = true;
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug=true;
androidHttpTransport.call(SOAP_ACTION4, envelope);
Log.d(logtag + " request dump", androidHttpTransport.requestDump);
Log.d(logtag + " response dump", androidHttpTransport.responseDump);
final SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
final int num = Integer.parseInt(response.toString());
} catch (Exception e)
{
e.printStackTrace();
}
这是我的 java 类 testadd:
import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class testadd implements KvmSerializable{
int number1;
int number2;
testadd(){}
testadd(int a, int b){ number1 = a; number2 = b;}
@Override
public Object getProperty(int arg0) {
switch(arg0)
{
case 0:
return number1;
case 1:
return number2;
}
return null;
}
@Override
public int getPropertyCount() {
return 2;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
switch(arg0)
{
case 0:
arg2.type = PropertyInfo.INTEGER_CLASS;
arg2.name = "number_1";
break;
case 1:
arg2.type = PropertyInfo.INTEGER_CLASS;
arg2.name = "number_2";
break;
default:break;
}
}
@Override
public void setProperty(int arg0, Object value) {
switch(arg0)
{
case 0:
number1 = Integer.parseInt(value.toString());
break;
case 1:
number2 = Integer.parseInt(value.toString());
break;
default:
break;
}
}
}
服务代码:
<ServiceContract()> _
Public Interface IService1
<OperationContract()> _
Function ksoapAdd(ByVal num1 As testadd) As Integer
<OperationContract()> _
Function addParam(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
End Interface
<DataContract()> _
Public Class testadd
Private number1 As Integer
Private number2 As Integer
<DataMember()> _
Public Property number_1() As Integer
Get
Return number1
End Get
Set(ByVal value As Integer)
number1 = value
End Set
End Property
<DataMember()> _
Public Property number_2() As Integer
Get
Return number2
End Get
Set(ByVal value As Integer)
number2 = value
End Set
End Property
End Class
服务方式:
Public Function ksoapAdd(ByVal num1 As testadd) As Integer Implements IService1.ksoapAdd
MsgBox(num1.number_1)
Return num1.number_1 + num1.number_2
End Function
Public Function addParam(ByVal num1 As Integer, ByVal num2 As Integer) As Integer Implements IService1.addParam
MsgBox(num1 + num2)
Return num1 + num2
End Function
我知道这是很多代码,但它认为有必要了解整个画面。
谢谢!
最佳答案
我终于让它工作了!
原来我的 android ksoap2 代码不喜欢 WCF 在 SOAP 服务中设置的默认命名空间 (tempuri.org)。
我的猜测是,使用默认命名空间,请求信封无法将传递的 testadd 对象映射到服务中定义了 testadd 类的数据协定。通过为 WCF 服务中的服务契约(Contract)和数据契约(Contract)显式定义命名空间,这会更改/重新排列 wsdl 并使数据契约(Contract)可访问。
我按照本教程摆脱了 tempuri.org 命名空间- http://blogs.msdn.com/b/endpoint/archive/2011/05/12/how-to-eliminate-tempuri-org-from-your-service-wsdl.aspx
我在服务代码(VB)的适当位置添加了以下内容
<ServiceContract(Namespace:="http://wcfservicetest.org/Service1")> _
<DataContract(Namespace:="http://wcfservicetest.org/Service1")> _
<ServiceBehavior(Namespace:="http://wcfservicetest.org/Service1")> _
我将命名空间更改为“http://wcfservicetest.org/Service1”,并使用新命名空间在 android java 代码中编辑了 NAMESPACE 和 SOAP_ACTION。
这样做之后我得到了我想要的结果!
这是 soap 请求:
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<ksoapAdd xmlns="http://wcfservicetest.org/Service1" id="o0" c:root="1">
<n0:num1 xmlns:n0="http://wcfservicetest.org/Service1">
<number_1>25</number_1>
<number_2>25</number_2>
</n0:num1>
</ksoapAdd>
</v:Body>
</v:Envelope>
SOAP react :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ksoapAddResponse xmlns="http://wcfservicetest.org/Service1">
<ksoapAddResult>50</ksoapAddResult>
</ksoapAddResponse>
</s:Body>
</s:Envelope>
所以我建议任何其他使用 ksoap2 学习 SOAP 服务的人,不要使用默认命名空间,设置你自己的命名空间。我浪费了一个星期的时间来解决这个问题。
希望有一天这对某人有所帮助!!
关于android - 使用 ksoap2 将对象从 android 传递到 wcf soap 服务;它发送和接收 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12846149/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po