svc service that can recieve any request - wcf

Hello BizTalk and WCF experts
I need your help todo a implementation for this scenario:
I have created a BizTalk application without schemas, orchestrations but just with a send port pipeline that look at the soap action on the request message and send the request to the correct destination service.
I have also created a in-process WCF-Custom receive port that my send port subscribe and I have defined following in-process custom URL "http://localhost:8080/bts/services/serviceRoute.svc".
Instead of calling the above metioned URL i want an IIS service endpoint that receive all the request and send it to ny custom url.
So i want a IIS svc endpoint without specific schema but a service endpoint that can receive any request no matter operationsname and send the request to my BizTalk receive port (my WCF-Custom receive port).
Can anyone tell me how I can define/create a IIS service endpoint for this scenario or any other way I can solve this issue.?
Thanks for your help..

Very important point: BizTalk already does this. You don't need the extra IIS service.
BizTalk Receive Locations are not Schema bound. They will happily accept any message type. The only validation happens if you implement it.
So, I would start with a plain WCF-WebHttp endpoint hosted In-Process or IIS or WCF-BasicHttp/basicHttpBinding to have the Action automatically Promoted (IIRC, been a while ;).
You can configure the URL, security and what not any way you need in IIS.

Create a service with a method that receives a System.ServiceModel.Channels.Message class, like this interface:
[ServiceContract(Namespace = "http://yournamespace")]
public interface IRouter
{
[OperationContract(Action = "*", ReplyAction = "*", Name = "*")]
[WebGet]
Message RouteMessage(Message incomingRequest);
}
This will receive any message, including non-soap messages, so you can create your routing logic.
Message class has some useful members, like Headers property and CreateMessage method, that you can use to create a copy of original message and redirect to its destination, or simply extract the data for logging.
EDIT: adding some information (some doubts in comments)
Using the code above, you can simply redirect the incomming message to another endpoint, like this:
/* "endpointConfigurationName" is the name of a client endpoint, that is in Web.config, like this for instance:
<endpoint name="endpointConfigurationName" binding="basicHttpBinding" bindingConfiguration="someBindingConfiguration" behaviorConfiguration="someBehaviorConfiguration" contract="IRouter" />
notice that there is not an address defined, you can define in code */
using (var factory = new ChannelFactory<IRouter>("endpointConfigurationName", new EndpointAddress("http://destinationEndpoint")))
{
// create a channel to send the resquest
IRouter router = factory.CreateChannel();
// get the response
var reply = router.ProcessarMensagem(incomingRequest);
}
This is a very simple example, but contains the base logic.

Related

How to pass parameter and get data from wcf service

I got this error:
There was no endpoint listening at http://vkalra.in/WCF_SERVICE/RestServiceImpl.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
InnerException-The remote server returned an error: (404) Not Found.
This is my code:
Binding binding = new BasicHttpBinding();
// Create endpointAddress of the Service
EndpointAddress endpointAddress = new EndpointAddress("http://vkalra.in/WCF_SERVICE/RestServiceImpl.svc");
ServiceReference1.Leave_Details emp = new ServiceReference1.Leave_Details();
emp.empid = items.empid;
emp.fromdate = "01-04-2019";
emp.todate = "04-06-2019";
emp.tabt = "1";
emp.jdis = "0";
try
{
ServiceReference1.RestServiceImplClient service = new ServiceReference1.RestServiceImplClient(binding, endpointAddress);
string levbal = service.Leave_Calculation(emp);
}
catch(Exception ex)
{
}
If we want to consume the WCF service created by WebHttpBinding(this type of the WCF service is also called Restful service) by adding service reference, we need to do something special. Generally speaking, if we want to call Restful service (such as the service created by Asp.net WebAPI), we could construct a http request, Get or Post with a request body, then send to the specified service address.
https://code-maze.com/different-ways-consume-restful-api-csharp/
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
This also applies to WCF service created by WebHttpBinding.
consuming a WCF service using simple HttpClient class
But if we want to consume the WCF restful service by adding the service reference, we are supposed to maintain the consistency of binding between the client and server. we should add [WebGet]/[WebInvoke] to the auto-generated method of the service interface, which comes in the form of adding service reference, located in Reference.cs file.
One more thing we need do is add Webhttpbehavior (endpoint behavior) to the client service endpoint. This client configuration comes in the form with adding service reference, located in the System.ServiceModel section of the app.config/web.config.
The remote server returned an unexpected response: (400) Bad Request. wcf
Feel free to let me know if there is anything I can help with.

Configure WCF Service address in Xamarion iOS

In my Xamario.iOS application which I'm doing in VisualStudio, I'm consuming WCF services by adding the ServiceReferences (Add ServiceReference) and I get my services added in ServiceReference folder as below:
LoginService (This is of Login.svc)
RegisterService (This is of Register.svc)
my code looks like
LoginRequest req = new LoginRequest()
req.username = "test"
req.password = "test"
LoginResponse res = LoginService.Authenticate(req)
and I get my response which is fine.
But I would like to configure the WCF service's address dynamically, so that in future I can change my service URL just in one place rather than updating all the services under ServiceReference folder.
Right now, I don't find any config file which has the configuration details for the WCF services added, in my Xamarin.iOS project.
If I create the Service Client in code behind, I can get the client for each service, but in such case how can I have my LoginRequest and LoginResponse type?
Your client class should have a constructor overload that allows you to specify the address of the endpoint.

How to prevent WCF proxy from following redirect?

