Service should only be accesible between certain times - c#

I need to create a WCF service that gets some data out of a database. This service should only be accessible at night, for some reason. I have been told this should be possible by some code in web.config, but I have no idea how.

Not sure if there's a way to define in web.config, but it seems like you can use PowerShell to schedule and terminate the service.
MSDN blog post on scheduling background jobs

It's not possible in web.config. This is a highly unusual requirement. Certainly not built in.
Just go like this:
if (DateTime.Now.Hour >= 22)
throw new FaultException("ServiceUnavailable");

For a client, you would want to adjust the sendTimeout attribute of a binding element. For a service, you would want to adjust the receiveTimeout attribute of a binding elemnent.
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="longTimeoutBinding"
receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="longTimeoutService"
behaviorConfiguration="longTimeoutBehavior">
<endpoint address="net.tcp://localhost/longtimeout/"
binding="netTcpBinding" bindingConfiguration="longTimeoutBinding" />
</service>
Let me know if this answers your question.

Related

C# using different endpoints to the same WebService

We have a setup, with a dev- test- and production environment. So when development and testing is done, each server has the same WebServices.
This is my first time doing so, but on the dev. environment I’ve written a WebService, and a C# client, using the Visual Studio (2017) ‘Add Service Reference’ feature. So I have an app.config file like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BizTalkInterfaceServiceSoapBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://xxx.xxx.xxx.xxx:xxxxx/and/so/on"
binding="basicHttpBinding" bindingConfiguration="BizTalkInterfaceServiceSoapBinding"
contract="ServiceReference.BizTalkInterface" name="BizTalkInterfacePort" />
</client>
</system.serviceModel>
</configuration>
And a Connected Services->ServiceReference structure, with a .wsdl, configuration.svcinfo, configuration91.svcinfo and Reference.svcmap files. I don’t know if there is any point in showing the contents of these files?
I initialize the client like this:
protected BizTalkInterfaceClient client;
protected ServiceBase()
{
client = new BizTalkInterfaceClient("BizTalkInterfacePort");
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
client.ClientCredentials.UserName.UserName = "xxx#xxxdomain";
client.ClientCredentials.UserName.Password = "xxxxxx";
}
Anyhow - This is all well and good, and works fine.
If you haven’t figured it out yet :-), I would like to define two other named endpoints, but I’m unsure on how to do it. Is there a wizard like way to do it, or do I have to copy/past the endpoint in the app.config and configuration files?
Any help would be greatly appreciated. Thanks a lot in advance.
You should be able to copy and paste this endpoint in your <client> node:
<endpoint address="https://xxx.xxx.xxx.xxx:xxxxx/and/so/on"
binding="basicHttpBinding" bindingConfiguration="BizTalkInterfaceServiceSoapBinding"
contract="ServiceReference.BizTalkInterface" name="BizTalkInterfacePort" />
and just give it a different name.
Also, when you initialize you client you would use the corresponding name here:
client = new BizTalkInterfaceClient("BizTalkInterfacePort");
example:
<endpoint address="https://xxx.xxx.xxx.xxx:xxxxx/and/so/on"
binding="basicHttpBinding" bindingConfiguration="BizTalkInterfaceServiceSoapBinding"
contract="ServiceReference.BizTalkInterface" name="BizTalkInterfacePortProd" />
client = new BizTalkInterfaceClient("BizTalkInterfacePortProd");
If your service has multiple service endpoint, it should be like
<service name="Service.CalculatorService" >
<endpoint address="http://localhost:3721/calculator" binding="basicHttpBinding" bindingConfiguration="ECMSBindingConfig" contract="ServiceInterface.ICalculatorService"></endpoint>
<endpoint address="http://localhost:4000/calculator" binding="wsHttpBinding" contract="ServiceInterface.ICalculatorService"></endpoint>
</service>
And then you could add reference to the service using wsdl address.
After adding reference, there should be two endpoint in your client with endpoint name, like
<endpoint address="http://localhost:3721/calculator" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ICalculatorService" contract="Calculator.ICalculatorService"
name="BasicHttpBinding_ICalculatorService" />
<endpoint address="http://localhost:4000/calculator" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculatorService" contract="Calculator.ICalculatorService"
name="WSHttpBinding_ICalculatorService">
Then in your client , you could initialize your client using the name of your configuration just as Popo has written.

WCF: strange automatic service reference

I created a simple WCF service with netHttp binding, and then automatically added service references from it into another application via "Add service reference|Discover". The resulting binding looks weird.
Instead of the original NetHttpBinding I get a CustomBinding.
It works, but annoyingly I can't add a maxReceivedMessageSize to a custom binding.
Question: Is there any good reason for this, or can I safely replace the custom binding with the original netHttpBinding?
The host's app.config:
<endpoint address="images/netbh" binding="netHttpBinding" contract="WcfImageService.IImageService" bindingConfiguration="netHttp_bh" />
<netHttpBinding>
<binding name="netHttp_bh" messageEncoding="Binary">
<webSocketSettings transportUsage="Never"/>
</binding>
</netHttpBinding>
The client's generated app.config:
<customBinding>
<binding name="NetHttpBinding_IImageService1" >
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
<endpoint address="http://localhost:8080/images/netbh" binding="customBinding"
bindingConfiguration="NetHttpBinding_IImageService1" contract="ImageServiceReference.IImageService"
name="NetHttpBinding_IImageService1" />
I'm using Visual Studio 2015, in case that matters.
I don't know why you get a customBinding in the client (I think the wsdl.exe tool that Visual Studio uses behind the scenes is a bit confused) but you can safely replace the custom binding with the original webHttpBinding.
As an alternative, I think you can also specify can also specify maxReceivedMessageSize on the <httpTransport> element like this:
<httpTransport maxReceivedMessageSize="2000000000" />

