我已经阅读了100多篇文章和答案我什么都没有,所以希望你能帮忙(对不起,如果我找不到合适的文章,即使它存在)。
我有一个包含4个SOAP端点服务引用的类库(.NET Framework)。如果它很重要 - 端点是一个黑盒子,我只需要wsdl,我需要连接那里。
库是由.exe加载的,我无法更改,所以即使我尝试使用app.config,我也不能(问题已知),因为它应该添加到.exe配置中,所以我使用那些参考,但我自己创建一个绑定,并使用ChannelFactory作为代理来调用Web方法。我尝试了这三种类型 - BasicHttpBinding,BasicHttpsBinding和BasicHttpContextBinding。所有绑定属性与引用生成的app.config中的相同。 从端点调用方法后,我收到了一条消息,这在SO上非常流行:
内容类型text / html;响应消息的charset = utf-8与绑定的内容类型不匹配(text / xml; charset = utf-8)。如果使用自定义编码器,请确保正确实现IsContentTypeSupported方法
但是这个问题的答案对我没有帮助,因为我收到此错误的原因是因为请求而不是SOAP是以下HTML:
<head>
<script>
var title = "<title>" + location.host + " - webMethods Integration Server" + "</title>";
document.write(title);
</script>
<LINK REL="SHORTCUT ICON" HREF="/favicon.ico">
</head>
<frameset rows="100%,*" border=0><frame src="/WmRoot/index.dsp"></frameset>
<noframes>
<body>
<h4>
Your browser does not support frames. Support for frames is required to use the webMethods Integration Server.
</h4>
</blockquote>
</body>
</noframes>
我也尝试自己创建SOAP信封并直接连接到服务器而没有服务引用,但我得到了相同的消息。
然而,如果我尝试从SaopUI连接,我得到适当的回应。
我做错了什么?
@EDIT:添加代码@Tim问
我的代码 - 两种方式,都响应相同......
我从引用的服务类型的类中调用一个方法(我合并了2个方法,因为最初在我的代码中它分为创建客户端然后打开并调用方法 - 这是另一部分应用程序,但它与此类似:)
public virtual FindCustResponse FindCust (FindCustRequest customer)
{
FindCustResponse result = null;
Services.FindCustomer.findCustomer_WSD_PortTypeClient client = null;
client = new Services.FindCustomer.findCustomer_WSD_PortTypeClient(FindCustomerHTTPsBinding(), GetServiceEndpoint(_serviceConfigProvider.
RemoteAddress));
if (client != null)
{
try
{
ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = _serviceConfigProvider.User;
loginCredentials.UserName.Password = _serviceConfigProvider.Password;
var defaultCredentials = client.Endpoint.Behaviors.Find<ClientCredentials>();
client.Endpoint.Behaviors.Remove(defaultCredentials);
client.Endpoint.Behaviors.Add(loginCredentials);
client.Open();
result = client.findCustomer(customer);
}
catch (Exception ex)
{
//Logging
}
finally
{
if (client.State == CommunicationState.Opened || client.State == CommunicationState.Opening)
{
client.Close();
}
}
}
return client;
}
另一种方式 - 使用ChannelFacotry
public virtual Services.FindCustomer.ImyService_WSD_PortType FindCustClient()
{
var client = new ChannelFactory<Services.FindCustomer.IMyService_WSD_PortType (FindCustomerHTTPsBinding(), GetServiceEndpoint(_serviceConfigProvider.RemoteAddress));
ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = _serviceConfigProvider.User;
loginCredentials.UserName.Password = _serviceConfigProvider.Password;
var defaultCredentials = client.Endpoint.Behaviors.Find<ClientCredentials>();
client.Endpoint.Behaviors.Remove(defaultCredentials);
client.Endpoint.Behaviors.Add(loginCredentials);
var proxy = client.CreateChannel();
return proxy;
}
public FindCustResponse1 FindCust (FindCustRequest1 customer)
{
var customerresults = _service.FindCustClient().findCustomer(customer);
return customerresults;
}
我在两种情况下都试过的约束力:
public virtual BasicHttpContextBinding FindCustomerContextBinding()
{
var binding = new BasicHttpContextBinding
{
ContextManagementEnabled = true,
MessageEncoding = WSMessageEncoding.Text,
TextEncoding = System.Text.Encoding.UTF8,
SendTimeout = TimeSpan.FromMinutes(1),
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
TransferMode = TransferMode.Buffered,
Security = { Mode = BasicHttpSecurityMode.Transport },
Name = ConfigConstants.FindCustomerBinding
};
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
return binding;
}
public virtual System.ServiceModel.BasicHttpsBinding FindCustomerHTTPsBinding()
{
var binding = new BasicHttpsBinding
{
TextEncoding = System.Text.Encoding.UTF8,
SendTimeout = TimeSpan.FromMinutes(1),
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard, // tried both - with and without
TransferMode = TransferMode.Buffered,
Security = { Mode = BasicHttpsSecurityMode.Transport },
Name = ConfigConstants.FindCustomerBinding
};
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
return binding;
}
public virtual BasicHttpBinding FindCustomerBasicBinding()
{
var binding = new BasicHttpBinding
{
TextEncoding = System.Text.Encoding.UTF8,
SendTimeout = TimeSpan.FromMinutes(1),
TransferMode = TransferMode.Buffered,
Security = { Mode = BasicHttpSecurityMode.Transport },
// Tried alsow with: TransportWithMessageCredential, Message = { ClientCredentialType = BasicHttpMessageCredentialType.UserName}
Name = ConfigConstants.FindCustomerBinding,
};
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
return binding;
}
这是我获取端点地址的方式:
public virtual EndpointAddress GetServiceEndpoint(string address)
{
if (!Uri.IsWellFormedUriString(address, UriKind.Absolute)) {return null;}
var uri = new Uri(address);
var endpoint = new EndpointAddress(uri.AbsoluteUri);
return endpoint;
}
我生成的app.config(我没有按照我的提议使用)是:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SomeBindingname_GET_Binder">
<security mode="Transport"/>
</binding>
<binding name="SomeBindingname_GET_Binder1"/>
<binding name="SomeBindingname_ADD_Binder">
<security mode="Transport"/>
</binding>
<binding name="SomeBindingname_ADD_Binder1"/>
<binding name="SomeBindingname_UPDATE_Binder">
<security mode="Transport"/>
</binding>
<binding name="SomeBindingname_UPDATE_Binder1"/>
<binding name="SomeBindingname_FIND_Binder">
<security mode="Transport"/>
</binding>
<binding name="SomeBindingname_FIND_Binder1"/>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://myServiceAddress:11111/ws/veryLongNameGETCustomer" binding="basicHttpBinding" bindingConfiguration="SomeBindingname_GET_Binder" contract="GetCustomer.getCustomer_WSD_PortType" name="getCustomer_WSD_Port"/>
<endpoint address="https://myServiceAddress:11111/ws/veryLongNameAddCustomer" binding="basicHttpBinding" bindingConfiguration="SomeBindingname_ADD_Binder" contract="AddCustomer.addCustomer_WSD_PortType" name="addCustomer_WSD_Port"/>
<endpoint address="https://myServiceAddress:11111/ws/veryLongNameUpdateCustomer" binding="basicHttpBinding" bindingConfiguration="SomeBindingname_UPDATE_Binder" contract="UpdateCustomer.updateCustomer_WSD_PortType" name="updateCreateCustomer_WSD_Port"/>
<endpoint address="https://myServiceAddress:11111/ws/veryLongNameFindCustomer" binding="basicHttpBinding" bindingConfiguration="SomeBindingname_FIND_Binder" contract="FindCustomer.findCustomer_WSD_PortType" name="findCustomer_WSD_Port"/>
</client>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/></startup></configuration>