Connect to a web service using a mapped configuration file - c#

We have a CRM2011 plugin running async which needs to connect to a webservice to get some missing data. The way i'm trying to solve this is to use a webservice client, made using 'add service reference'.
But for configuration i don't want to hard code the endpoint and binding. So i thought i would just load the configuration for the webservice using OpenMappedExeConfiguration like so.
var config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap{ ExeConfigFilename = #"c:\Path\to\config.xml"}, ConfigurationUserLevel.None);
The config file is loaded... however it is not visible to the client. Because calling
var client = new MyDataServiceClient();
will throw
InvalidOperationException :
Could not find default endpoint element that references contract
'MyDataService.IMyDataService' in the ServiceModel client
configuration section. This might be because no configuration file
was found for your application, or because no endpoint element
matching this contract could be found in the client element.
The configuration file i'm using is:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyDataService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Ntlm" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="https://integrationservices-dev.thecompany.com/MyDataService/MyDataService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyDataService"
contract="MyDataService.IMyDataService"
name="BasicHttpBinding_IMyDataService" />
</client>
</system.serviceModel>
</configuration>
I know i could initialize a binding and endpoint and give those to the MyDataServiceClient(Binding, Endpoint) constructor. But i rather don't want to write my own configuration loader logic.
Is there a way to make the loaded config known to the code constructing the client? If not what other options are there ?

You are trying to read a exe configuration but you are on Web Context, I think you must use OpenWebConfiguration.
In short this command opens the Web-application configuration file as a Configuration object.
Alternatively you can add your configuration into web.config on CRM site
See this Stackoverflow article
See MSDN

Related

WCF throws error intermittently for the first time whenever I access if after a long time

WCF throws below error intermittently whenever I access the service for the first time in day or after long time.
"The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
Otherwise, it works fine in every case. I am not able to understand why this error occurs?
P.s : I have referred many threads and tried config changes,checked proxy mismatching, but none of them worked for me.
please guide me otherwise I have to put retry option in the service
Update
Client config
<endpoint address="xxxxx" binding="basicHttpBinding" bindingConfiguration="Binding1" contract="IService" name="BasicEndPoint" />
<binding name="Binding1" maxReceivedMessageSize="99999999"
closeTimeout="00:05:00" openTimeout="00:05:00"
sendTimeout="00:05:00" receiveTimeout="00:05:00" >
<readerQuotas maxStringContentLength="99999999" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm"/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<binding name="BasicEndPoint" closeTimeout="00:03:00" openTimeout="00:03:00"
receiveTimeout="00:10:00" sendTimeout="00:03:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
Service config:
<binding name="Binding1" maxReceivedMessageSize="99999999">
<readerQuotas maxStringContentLength="99999999" />
<security mode="None">
</security>
</binding>
Okey, I have had a lot of strange error messages during the time I have been working with WCF services. What I learned from that is that they do not alwats make that much sense.
When that said, when you describe yur problem, it sounds like one issue I had with one of the WCF services I have worked with that used named pipes. That was a problem related to the activation. Then I had to refresh the service address in the browser then it worked fine. To solve that it was a permission issue.
Anouther thing that have been gining me error messages is that the namespace and contract to the service is correct in the web.config.
When I was googling your error message, there seems like some people get this have issues with enum in the service. I do not think that's your issue, but maybe... WCF catches exception " The server did not provide a meaningful reply.."

.NET Web Service Using WEB CONFIG Settings Hard Coded Net TCP

I wanted to confirm something.
Below is how I am spinning up a call to my WCF web service in my ASP.NET application.
var xml = "my xml string";
var ep = new EndpointAddress("http://myendpoint");
xml = new Proxy.ServiceClient(new NetTcpBinding(), ep).getNewXML(new Proxy.CallContext(), xml);
My web config looks similar to below. My question is, even though these settings are in the web config, the fact that my calls above are newing up the a service client and fresh New TCP binding everytime tell me that these settings aren't being referenced. Is this correct based on above?
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_SCSService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://myendpoint"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_SCSService"
contract="Proxy.Service" name="NetTcpBinding_SCSService">
<identity>
<userPrincipalName value="user#user.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
That's correct. In this case, you are not using the configuration settings found in the config file.
Proxies typically derive from the abstract class ClientBase<T> which provides several different ways to create an instance of a client proxy. Some of the constructors listed will use all of the config file while others will attempt to use the config file to fill in the information that has not been explicitly supplied in the constructor. There are even constructor overloads which do not use the configuration file at all which ClientBase<TChannel>(Binding, EndpointAddress) is one of them.
If you wanted to use what was in the application configuration file, you could use:
var client = new Proxy.ServiceClient("NetTcpBinding_SCSService");

Call web services from event sink

I am using C# to build an event sink to monitor a specific exchange server inbox.
My implementation is based on this example: http://www.codeproject.com/KB/exchange/ManagedEventSinks.aspx?fid=382114&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx
Instead of the functionality described in the example i am trying to send some specific information to a web service.
I use visual studio to add the service reference to my class library and the following code to call the single method in the web service:
public void OnSave(IExStoreEventInfo pEventInfo, string bstrURLItem, int lFlags)
{
try
{
Message iMessage = new MessageClass();
iMessage.DataSource.Open(bstrURLItem, null,
ADODB.ConnectModeEnum.adModeRead,
ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
ADODB.RecordOpenOptionsEnum.adOpenSource, "", "");
string sub= iMessage.Subject;
string body = iMessage.HTMLBody;
MyWSSoapClient wsc = new MyWSSoapClient();
wsc.SingleMethodinWS(sub, body);
}
catch (Exception ex)
{
}
}
After i build the COM component and add the event sink to the inbox and test it i get the error:
Could not find default endpoint element that references contract 'MyWS.MyWSSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)
at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)
at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)
at System.ServiceModel.EndpointTrait`1.CreateSimplexFactory()
at System.ServiceModel.EndpointTrait`1.CreateChannelFactory()
at System.ServiceModel.ClientBase`1.CreateChannelFactoryRef(EndpointTrait`1 endpointTrait)
at System.ServiceModel.ClientBase`1.InitializeChannelFactoryRef()
at System.ServiceModel.ClientBase`1..ctor()
at ReplyParserEventSink.AnswerQuestionWS.AnswerQuestionWSSoapClient..ctor()
at ReplyParserEventSink.AsyncParser.OnSave(IExStoreEventInfo pEventInfo, String bstrURLItem, Int32 lFlags)
EDIT:
This is what i found in the app config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyWSSoap" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<endpoint address="http://127.0.0.1/MyProject/WebService/MyWS.asmx"
binding="basicHttpBinding" bindingConfiguration="MyWSSoap"
contract="MyWS.MyWSSoap" name="MyWSSoap" />
</system.serviceModel>
#Alexander: I tried what you said but i get the same error. Thanks
This is of course VS2010. Thing is with autogenerated code in app.config.
Check your app.config. This file contains all defenitions for bindings and endpoints. Just check you endpoints 1st, check whether your endpoint is described, and binding is defined too.
After that try:
MyWSSoapClient wsc = new MyWSSoapClient( "<endpointConfigurationName>" );
and see what would happen.
Also in <client> area you will find description of endpoints. Try to change binding to basicHttpBinding manually - that worked for me.
<endpoint address="http://service.address.com"
binding="basicHttpBinding" bindingConfiguration="yourService"
contract="Domain.Serice" name="serviceName" />
I am answering my own question because i have found and fixed the problem
The problem was that the information form the app.config file of the class library was not getting into the com component and therefore the error.
I fixed it by setting all my parameter values in my code from an external text file by following the example at: Consume a SOAP web service without relying on the app.config
Thanks for the suggestions everyone.

