代码显示及其理由
首先说一下二者区别,自己在同时支持二者调用的去配置化时,一开始并没有觉得有多难,想的就是一个配置文件转代码形式,后来在写的过程中发现,是有区别的:js是传统的web形式,支持的是对应的json字符串的调用形式,而WCF后台的调用一般是支持BasicHttpBinding形式。二者的区别如下(此处只说一部分,更多的可以自行百度去了解一下):
webhttpbinding是REST风格的绑定,您只需点击一个URL,然后从Web服务中获取大量XML或JSON。
basichttpbinding和wshttpbinding是两个基于SOAP的绑定,与REST有很大的不同。SOAP的优势在于拥有WSDL和XSD来详细描述服务、其方法以及传递的数据(REST风格并不具备这种功能)。另一方面,您不能只使用浏览器浏览到wshttpbinding端点并查看XML(例如这种绑定的服务如果通过形如http://localhost:端口/testservice.svc的地址访问,将会报http400错误),您必须使用SOAP客户端,例如wcftestclient或您自己的应用程序。
basichttpbinding和wshttpbinding的区别如下:
basichttpbinding是非常基本的绑定-soap 1.1,在安全性方面不多,在功能方面不多,但与现有的任何SOAP客户机都兼容——>互操作性好,功能和安全性差。
wshttpbinding是一个全面的绑定,它支持大量的ws-*功能和标准-它有更多的安全功能,您可以使用会话连接,您可以使用可靠的消息传递,您可以使用事务控制,您可以使用流式处理大数据,但wshttpbinding也有点“笨重”并且当你的消息在网络中传输时,会有很多开销。
由于以上原因,那么你在写对应的同时支持的调用,就必须要有两种请求方式了,BasicHttpBinding与WebHttpBinding。不然,只用一种,另一种是会报错的。因为解决这个原因,自己花费了一天多时间。。。最后还是自己从基本支持格式考虑入手找到的。所以写下来总结一下,希望可以帮到大家。
详细代码附上
private void StartECGService()
{
try
{
string ECGServiceUrl = CommConfigHelper.CAServerIPInfo;//为了不与IIS部署的web应用重名,故用MedExECGCommunicationWCFService服务名
Uri address = new Uri(ECGServiceUrl);
m_WECGServiceHost = new ServiceHost(typeof(ServiceInterface.CAService), address);//实例化WCF服务对象
ServiceMetadataBehavior behaviour = m_WECGServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (behaviour == null)
behaviour = new ServiceMetadataBehavior();
//设置允许进行HttpGet操作。
behaviour.HttpGetEnabled = true;
//设置MetadataExporter导出Metadata时遵循WS-Policy 1.5规范。
behaviour.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
//将创建好的behaviour加入到宿主实例的行为描述组当中。
m_WECGServiceHost.Description.Behaviors.Add(behaviour);
m_WECGServiceHost.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex"
);
//Web请求节点
WebHttpBinding wsBinding = new WebHttpBinding();
wsBinding.CrossDomainScriptAccessEnabled = true;
wsBinding.MaxBufferPoolSize = int.MaxValue;
wsBinding.MaxBufferSize = int.MaxValue;
wsBinding.MaxReceivedMessageSize = int.MaxValue;
wsBinding.ReaderQuotas = new XmlDictionaryReaderQuotas()
{
MaxDepth = 64,
MaxArrayLength = int.MaxValue,
MaxBytesPerRead = int.MaxValue,
MaxNameTableCharCount = int.MaxValue,
MaxStringContentLength = int.MaxValue
};
//Basic请求节点
BasicHttpBinding bacBinding = new BasicHttpBinding();
bacBinding.MaxBufferPoolSize = int.MaxValue;
bacBinding.MaxBufferSize = int.MaxValue;
bacBinding.MaxReceivedMessageSize = int.MaxValue;
bacBinding.ReaderQuotas = new XmlDictionaryReaderQuotas()
{
MaxDepth = 64,
MaxArrayLength = int.MaxValue,
MaxBytesPerRead = int.MaxValue,
MaxNameTableCharCount = int.MaxValue,
MaxStringContentLength = int.MaxValue
};
//启动CA服务(bac服务添加)
m_WECGServiceHost.AddServiceEndpoint(typeof(Interface.ICAService),//契约(C)
bacBinding, //绑定(B)
ECGServiceUrl+"/Basic"); //地址(A)
//定义一个终结点行为
var endpointBehavior = new WebHttpBehavior();
endpointBehavior.AutomaticFormatSelectionEnabled = true;
endpointBehavior.DefaultOutgoingResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json;
//启动CA服务(web信息添加)
var end = m_WECGServiceHost.AddServiceEndpoint(typeof(Interface.ICAService),//契约(C)
wsBinding, //绑定(B)
ECGServiceUrl); //地址(A) + "Jweb"
//定义终结点行为
end.Behaviors.Add(endpointBehavior);
m_WECGServiceHost.Open();
ShowMsg(string.Format("CA服务启动成功:{0}", address));
}
catch (Exception ex)
{
string msg = string.Format("{0}服务启动异常:{1}", CommConfigHelper.ReadAppSettingsString("CAServerIPInfo"), ex.Message);
ShowMsg(msg);
LogHelper.Write(LogLevel.ERROR, "服务启动异常", msg);
MessageBox.Show(msg);
}
}
js部分代码
**参数加对应的请求地址,如果不加对应的WebHttpBinding形式,js一直报405不允许形式,这个很难受。因为BasicHttpBinding形式,js是不支持的,不过我在想其实应该也是可以的,如果进行类型互转,把wsdl转换成js,然后再返回去再转,但是这样就太麻烦了,并不建议。**
心得体会
一步一步排除,定位问题,才是最本质的解决办法,尤其是当你感觉无从下手的时候!