I'm using basicHttpBinding for my WCF service and have a message inspector that sets response code to Redirect under certain circumstances. I find that the WCF proxy (generated by svcutil) automatically tries to follow the redirect. How do I prevent this from happening?
Thanks,
Priya
Can you reference the service contract assembly from your client application? If so you can get rid of the generated service reference and just spin up a proxy at runtime using ChannelFactory.
For example:
// Create service proxy on the fly
var factory = new ChannelFactory<IMyServiceContract>("NameOfMyClientEndpointInConfigFile");
var proxy = factory.CreateChannel();
// Create data contract
var requestDataContract = new MyRequestType();
// Call service operation.
MyResponseType responseDataContract = proxy.MyServiceOperation(requestDataContract);
In the above example, IMyServiceContract is your service contract, and MyRequestType and MyResponseType are your data contracts, which you can use by referencing the assembly which the service also references (which defines these types).
what have you tried to achieve with redirect ? you will an handle this cases with some message interceptors on client side:
http://msdn.microsoft.com/en-us/library/ms733786(v=vs.90).aspx

WCF - Dynamically calling different web service endpoints implementing the same interface

I have a number of different applications that implement the same contract. In my main app, I would like to have one proxy. Then dynamically, given a Uri for a particular application, I would create a web service request and call that. How can that be accomplished? Thanks!
Do these steps:
generate your client-side proxy based on one service
this will generate the C#/VB.NET classes for you, as well as the app.config (or web.config if your client is a web app)
when calling the default service endpoint, you can do something like:
YourServiceClient client = new YourServiceClient();
client.CallSomeMethod();
This will use all the settings from the default service endpoint as defined in your config file
if you need to provide a different endpoint, do this:
YourServiceClient client =
new YourServiceClient("default", "http://server/YourOtherService.svc");
client.CallSomeMethod();
There is an overload for the client constructor which will take two parameters: the name of the endpoint configuration in your client config file (you need to look that up after you've added the service reference), and the endpoint URL you want to connect to (which can be different from what's stored in the config).
If all the other parameters like service contract, binding information etc. stay the same, this method should work and it should allow you to connect to any number of varying endpoints using this second constructor overload.
When you instantiate the service client, you can set the uri
ReconcileSvc.ReconcileClient client = new ReconcileClient();
client.Endpoint.Address = new System.ServiceModel.EndpointAddress(uri);
Hope it helps.

WCF -> ASMX and Cookies

I have a web application that communicates to a WCF service through a WCF client. At the point my code is invoked, authentication cookies have been issued and I have a dependency on an ASMX service that expects those authentication cookies.
I need to pass the cookies from the web application through the WCF client to the WCF service to the ASMX service.
Any ideas? It looks like my best bet may be setting allowCookies to false, parsing out the cookie headers, attempting to re-create them on the WCF service and then attaching them to the SOAP request.
Note: I looked at this article, which seems close but not quite applicable to this question. In the linked scenario, an ASMX service is creating cookies, which must be persisted to a subsequent ASMX service by the same WCF client.
Ok, so there's two main things that need to occur:
Get the cookie from the web app context to the WCF service
Get the cookie from the WCF service to the ASMX service
NOTE: Because you didn't specify, I'm going to assume that you're using a WCF client within your WCF service to talk to the ASMX service. If this is not the case please let me know and I will revise this post accordingly.
Step #1:
I would recommend writing an IClientMessageInspector which you bind to your client endpoints using an IEndpointBehavior. In your implementation of IClientMessageInspector::BeforeSendRequest you basically read the cookie out of the current HttpContext::Request::Cookies collection and append the value as a message header. That would look a little something like this:
public void BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Get the cookie from ASP.NET
string cookieValue = HttpContext.Current.Request.Cookies["MyCookieName"].Value;
// Create a header that represents the cookie
MessageHeader myCookieNameHeader = MessageHeader.CreateHeader("MyCookieHeaderName", "urn:my-custom-namespace", cookieValue);
// Add the header to the message
request.Headers.Add(myCookieNameHeader);
}
One you configure the endpoint with this message inspector every logical request will automatically flow the cookie value through as a header to your WCF service. Now, since your WCF service doesn't actually care about the header itself, it can basically ignore it. In fact, if you only did this step, you should be able to run all your code right now and not experience any difference.
Step #2:
Now we need the cookie to go from the WCF service to the ASMX service. Once again all you need to do is implement an IClientMessageInspector, except your BeforeSendMessageRequest is going to be a little different:
public void BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Get the cookie value from the custom header we sent in from step #1
string cookieValue = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("MyCookieHeaderName", "urn:my-custom-namespace");
HttpRequestMessageHeaderProeperty httpRequestMessageHeaderProperty;
MessageProperties outgoingMessageProperties = OperationContext.Current.OutgoingMessageProperties;
// Get the HttpRequestMessageHeaderProperty, if it doesn't already exist we create it now
if(!outgoingMessageProperties.TryGetValue(HttpRequestMessageHeaderProperty.Name, out httpRequestMessageHeaderProperty))
{
httpRequestmessageHeaderProperty = new HttpRequestMessageHeaderProperty();
outgoingMessageProperties.Add(HttpRequestMessageHeaderProperty.Name, httpRequestmessageHeaderProperty);
}
// Set the cookie header to our cookie value (note: sample assumes no other cookies set)
httpRequestmessageHeaderProperty.Headers[HttpRequestHeader.Cookie] = cookieValue;
}
Once again you need to bind this to the endpoint for your ASMX service using an IEndpointBehavior and every logical request you make will automatically pass the cookie through.