如何通过Web References来访问WCF的服务

qldsrx 2011-09-14 10:06:54
一般都是通过Service References来访问WCF服务,现在尝试通过Web References来访问,但是始终不成功,VS中添加引用发现,总会在方法中对参数添加“参数名+Specified”这类命名的参数,改变了原来的方法声明,自然调用无响应,最终超时。
现在不知道是不是WCF端配置上有什么问题,就连最简单的无参数函数,都会改变方法,添加Specified后缀的参数,非常奇怪,使用Service References访问则一切正常,是否是WCF不支持Web References来访问来访问呢?如果不支持,又为何可以通过VS添加Web References的引用呢?
...全文
899 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
gen84912944 2011-11-10
  • 打赏
  • 举报
回复
额。各位大神 小弟新手。
在用WCF的时候,像楼主所说的一样 生成之后,更新引用 WCF把定义的方法多出了
public string GetData(int value, [System.Xml.Serialization.XmlIgnoreAttribute()] bool valueSpecified)

这种参数.
而且 我ref int code作为参数的话,方法传完 没有被赋值。
qldsrx 2011-09-16
  • 打赏
  • 举报
回复
这里有人提出了和我一样的问题,英文版,看起来比较吃力,不过总算让我测试通过了:http://social.msdn.microsoft.com/forums/en-US/wcf/thread/d2a9440d-0c5b-4dc3-8e0d-54a72f7b6ca2

不过关于那个自动添加Specified后缀参数的问题还是不解。

另外如果我要添加SOAP Header该如何操作?我的WINFORM的WCF中添加了继承IEndpointBehavior的自定义类,实现写入自定义的Header内容,但是WINCE的System.ServiceModel.Description命名空间下并没有IEndpointBehavior接口,找不到任何让我写入Header的地方(如果Web Reference可以写入Header也可以考虑),我在服务端判断了MessageHeaders中的用户信息,验证访问的安全性。
qldsrx 2011-09-16
  • 打赏
  • 举报
回复
前面的问题我解决了,basicHttpBinding是可以的,只不过添加引用后,还需要修改url,把localhost改为固定IP才行,我测试的时候有点混乱,忘记改了,使用wxHttpBinding的时候url设置倒是正确的,于是怎么试都失败。在有人确定basicHttpBinding是可以的情况下,再次反复测试,总算成功。

不过现在另一个问题比较麻烦,就是我#19楼所说的Header信息的传递,也许我说的不够具体,那么就用代码说明下,在WCF服务端方法中,可以用如下方法获取MessageHeaders:
MessageHeaders messageHeaderCollection = OperationContext.Current.IncomingMessageHeaders;

这个MessageHeaders里的信息,是客户端在发送请求时写入的,我在WINFORM的客户端访问接口里加入了Header信息,传递用户验证信息,以实现身份验证,但是WINCE的客户端却找不到任何地方让我加入,另外使用web reference添加的客户端,也不知道该如何加入这部分信息。
宝_爸 2011-09-16
  • 打赏
  • 举报
回复
我创建两个新的工程,好像没有问题啊
WCF config 除了改成basicHttpBinding,其他没变


<system.serviceModel>
<services>
<service name="TestWebReferenceOfWCF.Service1" behaviorConfiguration="TestWebReferenceOfWCF.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="TestWebReferenceOfWCF.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestWebReferenceOfWCF.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>


WCF Interface用的就是默认的

// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
[ServiceContract]
public interface IService1
{

[OperationContract]
string GetData(int value);

[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);

// TODO: Add your service operations here
}


// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";

[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}

[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}


WCF Service实现,也是默认的

public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}

public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}


客户端是winform,建立时选择.net2.0.然后add web reference..

调用时

private void button1_Click(object sender, EventArgs e)
{
Service1.Service1 client = new testclient.Service1.Service1();
string res = client.GetData(100, true);

MessageBox.Show(res);

string res2 = client.GetData(100, false);

MessageBox.Show(res2);


Service1.CompositeType para = new testclient.Service1.CompositeType();
para.StringValue = "aaa";
para.BoolValue = false;
para.BoolValueSpecified = true;
Service1.CompositeType res1 = client.GetDataUsingDataContract(para);
MessageBox.Show(res1.StringValue + " -- " + res1.BoolValueSpecified + " --- " + res1.BoolValue);
}