WCF service errors out on other machines in the same network

I developed a C# console application that consumes a WCF service. All works fine on the local machine. When I created the set up files and distributed the exe and exe.config files, the application errors out on other machines on the same network with the below error:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state..
The WCF service endpoint URL - http://inblrlwssc251.wdf.corp:7980/AfariaService/Server is accessible form other machines as well. Unsure what can be going wrong.
The configuration for the service looks as below, I use the WSHTTP binding:
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IServerService" />
</netNamedPipeBinding>
<netTcpBinding>
<binding name="NetTcpBinding_IServerService">
<security mode="Message" />
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IServerService" />
</wsHttpBinding>
</bindings>
<!--
Modify the "adress" in each of the endpoint tags based on where the Afaria API service is hosted
-->
<client>
<endpoint address="http://inblrlwssc251:7980/AfariaService/Server"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServerService"
contract="AfariaServerService.IServerService" name="WSHttpBinding_IServerService">
</endpoint>
<endpoint address="net.tcp://inblrlwssc251:7982/AfariaService/Server"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IServerService"
contract="AfariaServerService.IServerService" name="NetTcpBinding_IServerService">
</endpoint>
<endpoint address="net.pipe://localhost/AfariaService/Server"
binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IServerService"
contract="AfariaServerService.IServerService" name="NetNamedPipeBinding_IServerService">
</endpoint>
</client>
</system.serviceModel>
Any help or a pointer in the right direction will be very much appreciated.
I know that this is old and you said it is resolved, but for posterity's sake this is not typically the result of passing incorrect credentials. Normally this is a result of the response from the server responding with more data that you've configured to accept in your buffers, exceeding the maxitemsinobject graph, or the response from the server taking too long, which causes an exception, which is handled... and this exception is the result of the next call (as fejesjoco and Tim pointed out).
When this occurs, it is best to reinitialize the client/serviceclient object (for this api, also call initContext) and then try the call again.

Namespace is not supported with rpc\\literal SOAP. The wrapper element has to be unqualified

I'm currently working on an integration with a leasing service provider, which runs (I assume) a Java service.
When I add the service reference in Visual Studio 2012, the reference is created correctly and I can call the methods specified in the service.
The problem arises when I get a response from the service.
Let's say I call the service with wrong parameters getCalculation and I get the JSON response JSONException. The problem is, that Visual Studio throws an exception There was an error reflecting 'JSONException'. and as InnerException: {"Namespace='http://service.ecommerce.cetelem.hu/' is not supported with rpc\\literal SOAP. The wrapper element has to be unqualified."}
This is the web.config code:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="EcommerceServiceImplPortBinding">
<security mode="Transport" />
</binding>
<binding name="EcommerceServiceImplPortBinding1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://ecomdemo.cetelem.hu:443/ecommerce/EcommerceService"
binding="basicHttpBinding" bindingConfiguration="EcommerceServiceImplPortBinding"
contract="CetelemInstallmentsService.EcommerceService" name="EcommerceServiceImplPort" />
</client>
</system.serviceModel>
If this is of any help, I'm using WebAPI for the user "front-end".
Thank you for all the answers!
I figured this thing out eventually, but with the help of another post on SO: SOAP Requests in .net
All I needed to change in the service refence file was:
[System.ServiceModel.XmlSerializerFormatAttribute(Style = System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults = true)]
To:
[System.ServiceModel.XmlSerializerFormatAttribute(Style = System.ServiceModel.OperationFormatStyle.Document, SupportFaults = true)]

How to Send Large File From Client To Server Using WCF?

How to Send Large File From Client To Server Using WCF in C#? Below the configuration code.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="HttpStreaming_IStreamingSample"
maxReceivedMessageSize="67108864"
transferMode="Streamed">
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:4127/StreamingSample.svc"
binding="basicHttpBinding"
bindingConfiguration="HttpStreaming_IStreamingSample"
contract="StreamingSample.IStreamingSample"
name="HttpStreaming_IStreamingSample" />
</client>
</system.serviceModel>
You need to check out streaming, as Dzmitry already pointed out.
In order to be able to send large files as a stream to your service, you'll need to:
create a service method that accepts a Stream as its input parameter
create a binding configuration (on both the server and the client) which uses transferMode=StreamedRequest
create a stream in your client and send it to the service method
So first off, you need a method in your service contract:
[ServiceContract]
interface IYourFileService
{
[OperationContract]
void UploadFile(Stream file)
}
Then you need a binding configuration:
<bindings>
<basicHttpBinding>
<binding name="FileUploadConfig"
transferMode="StreamedRequest" />
</basicHttpBinding>
</bindings>
and a service endpoint on your service using that binding configuration:
<services>
<service name="FileUploadService">
<endpoint name="UploadEndpoint"
address="......."
binding="basicHttpBinding"
bindingConfiguration="FileUploadConfig"
contract="IYourFileService" />
</service>
</services>
and then, in your client, you need to open e.g. a filestream and send that to the service method without closing it.
Hope that helps!
Marc
You can take a look at WCF Streaming feature.
In addition to increasing readerQuota settings (mentioned above) I had to also up the maxRequestLength inside the httpRuntime attribute.
<system.web>
<httpRuntime maxRequestLength="2097151" />
</system.web>

Categories