C# Consuming XML API - No REST - c#

I was wondering how to consume a XML Service, which states: "CarTrawler’s OTA Server does not expose a Web Services interface - i.e. no SOAP-discoverable WSDL. All messages are stateless and no session is maintained between calls.".
The service have targets URL’s defined in order to send the requests.
One possible request may be:
<?xml version="1.0" encoding="UTF-8"?>
<OTA_VehAvailRateRQ
xmlns="http://www.opentravel.org/OTA/2003/05"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_VehAvailRateRQ.xsd"
Target="Test" Version="1.005">
<POS>
<Source ISOCurrency="EUR">
<RequestorID Type="16" ID="#####" ID_Context="####" />
</Source>
</POS>
<VehAvailRQCore Status="Available">
<VehRentalCore PickUpDateTime="2016-04-01T07:00:00" ReturnDateTime="2016-04-09T19:00:00">
<PickUpLocation CodeContext="####" LocationCode="71" />
<ReturnLocation CodeContext="####" LocationCode="71" />
</VehRentalCore>
<DriverType Age='30'/>
</VehAvailRQCore>
<VehAvailRQInfo PassengerQty='3'>
<Customer>
<Primary>
<CitizenCountryName Code='IE' />
</Primary>
</Customer>
<TPA_Extensions>
<ConsumerIP>999.999.999.999</ConsumerIP>
</TPA_Extensions>
</VehAvailRQInfo>
</OTA_VehAvailRateRQ>
Maybe using HttpClient?, as it has no WSDL and I guess the service isn't REST.

This is no problem. WSDL is just metadata to help you figure out the kind of data you should send or receive. It doesn't mean that the service is not RESTful.
There are many tools that you can use to call a RESTful service. This is my REST client:
https://bitbucket.org/MelbourneDeveloper/restclient-.net
NuGet: Install-Package RESTClient.NET
You should try just doing a simple GET as a string and see what gets returned. If you post the Url of the API, I will try it.

Related

Unwanted Prefix in SoapCore Response in .NET Core

I am writing a SoapCore web service in .NET Core 5.0 and I have successfully been able to execute the request via SOAPUI and get back a valid response. The only thing I don't like is that it puts unwanted prefixes in the repose message. for example in this response:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Body>
<getMeterIntervalDataByTimeSliceResponse xmlns="http://tempuri.org/">
<getMeterIntervalDataByTimeSliceResult xmlns:d4p1="http://schemas.datacontract.org/2004/07/MeterDataWebService.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:AccountId>1234567890</d4p1:AccountId>
<d4p1:ID>0</d4p1:ID>
<d4p1:IntervalEndTime>2020-12-22T15:30:57.3705724-05:00</d4p1:IntervalEndTime>
<d4p1:IntervalLengthInSeconds>PT5M</d4p1:IntervalLengthInSeconds>
<d4p1:Load>2345.8010350836185</d4p1:Load>
<d4p1:MeterChannel>1</d4p1:MeterChannel>
<d4p1:TimeZone>UT</d4p1:TimeZone>
<d4p1:UnitOfMeasure>KM</d4p1:UnitOfMeasure>
<d4p1:UtcOffset>0</d4p1:UtcOffset>
</getMeterIntervalDataByTimeSliceResult>
</getMeterIntervalDataByTimeSliceResponse>
</s:Body>
</s:Envelope>
How do I get rid of the "d4p1" prefix?
I figured it out. It was in my Startup.cs class.
app.UseSoapEndpoint("/Service.asmx", new
BasicHttpBindingg(), SoapSerializer.XmlSerializer);
I forgot to add the SoapSerializer.XmlSerializer part

Service Fabric service exists but returns 404 upon calling

I have a service fabric cluster that works fine locally but when deployed to azure the WebAPI stateless service returns
404 FABRIC_E_SERVICE_DOES_NOT_EXISTS
However the SF cluster shows that the service actually does exists and is up and running
Below is my service manifest for the service
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="SvcWebAPIPkg"
Version="1.0.9"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
This name must match the string used in RegisterServiceType call in
Program.cs. -->
<StatelessServiceType ServiceTypeName="SvcWebAPIType" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.9">
<EntryPoint>
<ExeHost>
<Program>SvcWebApi.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
</CodePackage>
<ConfigPackage Name="Config" Version="1.0.9" />
<Resources>
<Endpoints>
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input"
Port="80" />
</Endpoints>
</Resources>
</ServiceManifest>
If that's the way how you access your service - "myaddress.com/api/BriefcaseApi/GetString" - it's incorrect. SF tries to resolve 'api' as a registered service, which is obviously does not exist. Right? Here is the way how you should construct the url -
http(s)://<Cluster FQDN | internal IP>:Port/<ServiceInstanceName>/<Suffix path>?PartitionKey=<key>&PartitionKind=<partitionkind>&ListenerName=<listenerName>&TargetReplicaSelector=<targetReplicaSelector>&Timeout=<timeout_in_seconds>
In your case, here is how it may look like -
http(s)://myaddress.com/SvcWebAPI/api/BriefcaseApi/GetString
Find more info here - Reverse proxy in Azure Service Fabric.

