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.
Related
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.
I created a simple WCF service that worked just fine. I tried later to make it a duplex service.
I created the duplex contract, changed the binding to wsDualHttpBinding and pulish the WSDL. However when I try to do the last step on the client side I face some trouble. Here is what I did on the client side:
static void Main(string[] args)
{
InstanceContext context = new InstanceContext(new CalcCallbackHandler());
CalcClient proxy = new CalcClient(context);
}
The problem is that CalcClient ctor can't receive InstanceContext.
I can't understand how It's possible beacuse all the example I've seen on the web use this method to create duplex server. Any suggestions?
On the client side you will need to setup/host the call back object and expose the callback endpoint.
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
Maybe I am mixing things, if this is the case, please let me know.
I want to provide a set of services through WCF regarding messages (this is an example). In this set I am going to have a "sendMessage" service and a "receiveMessage" service.
For the sendMessage, I want to use MSMQ, so the user can send the message to 100.000 other users and this will be processed in background.
For the receiveMessage I do not want to use MSMQ because I want the user to be served when he makes the request and get the response (MSMQ, in this case, is oneway).
I am using this code to start my host in an example application
static void Main(string[] args)
{
using (ServiceHost host =
new ServiceHost(typeof(Service), new Uri[] {
new Uri("net.msmq://localhost/private/loadqueue"),
new Uri("http://localhost:8383/") }))
{
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
NetMsmqBinding binding = new NetMsmqBinding();
binding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
binding.Security.Transport.MsmqProtectionLevel = System.Net.Security.ProtectionLevel.None;
binding.ExactlyOnce = false;
host.AddServiceEndpoint(
typeof(IContract),
binding,
string.Empty);
host.AddServiceEndpoint(
typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex");
host.Open();
Console.WriteLine("service running");
Console.ReadLine();
}
}
The Contract looks like this
[ServiceContract(SessionMode=SessionMode.Allowed)]
[DeliveryRequirements(QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Allowed)]
public interface IContract
{
[OperationContract(IsOneWay = true)]
void SendData(string msg);
}
When the client invokes the SendData service, the message is sent to the queue and after that it is consumed by the service.
I would like to create a second service which receives directly the message from the client (no queue in the middle).
The client would have only one web reference and if he calls service.SendData() the message is sent to the queue and if the client calls service.NetMethod() the service receives the message directly. This way it would be transparent for the client side developer if the service is using a queue or not and I would be able to group the services regarding their functions and not mechanisms. Would that be possible to make?
Thanks,
Oscar
WCF allows you to expose the same service contract across mixed transport bindings. For example, your service class has two operations, one one-way, and one request-response. You can expose this service across net.tcp:// and http:// on two endpoints (with different URIs).
However, what you want to do is have the different operations on your service contract exposed over different transports, and as far as I know WCF does not allow this.
The problem you have is that, as you say, the bi-directional operation cannot be supported under the msmq binding. So you would not be able to expose your entire contract across http and msmq simultaneously.
Is there any reason you cannot define two service contracts and host them in the same servicehost, as described here?
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.