因为公司的一个项目需要通过模拟POST请求来实现WCF的调用,WCF框架也是才接触没多久,只能是边学边做。
今天终于把所有环节都走通了,记录一下方便以后查阅,因此写了这篇随笔,也希望会对大家有点帮助。
- web.config中的相关配置
1 <?xml version="1.0" encoding="utf-8"?>
2 <configuration>
3 <system.serviceModel>
4 <services>
5 <service behaviorConfiguration="JHSoft.WCF.ServiceBehavior" name="JHSoft.WCF.POSTServiceForApp">
6 <endpoint address="" behaviorConfiguration="webHttp" binding="webHttpBinding"
7 name="post" contract="JHSoft.WCF.Contract.IPOSTServiceForApp"/>
8 <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
9 </service>
10 </services>
11 <behaviors>
12 <endpointBehaviors>
13 <behavior name="webHttp">
14 <webHttp />
15 <!--<enableWebScript />如果需要支持脚本调用请启用此项-->
16 </behavior>
17 </endpointBehaviors>
18 <serviceBehaviors>
19 <behavior name="JHSoft.WCF.ServiceBehavior">
20 <serviceMetadata httpGetEnabled="true"/>
21 <serviceDebug includeExceptionDetailInFaults="true"/>
22 </behavior>
23 </serviceBehaviors>
24 </behaviors>
25 <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
26 </system.serviceModel>
27 </configuration>
有几点需要特别说明一下:
1) <endpoint binding="webHttpBinding"
这里必须设置为webHttpBinding,否则不可以通过post调用。如果想通过Flex调用,必须设置为basicHttpBinding,因为
目前Flex只能支持SOAP1.1。创建wcf服务时默认的模式为wsHttpBinding,如果是通过添加服务代理模式调用就不需要进
行修改了。如果还有其他特殊的要求,比如说双工,可以设置其他的绑定模式。
2) <endpoint behaviorConfiguration="webHttp"
1 <endpointBehaviors>
2 <behavior name="webHttp">
3 <webHttp />
4 <!--<enableWebScript />-->
5 </behavior>
6 </endpointBehaviors>
启用<webHttp />,或者<enableWebScript />,如果只是想通过post方式调用wcf而不需要支持脚本调用可以只启用
<webHttp />,如果还希望能支持脚本调用就需要启用<enableWebScript />,但是可能存在跨越调用的问题。不过在实际测试的过程中发现,如果只启用<webHttp />返回的json数据格式为:{Error:0,ErrorMessage:"",UID:"1001"},
如果启用了<enableWebScript />返回的数据格式则会变为
{d:{__type:"User#WCF.App"Error:0,ErrorMessage:"",UID:"1001"}}
3)<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
启用ASP.NET兼容模式
- WCF服务中的配置
1)在接口契约的方法上增加属性
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
BackInfo Authorize(string sign);
RequestFormat = WebMessageFormat.Json 请求数据格式
ResponseFormat = WebMessageFormat.Json 回传数据格式
Method = "POST" 调用方式
BodyStyle = WebMessageBodyStyle.WrappedRequest 这里必须设置为WrappedRequest
2)在实现接口契约的类头部增加属性
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class POSTServiceForApp : IPOSTServiceForApp
开启ASP.NET兼容性
- POST调用
通过以上配置就可以实现POST调用了
public static string SendHttpRequest(string requestURI, string requestMethod, string json)
{
//json格式请求数据
string requestData = json;
//拼接URL
string serviceUrl = string.Format("{0}/{1}", requestURI, requestMethod);
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
//utf-8编码
byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(requestData);
//post请求
myRequest.Method = "POST";
myRequest.ContentLength = buf.Length;
//指定为json否则会出错
myRequest.ContentType = "application/json";
myRequest.MaximumAutomaticRedirections = 1;
myRequest.AllowAutoRedirect = true;
Stream newStream = myRequest.GetRequestStream();
newStream.Write(buf, 0, buf.Length);
newStream.Close();
//获得接口返回值,格式为: {"VerifyResult":"aksjdfkasdf"}
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
string ReqResult = reader.ReadToEnd();
reader.Close();
myResponse.Close();
return ReqResult;
}
1)myRequest.Method = "POST";
2)myRequest.ContentType = "application/json";
3)byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(requestData);
- 其他问题
1)测试的WCF的宿主是IIS6.0,在调用过程中曾经遇到过400错误,后来发现是因为IIS启用了“集成Window验证”。勾掉此项问题解决。
2)如果想通过服务代理模式调用WCF调用结束之后必须关闭管道,否则可能会因为连接过多无法释放造成服务无法调用。