Orleans Specify SqlServer for Liveness

I am trying to setup a test environment for Orleans that uses SQL Server for liveness. This is my server config file:
<?xml version="1.0" encoding="utf-8" ?>
<OrleansConfiguration xmlns="urn:orleans">
<Globals>
<Liveness LivenessType="SqlServer" DeploymentId="42783519-d64e-44c9-9c29-111111111133" DataConnectionString="Data Source=.\\SQLEXPRESS;Initial Catalog=Orleans;Integrated Security=True;" />
<!--<SeedNode Address="localhost" Port="11111" />-->
</Globals>
<Defaults>
<Networking Address="localhost" Port="11111" />
<ProxyingGateway Address="localhost" Port="30000" />
<Tracing DefaultTraceLevel="Info" TraceToConsole="true" TraceToFile="{0}-{1}.log">
<TraceLevelOverride LogPrefix="Application" TraceLevel="Info" />
</Tracing>
<Statistics MetricsTableWriteInterval="30s" PerfCounterWriteInterval="30s" LogWriteInterval="300s" WriteLogStatisticsToTable="true" />
</Defaults>
<Override Node="Primary">
<Networking Address="localhost" Port="11111" />
<ProxyingGateway Address="localhost" Port="30000" />
</Override>
</OrleansConfiguration>
When I use this config I get this error when running:
MembershipTableGrain cannot run without Seed node - please check your
silo configuration file and make sure it specifies a SeedNode element.
Alternatively, you may want to use AzureTable for LivenessType.
Parameter name: grain = MembershipTableGrain Exception =
System.ArgumentException: MembershipTableGrain cannot run without Seed
node - please check your silo configuration file and make sure it
specifies a SeedNode element. Alternatively, you may want to use
AzureTable for LivenessType.
and further up, the logs say that the Liveness is MembershipTableGrain (which is the default and requires a SeeNode). What am I missing here?
My silo config for SQLServer membership looks like this
<?xml version="1.0" encoding="utf-8"?>
<OrleansConfiguration xmlns="urn:orleans">
<Globals>
<SystemStore SystemStoreType="SqlServer" DeploymentId="YYYYY" DataConnectionString="Server=THESERVER;Database=Orleans;User ID=USER;password=PASSWORD;"/>
</Globals>
<Defaults>
<Networking Address="" Port="11111"/>
<ProxyingGateway Address="" Port="30000"/>
</Defaults>
</OrleansConfiguration>
No need to specify the liveness type. It figures it out by looking at the SystemStoreType.
The client config does need the gateway specified
<ClientConfiguration xmlns="urn:orleans">
<SystemStore SystemStoreType ="SqlServer"
DeploymentId="YYY"
DataConnectionString="Server=THESERVER;Database=Orleans;User ID=USER;password=PASSWORD;" />
<GatewayProvider ProviderType="SqlServer"/>
</ClientConfiguration>
You can also use programmable API for configuration, instead of XML.
I found the problem. That is not how to change the Liveness type. It should be like this:
<SystemStore SystemStoreType="SqlServer" DeploymentId="42783519-d64e-44c9-9c29-111111111133" DataConnectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Orleans;Integrated Security=True;" />
<Liveness LivenessType="SqlServer" />
Also, you must make sure to ref "Microsoft.Orleans.OrleansSqlUtils" NuGet package and run this SQL Create Script

Create a web service with XML response

