I am wondering if anyone has encountered this same error, and if so, can point me in the right direction to try and fix it. The error reads:
Value cannot be null. Parameter name: key.
It seems like this error can stem from many different things.
I am trying to send data that is read from a CSV file to a SOAP web service. Below is the code I am using in the script task:
BasicHttpBinding CostCenterSoap = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
EndpointAddress remoteAddress = new EndpointAddress("https://example.com/services/CostCenter.asmx");
CostCenterSoapClient client = new CostCenterSoapClient(CostCenterSoap, remoteAddress);
CostCenterProperties[] costcenters = new CostCenterProperties[list.Count];
for (var c = 1; c < list.Count; c++) {
costcenters[c] = new CostCenterProperties
{
InteropID = list[c].CostCenter,
CompanyInteropID = companyInteropID,
Name = list[c].CostCenter,
Description = list[c].CostCenter
};
try
{
client.Save(CostCenters: costcenters, SharedSecret: sharedSecret);
}
catch (Exception e)
{
errorList.Add(e.Message);
MessageBox.Show("Errors from adding cost center: " + e.Message);
}
}
What is even more confusing is that this same logic works perfectly fine for another web service in another script task. When using SoapUI to test, I can pass data to the web service just fine, so the issue must be reside with my script.
Screenshot of error from the StackTrace:
Here is my app.config file that is part of my script task:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy useDefaultCredentials="true">
<proxy usesystemdefault="True" bypassonlocal="True"/>
</defaultProxy>
</system.net>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="CostCenterSoap">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://www.example.com/services/CostCenter.asmx"
binding="basicHttpBinding" bindingConfiguration="CostCenterSoap"
contract="CostCenterService.CostCenterSoap" name="CostCenterSoap" />
</client>
</system.serviceModel>
</configuration>
Related
I have made a C#-project where I am trying to connect to my Business Central cloud sandbox.
In Business Central, I have made an extension with a new codeunit, which has a function that I call "MHSTest". It just returns a text.
In Visual Studio, I have made the service reference that connects to the SOAP URL in Business Central. So I can see the name of my function, "MHSTest", in Visual Studio.
When I write this in Visual Studio, I get an error, because it tries to connect anonymously:
var client = new MHSTest.CSharpCodeunit_PortClient();
myTextBox.Text = client.MHSTest();
If I try the below instead, I get an error message saying that "https" is not valid. It has to be "http".
string endpoint = "">api.businesscentral.dynamics.com/.../CSharpCodeunit";
var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.MaxBufferSize = 999999;
binding.MaxReceivedMessageSize = 999999;
var client = new MHSTest.CSharpCodeunit_PortClient(binding, new EndpointAddress(endpoint));
myTextBox.Text = client.MHSTest();
How do I connect to Business Central and get (or set) data?
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Debitorer_Binding">
<security mode="Transport" />
</binding>
<binding name="Debitorer_Binding1" />
<binding name="CSharpCodeunit_Binding">
<security mode="Transport" />
</binding>
<binding name="CSharpCodeunit_Binding1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="api.businesscentral.dynamics.com/.../2999befa-1255-4304-a79a-67de0e24f090/Sandbox/WS/CRONUS%20Danmark%20A%252FS/Page/Debitorer?tenant=msneua5672t92712555&aid=FIN"
binding="basicHttpBinding" bindingConfiguration="Debitorer_Binding"
contract="BCCustomer.Debitorer_Port" name="Debitorer_Port" />
<endpoint address="api.businesscentral.dynamics.com/.../2999befa-1255-4304-a79a-67de0e24f090/Sandbox/WS/CRONUS%20Danmark%20A%252FS/Codeunit/CSharpCodeunit?tenant=msneua5672t92712555&aid=FIN"
binding="basicHttpBinding" bindingConfiguration="CSharpCodeunit_Binding"
contract="MHSTest.CSharpCodeunit_Port" name="CSharpCodeunit_Port" />
</client>
</system.serviceModel>
</configuration>
The problem is solved. I just needed to add this code after defining my client variable:
System.ServiceModel.Security.UserNamePasswordClientCredential cre = client.ClientCredentials.UserName;
cre.UserName = " ";
cre.Password = " ";
Use the Export-NAVData cmdlet to export data from a Business Central database. You can export company-specific data, and you can choose to include global data, application data, and application objects. When you export data from a Business Central database, the data is stored in a file with the extension .
I'm trying to configure a script component with a service reference to my WSDL file inside this boiler plate method.
public override void CreateNewOutputRows()
{
//create instance of service client
}
However I'm running into problems with the configuration file app.config which is complaining about an invalid contract attribute contract="ServiceReference1.IClientService1
All attempts to change this manually have failed. Similar posts suggest using a fully qualified name Service.MyService but I'm not having any success so far. Is there a way to specify the binding programmatically?
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IClientService1">
<security mode="Transport" />
</binding>
<binding name="BasicHttpBinding_IClientService11" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://server/services/ClientService1.svc/soap"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IClientService1"
contract="ServiceReference1.IClientService1" name="BasicHttpBinding_IClientService1" />
</client>
</system.serviceModel>
</configuration>
Stub code looks like following
public override void CreateNewOutputRows()
{
string endpoint = "https://server/services/ClientService1.svc";
ClientService1Client client = new ClientService1Client(endpoint);
client.ClientCredentials.UserName.UserName = "";
client.ClientCredentials.UserName.Password = "";
Output0Buffer.name = client.GetActiveClients()[1].name.ToString();
}
I believe your issue may be due to having /soap in your endpoint address
<endpoint address="https://server/services/ClientService1.svc/soap"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IClientService1"
contract="ServiceReference1.IClientService1" name="BasicHttpBinding_IClientService1" />
I think it should just be:
address="https://server/services/ClientService1.svc"
As for creating the binding programmatically this should work or get you started:
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
EndpointAddress address = new EndpointAddress("https://server/services/ClientService1.svc");
ClientService1Client client = new ClientService1Client(binding, address);
I have several web services that I am connecting to from a Visual Studio C# project using service references. Two of the service references were created and work without a problem, and one of them took quite a lot of effort to get imported, and now seems to not be working.
I believe the problem lies in the app.config file since it is getting a "Could not find endpoint element" error when I try to create the client.
Here is the app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="RateQuoteSoap">
<security mode="Transport" />
</binding>
<binding name="RateQuoteSoap1" />
<binding name="QuoteSoap" />
<binding name="WebservicePrimusSoapBinding" />
</basicHttpBinding>
<customBinding>
<binding name="QuoteSoap12">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint
address="https://webservices.rrts.com/rating/ratequote.asmx"
binding="basicHttpBinding"
bindingConfiguration="RateQuoteSoap"
contract="RoadRunnerService.RateQuoteSoap"
name="RateQuoteSoap" />
<endpoint
address="http://services.echo.com/Quote.asmx"
binding="basicHttpBinding"
bindingConfiguration="QuoteSoap"
contract="EchoService.QuoteSoap"
name="QuoteSoap" />
<endpoint
address="http://services.echo.com/Quote.asmx"
binding="customBinding"
bindingConfiguration="QuoteSoap12"
contract="EchoService.QuoteSoap"
name="QuoteSoap12" />
<endpoint
address="http://api.shipprimus.com/"
binding="basicHttpBinding"
bindingConfiguration="WebservicePrimusSoapBinding"
contract="PrimusService.WebservicePrimusServicePort"
name="WebservicePrimusServicePort" />
</client>
</system.serviceModel>
</configuration>
The PrimusService is the one that is not working correctly, and the full error when I try to initialize the client like WebservicePrimusServicePortClient serviceClient = new WebservicePrimusServicePortClient("WebservicePrimusServicePort"); is
System.InvalidOperationException: Could not find endpoint element with name 'WebservicePrimusServicePort' and contract 'PrimusService.WebservicePrimusServicePort'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 name could be found in the client element.
I have also tried to simply initialize a BasicHttpBinding object using the binding name and the endpoint name with no luck (short variable names for readability)
BasicHttpBinding a = new BasicHttpBinding("QuoteSoap"); // Works fine
BasicHttpBinding b = new BasicHttpBinding("WebservicePrimusSoapBinding"); // Fails
BasicHttpBinding c = new BasicHttpBinding("WebservicePrimusServicePort"); // Fails
It throws no error for binding a, but binding b and c fail with the error:
System.Collections.Generic.KeyNotFoundException: No elements matching the key 'WebservicePrimusSoapBinding' were found in the configuration element collection.
While not a direct solution, I ended up just taking the information from the app.config and creating my own BasicHttpBinding and EndpointAddress objects in code. This is more of a workaround than a fix for the problem, and I still don't know why I couldn't access the information in the app.config directly.
I followed the solution in this answer about how to consume a service without using the app.config file.
I created my BasicHttpBinding like
BasicHttpBinding binding = new BasicHttpBinding();
binding.Name = "PrimusServiceBinding"; // Completely Unnecessary
and my endpoint like
EndpointAddress endpoint = new EndpointAddress("http://api.shipprimus.com/");
and could connect to the service and retrieve information without a problem, even providing as little information as I did (basically just the address).
I'm new to .NET and have been following this tutorial (http://johnwsaunders3.wordpress.com/2009/05/17/how-to-consume-a-web-service/) to consume a simple weather web service. My small console application essentially asks the user for a ZIP code, fires that to the web service then returns to response in the console. At least, that's the way it should work.
The web service I am using is:
http://wsf.cdyne.com/WeatherWS/Weather.asmx
The problem with this is there are multiple endpoints for different ways of consuming the service:
SOAP 1.1
SOAP 1.2
HTTP GET
HTTP POST
Because of this, when I run the console application, I am presented with the following error:
Unhandled Exception: System.InvalidOperationException: An endpoint configuration section for contract 'Service1Reference.WeatherSoap'
could not be loaded because more than one endpoint configuration for that contract was found. Please indicate the preferred endpoint configuration section by name.
My question is, how do I specify that my call to the web service should use one of the SOAP endpoints?
My code so far can be found below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoleApplication1.Service1Reference;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("Enter ZipCode: ");
var line = Console.ReadLine();
if (line == null)
{
return;
}
WeatherSoapClient svc = null;
bool success = false;
try
{
svc = new WeatherSoapClient();
var request = line;
var result = svc.GetCityForecastByZIP(request);
Console.WriteLine("The result is:");
Console.WriteLine(result);
Console.Write("ENTER to continue:");
Console.ReadLine();
svc.Close();
success = true;
}
finally
{
if (!success && svc != null)
{
svc.Abort();
}
}
}
}
}
Any help with this would be greatly appreciated.
Edit:
The contents of my App.config file can be found here:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WeatherSoap" />
</basicHttpBinding>
<customBinding>
<binding name="WeatherSoap12">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://wsf.cdyne.com/WeatherWS/Weather.asmx"
binding="customBinding" bindingConfiguration="WeatherSoap12"
contract="Service1Reference.WeatherSoap" name="WeatherSoap12" />
</client>
</system.serviceModel>
</configuration>
It seems as though .NET is trying to be helpful in generating a SOAP 1.2 binding for you when you probably don't need it (see this question for more information).
To work around this you can explicitly tell the service client which binding to use when you instantiate it by specifying the endpoint name to use:
svc = new WeatherSoapClient("WeatherSoap");
Where "WeatherSoap" is the value of the name attribute on your endpoint node.
I have downloaded schema files from a service provider to test their API. I referenced the service in my ASP.NET application and wrote a simple method to send a ping request. I receive following error:
Error making ping request: There was no endpoint listening at http://localhost:8080/kestrel/SystemService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Does that mean I need to host the files too? If yes, how?
EDIT:
Here is my web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ExternalCacheAccessBinding" />
<binding name="SystemPingBinding" />
<binding name="SystemInfoBinding" />
<binding name="SystemTimeBinding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://americas-uapi.copy-webservices.travelport.com/B2BGateway/connect/uAPI/SystemService"
binding="basicHttpBinding" bindingConfiguration="ExternalCacheAccessBinding"
contract="WSDLService.ExternalCacheAccessPortType" name="ExternalCacheAccessPort" />
<endpoint address="https://americas-uapi.copy-webservices.travelport.com/B2BGateway/connect/uAPI/SystemService"
binding="basicHttpBinding" bindingConfiguration="SystemPingBinding"
contract="WSDLService.SystemPingPortType" name="SystemPingPort" />
<endpoint address="https://americas-uapi.copy-webservices.travelport.com/B2BGateway/connect/uAPI/SystemService"
binding="basicHttpBinding" bindingConfiguration="SystemInfoBinding"
contract="WSDLService.SystemInfoPortType" name="SystemInfoPort" />
<endpoint address="https://americas-uapi.copy-webservices.travelport.com/B2BGateway/connect/uAPI/SystemService"
binding="basicHttpBinding" bindingConfiguration="SystemTimeBinding"
contract="WSDLService.SystemTimePortType" name="SystemtimePort" />
</client>
</system.serviceModel>
This is the request I am sending:
// PING REQUEST
//
String payload= "this my payload; there are many like it but this one is mine";
String someTraceId = "doesntmatter-8176";
//set up the request parameters into a PingReq object
PingReq req = new PingReq();
PingRsp rsp = new PingRsp();
req.Payload=payload;
req.TraceId=someTraceId;
SystemPingPortTypeClient port = new SystemPingPortTypeClient();
try {
//run the ping request
UserNamePasswordClientCredential creds = port.ClientCredentials.UserName;
creds.UserName = "MyUserName";
creds.Password = "MyPassword";
rsp = port.service(req);
//print results.. payload and trace ID are echoed back in response
Label1.Text = rsp.Payload;
Label2.Text = rsp.TraceId;
Label3.Text = rsp.TransactionId;
}
catch (Exception ex) {
//usually only the error message is useful, not the full stack
//trace, since the stack trace in is your address space...
Label1.Text = "Error making ping request: " + ex.Message;
You are trying to connect to yourself (localhost). You need to get the public service address that they supply to publicly access the service.
I.e.:
http://some.public.domain:8080/kestrel/SystemService
You should be able to hit the Service Reference in the browser by just navigating to the service url, and see the service methods. In this case, as in you web.config > https://americas-uapi.copy-webservices.travelport.com/B2BGateway/connect/uAPI/SystemService .
When I navigate to this URL, I get a "500" fault code. I'd start communicating with them about what you are receiving when just navigating to the URL in your browser.