app.config being ignored?

I have read several posts where users were having this same issue. When compiled, the .exe is unable to load any resources from app.config. This is occurring even when the app.config is copied to the output directory.
Specifically, I'm having an issue with a web service client being unable to determine the proper endpoint configuration, even if I statically compile it in like this:
this.ws = new MyServicePortTypeClient("MyServicePort", "http://mysite.com/customer_portal/ws.php");
The exception thrown states "System.InvalidOperationException: Could not find default endpoint element that references contract 'MyWebService.MyServicePortType' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
I'm at a loss so any help would be appreciated.
Edit: Here's the MyService.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyServiceBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://mysite.com/customer_portal/ws.php"
binding="basicHttpBinding" bindingConfiguration="MyServiceBinding"
contract="MyWebService.MyServicePortType" name="MyServicePort" />
</client>
</system.serviceModel>
</configuration>
EXE is taking the settings from FileName.exe.config, not from App.config
The FileName.exe.config should be auto generated when compiling the code, and placed alongside the EXE itself.
Check the folder where you have the EXE.. do you see FileName.exe.config in there?
(Posted as answer due to length and formatting)
Well, I figured it out with the help from the information provided by everyone.
The issue is that installutil.exe is trying to use its own config, instead of the one created by the service. In this case, It's trying to load C:\Windows\Microsoft.NET\Framework\v2.0...\InstallUtil.config.
Now that I've figured that out, I can work with it and get it to work correctly.
Thanks, y'all!