如果你需要我可以将我的测试工程发给你。

public string GetData(int value, [System.Xml.Serialization.XmlIgnoreAttribute()] bool valueSpecified)这个是说value值是否指定了。

估计还是服务器端的binding配置有问题。造成客户端生成proxy class是有些东西不认识。
我们还试过用WCF暴露soap1.1的接口,就像amsx一样,共Ruby的客户端调用,都没有问题。

宝_爸 2011-09-16
  • 打赏
  • 举报
回复
刚看懂。楼主用add web reference去添加多wcf的引用。
宝_爸 2011-09-16
  • 打赏
  • 举报
回复
WCF,我们用了很多啊,没啥问题啊。
  • 打赏
  • 举报
回复
我没有下载你的代码,我一般不下载别人的任何代码,除非是非常流行的开源项目。

我想你要搞清楚,WCF是对web service的极大的扩展。你要想保证web service去访问WCF这是本末倒置的,你应该是将WCF进行大多阔斧的简化和删除,才能适合web service。
qldsrx 2011-09-15
  • 打赏
  • 举报
回复
仔细研究了下自动创建的那个Reference.cs文件,会多出这些注释内容,看了下大致的意思,有两个WSDL元素无法解析,也就是MSDiscoCodeGenerator在自动创建代理类的时候,并没有正确识别这个服务说明,除非WCF的这个服务说明提供它能识别的格式,反正默认的格式将产生错误的代理类。
    // CODEGEN: The optional WSDL extension element 'PolicyReference' from namespace 'http://schemas.xmlsoap.org/ws/2004/09/policy' was not handled.
// CODEGEN: The optional WSDL extension element 'EndpointReference' from namespace 'http://www.w3.org/2005/08/addressing' was not handled.
qldsrx 2011-09-15
  • 打赏
  • 举报
回复
你确定是在我给的示例代码上,添加WEB引用后测试无问题吗?示例代码本身可正常运行,添加WEB引用,使用那个接口调用服务端方法则会有问题。如果说什么都不调整,肯定和我的测试结果一样,你改过什么了?再或者你只是在你自己的系统上测试,而没用我给的示例代码,那么一样没说明问题,因为我还是不知道WEB引用无法访问的原因,无故添加Specified后缀的参数的原因。
建议你先模拟出我描述的问题,然后再针对这问题来解释,而不是在自己的系统上说“没问题”。
q198708wyp 2011-09-15
  • 打赏
  • 举报
回复
http://www.cnblogs.com/artech/archive/2007/09/15/893838.html
给你关于WCF的网址你看下吧 希望对你有帮助 ,这上面资料很全
阿建像熊猫 2011-09-15
  • 打赏
  • 举报
回复
好使吧。我用WPF连过WCF。就和WEB service一样用的。


300分呀。真厉害呀。
  • 打赏
  • 举报
回复
不是wince不能访问,你要的根本就是web service而不是其它wcf实现的协议嘛。

如果在比较缓慢的设备上,如果直接通过http访问(WebClient类来访问)已经是性能极限了,不太去考虑什么wcf的问题。
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 qldsrx 的回复:]
basicHttpBinding已经试过,也不行,因为最初我要在WINCE上添加引用,WINCE只能支持basicHttpBinding,因此早就试过,后来用WINFORM试了下也无法使用WEB引用来访问WCF,于是就此一问。
不过现在WINCE访问WCF服务端的方法我也找到了,有一个工具叫NetCFSvcUtil.exe,可以生成代理类,用那个代理类复制到项目中,即可完美访问WCF服务端,但是……
[/Quote]

没办法,我只好用我们自己的系统来测试。不是BasicHttpBinding,而应该是 WSHttpBinding!我测试了,使用.net2.0平台来访问Wcf,一点问题也没有。