What is the easiest way to create a web service with XML response?
Use WCF to create the web service? (seems really complicated)
If i want to use WCF to create my web service, where do I start?
In your case, I would definitely use WCF with the REST binding (webHttpBinding) - and I would disagree about it being complicated to learn.
Check out these resources to get started:
MSDN WCF REST developer center
DotNet Rocks TV Show #135: Keith Elder Demystifies WCF
DotNet Rocks TV Show #122: Miguel Castro on Extreme WCF
Few links are available in this article. Hope they will help you -
http://social.msdn.microsoft.com/Forums/en/wcf/thread/b082d6de-d1e9-4e51-a0ab-0fe98d7003e6
The easiest way to create a web service with an XML response is, no kidding, to put an XML file on a standard web server and serve it as a static file.
I'm guessing you want something more flexible than that, though...
You've got several options, and WCF is at the more complex (but flexible) end of the spectrum. First question: what's your client? Are you writing it? Do you want to write a web service that can be consumed by other clients?
Do you want to use REST -- i.e. plain-old-XML (POX) over plain-old-HTTP? XML-RPC? SOAP?
WCF supports all of these, so this really depends on which clients you want to support.
Update: If you want to support XML-RPC, you could do worse than start with this implementation of XML-RPC for WCF by Clemens Vasters. I asked a question about this here.
It's actually pretty easy to create a WCF service. There are plenty of tutorials online.
As for returning xml, there are a few ways.
You can do this with an 'old school' SOAP web service by converting the xml to a string in the service and then convert back in the client. It's not pretty but it works.
An alternative, and the way I'd do it, would be to use WCF and create a data contract that maps your xml.
You can do some pretty good stuff with data contracts, like pass round datasets and custom types but this can sometimes limit the binding types you can use.
I just made a web service.
PHP server side code:
<?php // instantiate SOAP server
function sendXmlMsg($msg){
return $msg;
}
ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSD
$server = new SoapServer("mark.wsdl");
// Register exposed method
$server->addFunction('sendXmlMsg'); // generate captcha
//$server->addFunction('check_captcha'); // check captcha ID
$server->handle(); //?>
My WSDL file is
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='Msg91'
targetNamespace='http://localhost/webtest/test.wsdl'
xmlns:tns='http://localhost/webtest/test.wsdl'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<message name='sendXmlMsgRequest'>
<part name='msg' type='xsd:string'/>
</message>
<message name='sendXmlMsgResponse'>
<part name='Result' type='xsd:string'/>
</message>
<portType name='Msg91PortType'>
<operation name='sendXmlMsg'>
<input message='tns:sendXmlMsgRequest'/>
<output message='tns:sendXmlMsgResponse'/>
</operation>
</portType>
<binding name='Msg91Binding' type='tns:Msg91PortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='sendXmlMsg'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#sendXmlMsg'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='Msg91Service'>
<port name='Msg91Port' binding='tns:Msg91Binding'>
<soap:address location='http://localhost/webtest/test.php'/>
</port>
</service>
</definitions>
Client side PHP file:
<?php
$client = new SoapClient("mark.wsdl");
$params= array('HiT');
echo $client->__soapCall( 'sendXmlMsg', $params );
?>
I hope this will help you.

SharePoint Search Center issue

I am using SharePoint Server 2007 with collaboration portal template on Windows Server 2008. The default search address for a site is pointed to /SearchCenter/Pages/Results.aspx. Any ideas how to change the address to some other address? Either programming solution or easy config solution is fine.
thanks in advance,
George
The Collaboration Portal uses template SPSPORTAL#0, which has the following definition in 12\TEMPLATE\1033\XML\webtempsps.xml:
<Template Name="SPSPORTAL" ID="47">
<Configuration ID="0"
Title="Collaboration Portal"
Type="0"
Hidden="FALSE"
ImageUrl="/_layouts/1033/images/template_corp_intranet.png"
Description="A starter site hierarchy for an intranet divisional portal. It includes a home page, a News site, a Site Directory, a Document Center, and a Search Center with Tabs. Typically, this site has nearly as many contributors as readers and is used to host team sites."
ProvisionAssembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
ProvisionClass="Microsoft.SharePoint.Publishing.PortalProvisioningProvider"
ProvisionData="SiteTemplates\\WebManifest\\PortalWebManifest.xml"
RootWebOnly="TRUE"
DisplayCategory="Publishing"
VisibilityFeatureDependency="97A2485F-EF4B-401f-9167-FA4FE177C6F6">
</Configuration>
</Template>
What this means is that SPSPORTAL#0 does not point to a Site Template in an onet.xml but rather uses an XML file to define a number of sites that are to be created. Here is PortalWebManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- _lcid="1033" _version="12.0.4518" _dal="1" -->
<!-- _LocalBinding -->
<portal xmlns="PortalTemplate.xsd">
<web name="Home" siteDefinition="SPS" displayName="$Resources:spscore,PortalManifest_Home_DisplayName;" description="$Resources:spscore,PortalManifest_Home_Description;">
<webs>
<web name="News" siteDefinition="SPSNHOME" displayName="$Resources:spscore,PortalManifest_News_DisplayName;" description="$Resources:spscore,PortalManifest_News_Description;" />
<web name="SiteDirectory" siteDefinition="SPSSITES" displayName="$Resources:spscore,PortalManifest_SiteDirectory_DisplayName;" description="$Resources:spscore,PortalManifest_SiteDirectory_Description;" />
<web name="SearchCenter" siteDefinition="SRCHCEN" displayName="$Resources:spscore,PortalManifest_SearchCenter_DisplayName;" description="$Resources:spscore,PortalManifest_SearchCenter_Description;" />
<web name="Docs" siteDefinition="BDR" displayName="$Resources:spscore,PortalManifest_DocumentCenter_DisplayName;" description="$Resources:spscore,PortalManifest_DocumentCenter_Description;" />
</webs>
</web>
</portal>
You could create a custom Site Definition with a custom PortalWebManifest.xml that includes the name other than SearchCenter that you want to use. Or, since PortalProvisioningProvider does not do much more than create sites based on the XML passed into it, you could use PortalWebManifest.xml as a guide and write code that will create the sites how and where you want.

Categories