Connecting to an asmx webservice with WCF through a proxy

Sorry answer found while typing
I am trying to connect to an external webservice that requires username/password authentication through a proxy. I am using Visual Studio Express 2008 to generate a service reference
I have connected to the same
webservice using a web reference.We
only had to set a larger timeout
because it takes a long time to
finish.
I have connected to another
webservice that does not require
username/password authentication
with a generated service reference
and some settings to get it through
the proxy.
So my thought would be to
take this reference, point it to the
correct webservice and add
authentication.
The config I am using without security:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy bypassonlocal="False" proxyaddress="http://***.***.****:80" />
</defaultProxy>
</system.net>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="AreaWebServiceSoap12">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://www.****.*****.****.com/samplewebservice/service.asmx"
binding="customBinding" bindingConfiguration="AreaWebServiceSoap12"
contract="ServiceReference1.ServiceSoap" name="ServiceSoap" />
</client>
</system.serviceModel>
</configuration>
I have added te following code to my call for authentication:
static void Main(string[] args)
{
ServiceSoapClient s = new ServiceSoapClient();
s.ClientCredentials.UserName.UserName = #"username";
s.ClientCredentials.UserName.Password = #"password";
Service.RawGpsData[] result = s.GetRawGpsData(0);
Console.WriteLine(String.Format("done:{0}",result.Length));
Console.ReadLine();
}
Just using this setup gives an error as expected:
The HTTP request is not authorized with client authentication scheme Anonymous. The authentication header from the server is received, is NTLM.
Now I get lost and start trying silly things because I am just starting to use WCF.
When I add the following section to the config
<security authenticationMode="UserNameOverTransport"></security>
I get the following error:
The binding CustomBinding.http: / / tempuri.org / for the contract AreaWebServiceSoap.AreaWebServices is configured with a verification mode for which a transport level with integrity and confidentiality is required. The transport can not provide integrity and confidentiality.
Sorry, while typing this question I stumbled upon the answer myself. I still think people might be interested in this and all comments and thoughts are still welcome. So I will leave the question here and make it community and post the answer myself.
Change the binding to :
<?xml version="1.0" encoding="utf-8" ?>
<customBinding>
<binding name="AreaWebServiceSoap12" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="00:20:00" sendTimeout="00:05:00">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Ntlm"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
So set authenticationScheme="Ntlm"
And here is how you can connect without proxy:
http://blog.bodurov.com/Create-a-WCF-client-for-asmx-web-service-without-using-web-proxy

Categories

Resources