我们的系统中实现了Wcf,但是从来不启用其服务。实际上似乎只有当遇到从来没有做过通讯服务系统的人,才会被劝说要使用Wcf。

Wcf既大且慢,不是专门注重通讯过程的程序应该使用的。
qldsrx 2011-09-15
  • 打赏
  • 举报
回复
basicHttpBinding已经试过,也不行,因为最初我要在WINCE上添加引用,WINCE只能支持basicHttpBinding,因此早就试过,后来用WINFORM试了下也无法使用WEB引用来访问WCF,于是就此一问。
不过现在WINCE访问WCF服务端的方法我也找到了,有一个工具叫NetCFSvcUtil.exe,可以生成代理类,用那个代理类复制到项目中,即可完美访问WCF服务端,但是心中一个疙瘩,为啥就不能用WEB引用访问WCF呢?
  • 打赏
  • 举报
回复
[Quote=引用楼主 qldsrx 的回复:]
是否是WCF不支持Web References来访问来访问呢?如果不支持,又为何可以通过VS添加Web References的引用呢?[/Quote]

唉,又看了你下你的问题,看来只能瞎猜你的思路。你认为.net既然支持WCF,就应该在vs工具上取消添加Web References的引用的功能么?这明显不合逻辑啊。使用vs的开发人员能不添加web引用跟微软有没有开发过WCF技术有什么关系啊?

另外你自己的WCF如果要让web service客户端使用,那么应该将绑定方式设置为BasicHttp方式。
qldsrx 2011-09-15
  • 打赏
  • 举报
回复
看过你的服务声明了,那个服务本身就是Web Service服务,而不是WCF服务,所以添加Web Reference很正常,但是我说的服务是WCF服务啊,看http://www.webxml.com.cn/webservices/DomesticAirline.asmx的完整说明就知道不是WCF服务了,我这里也有Web Service的服务,测试下来也是正常的,所以还是请你试试WCF的代码来测试。
一句话,用Web Service的客户端访问WCF的服务端,低版本访问高版本,微软说WCF包含了Web Service,但实际这样访问却不可行,为啥?
  • 打赏
  • 举报
回复
没办法,我自己给你试了一下。创建一个.net2.0平台的项目,然后“Add Web Reference”添加它的客户端
http://www.webxml.com.cn/webservices/DomesticAirline.asmx?wsdl
我取名叫做air,接下来我就可以使用
air.DomesticAirline x = new air.DomesticAirline();
string test="Adfasd";
DataSet result = x.getDomesticAirlinesTime(test, test, test, test);

这样的代码访问了,没有见到你说的“改变了原来的方法名”的问题。
qldsrx 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sp1234 的回复:]
我的意思是你给出一个web service服务器端的url地址,然后让别人证明用vs来编写的客户端、自动生成的代理程序不支持你说的简短的方法名,或者无法访问web service服务。
[/Quote]
我没有挂在外网上,所以没法给出。再者服务端程序源代码都在里面了,还不好测试吗?那个服务端是自承载的,无需安装IIS就可以运行,只要你装过.net3.5即可(需要VS2005以上编译器编译下)
  • 打赏
  • 举报
回复
我的意思是你给出一个web service服务器端的url地址,然后让别人证明用vs来编写的客户端、自动生成的代理程序不支持你说的简短的方法名,或者无法访问web service服务。
qldsrx 2011-09-15
  • 打赏
  • 举报
回复
WCF服务就用微软的示例代码,我试过,一样不行。示例代码的话,MSDN帮助上面有下载。
不高兴自己找的话,这里上传了一个:http://wjy.xunlei.com/d/XVHVMLTKBOQE
这段WCF的示例代码,服务端和客户端都可正常运行,启动服务端的exe程序后,客户端访问测试正常,然后你只要在客户端项目上手动添加一个web引用(不过项目是NET2.0,你也看不到服务引用的选项)。之后使用这个web引用的接口,改写下客户端测试代码,你首先会发现,函数的参数被擅改了,然后是执行报超时错误,服务端无响应。
加载更多回复(5)

110,530

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