I have wsdl which was generatede by JAX-WS RI of a working web service, but i don't have access to the service itself.
Now what i would like to do is, to create my own WCF service out of the wsdl that i got. So i could just switch url's in the config file.
I created service interface with svcutil.exe.
svcutil my.wsdl my.xsd
All seemed ok until i tried to check my service via browser, i got:
The operations X and Y have the same action (). Every operation must have a unique action value.
Hmm.. ok. i checked the interface and realized that, yes, code generator has given each operation same name - "".
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
So i replaced all these linse with plain [OperationContract] and all seemed to work well until i tried to call my service from client. In config i just modified endpoints address.
The exception i got was: The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher
To me it seems like client is requesting operation with no name. How is it possible that working service knows which operation to use?
If i add new my service as a new service reference, all works fine.
What am i missing here?
How can i make WCF service to work on same contract it was generated from?
EDIT:
I did some more debugging. I creted opration
[OperationContract(Action = "*", ReplyAction = "*")]
public object UnknownAction()
{
return null;
}
When i add breakpoint to this operation i see from OperationContext.Current.IncomingMessageHeaders.Action that Action is empty. Message body is totally correct though.
Is there some kind of behavior i need to define on the server side?
current behavior configuration looks like this:
<behavior name="svcBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
EDIT vol2
When i create asmx web service and try to call web method from client, i get SoapException: Server did not recognize the value of HTTP Header SOAPAction: .
Related
I'm using WCF to invoke a remote REST API, and am getting a 500 Internal Server Error from the service. Using Fiddler, I can see the body of the 500 response (which includes, buried in HTML, the reason for the 500 error). I would like to be able to examine the response body in .Net, but it appears that the WebFaultClientMessageInspector gets there first, and throws a vague exception.
Is there anyway to disable/override this inspector (and see the full response body)?
I think I've figured this out - I do need a custom message inspector (IClientMessageInspector), but I also need to configure it FIRST in my WCF Endpoint configuration:
<endpointBehaviors>
<behavior name="myCustomErrorWebHttp">
<myCustomnClientBehavior />
<webHttp />
</behavior>
</endpointBehaviors>
Doing THIS caused my inspector to be triggered BEFORE WebFaultClientMessageInspector, and I was able to inspect the message body.
From this link
How to solve this problem? The answer is obvious: create custom
implementation IClientMessageInspector and use it on client.
Full details is in the link.
I post this questions after lot of time reading different messages about WCF.
I have developed a WFC service that is working at an specific location.
I have developed a vb.net app that consum the WCF service mentioned. It works fine.
I have now a new choice. How can I change from the app the address of the service?. I mean, suppose the service is located at IP a.b.c.d, and now has changed to e.f.d.r. How can I change this on the app?. Should I modify the app.config of the app in execution time? should be possible? Isn't another way to change the address?
A piece of the app.config I'm using on the app is the following:
< bindings>
< basicHttpBinding>
< binding name="BasicHttpBinding_IWCF_ServicioWeb" />
< /basicHttpBinding>
< /bindings>
< client>
< endpoint address="http://localhost:49311/WCF_ServicioWeb.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IWCF_ServicioWeb"
contract="MiServicioWeb.IWCF_ServicioWeb" name="BasicHttpBinding_IWCF_ServicioWeb" />
< /client>
I hope someone could help me...
Just add an ApplicationSettings entry to your config file
<MyApp.Properties.Settings>
<setting name="MyServiceUrl" serializeAs="String">
<value>http://a.b.com/ServicioWeb.svc</value>
</setting>
</MyApp.Properties.Settings>
Now, every time you need to call the service write
Using wcf = New ServicioClient("BasicHttpBinding_IWCF_ServicioWeb",
New EndpointAddress(YourAppNameSpace.Properties.Settings.Default.MyServiceUrl))
.... call your wcf methods ....
End Using
I see that you are using basicHttpBinding. If you are not using either Transport or Message security and certificate validation is not an issue then it's just a matter of changing the Endpoint Address both on the service (server) and in the client application that is consuming the WCF service.
I am trying to set up a simple WCF REST service that we will be able to call from jquery. When I visit the URL in the browser, I get a response back. When I attempt to send an HTTPRequest directly (using the Firefox plugin RESTClient), I get a response back. These responses look correct to me, containing headers and a string of JSON and apparently nothing else.
However, when I call this same service via a jquery.get() or jquery.post() call, nothing happens. Using the jquery.ajax() call reveals the error callback gets called, but to me the data given to the error callback doesn't give me clues as to why this isn't working.
<a id="thelink" href="javascript:void(0)">GO</a>
<script type="text/javascript">
function doAjax() {
$.ajax({type: "POST",
dataType: "json", // see note below
url: "http://localhost:54459/MySimpleService.svc/json/24",
success: function(jqXHR, textStatus) {
alert("success");
},
error: function(jqXHR, textStatus, errorThrown) {
alert("error");
}
});
}
$('#thelink').click(doAjax);
</script>
Note: for the dataType parameter I have tried all of "text", "json", "jsonp" and leaving the parameter off. Similarly, I have tried with both GET and POST (modifying the web service to respond to GET or POST respectively).
The method called at that endpoint doesn't do anything spectacular that should be failing -- it simply concatenates the string to a constant and returns (just testing at this point, it will clearly do more interesting things in the future)
Firefox shows me getting back 200 OK when I click the link.
The WCF service is running out of my Visual Studio 2010 debug environment. It hits breakpoints placed in the method that responds to this service method.
I have tried accessing the html posted above from a file on my local machine (port 80) as well as hosting it elsewhere, with the same results. Could this be a security issue?
The values passed to the error callback don't seem terribly helpful:
jqXHR - readyState : 0, status : 0, statusText : error
textStatus - "error"
errorThrown - ""
So, why does my service seem to work, for GET or POST, when I call the url in a browser or RESTClient, but fail when I attempt to call it from jquery.ajax()?
EDIT: after more tests based on the comments I received, I tried hosting the page with the javascript on the same port as the web service, and this shows success. In my real-world scenarios, I won't have the luxury of hosting the client side code and the web service on the same domain/port. I'm assuming this is a security model issue -- where do I look to allow this sort of access (whitelisting domains/ports or otherwise)
The issue seemed to be in my web.config; as we worked out in comments, the issue is one of cross-domain security. I was already using a webHttpBinding on my endpoint, but did not realize it needed to be configured:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"/>
</webHttpBinding>
</bindings>
...
</system.serviceModel>
Setting crossDomainScriptAccessEnabled="true" seems to have done the trick. Note that I already have <serviceMetadata httpGetEnabled="true"/> as part of my service behavior.
make sure you have already configured your service to be called from script clients: adding a couple of elements in web.config in your service:
<behaviors>
<endpointBehaviors>
<behavior name="webScriptEnablingBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
more info here: http://msdn.microsoft.com/en-us/library/bb763177(v=vs.90).aspx
hope it helps,
here's the setup for the project.
I have a WCF Service that is hosted on a net.tcp binding in buffered mode and ReliableSession enabled.
The binding is configured to use TransportWithMessageCredential security. The certificate is a self signed certificate that I am identifying using the Thumbprint.
The UserNameValidator is a custom validator which for testing, never fails (it wasn't failing before but I removed the uncertainty)
The service and client are on the same machine and they both have access to the certificate.
The problem:
I am receiving a Socket Aborted exception when trying to consume a Method from the service. Here is the code I use to open a connection to the service. MonitorServiceCallbacks only contains empty methods to fulfil the requirements of the Interface.
_instanceContext = new InstanceContext(new MonitorServiceCallbacks());
_serviceInterface = new MonitorCallbackServiceClient(_instanceContext);
_serviceInterface.ClientCredentials.UserName.UserName = Environment.MachineName;
_serviceInterface.ClientCredentials.UserName.Password = "myPassword";
_serviceInterface.Open();
This appears to work fine as the _serviceInterface.State variable is set to State.Opened and the custom validator is called and returns without exception.
However, if I try to call a method using the _serviceInterface proxy, no code that I can break into is run on the service and the tracelog reveals no errors apart from a SocketAborted exception which occurs 1 minute after receiving what appears to be the message for the method.
There is no InnerException.
I have tried to google the issue but the results tend to say "just disable security and it will work fine". Unfortunately, this cannot be done.
I am extremely confused by this issue and any help would be greatly appreciated.
Many thanks,
Ehrys
This was actually a serialisation error.
The object I was trying to send to the service inherited from the data contract. So I was trying to send a cast down to the data contract to the service.
WCF doesn't appear to allow this.
I would like to thank John Saunders for reminding me that not only the service can have tracing enabled. Enabling client side tracing would have saved me a lot of time.
I was attempting to do the following:
_serviceInterface.Register((MyDataContract)MyParentObject, aVariable, anotherOne);
What I needed to do:
MyDataContract tempContract = MyParentObject.CreateMyDataContract();
_serviceInterface.Register(tempContract, aVariable, anotherOne);
/* Note: MyParentObject.CreateMyDataContract() is my own method which creates an instance
of the MyDataContract and copies the relevant information to it */
How can I detect the user agent in a web service? My web service is implemented using a WCF webservice with basicHTTPBinding. It will be a post from some SOAP clients. I wish to know the user-agent from the clients.
I shall like to see some sample code for this.
I am using a WCF based web service and in the svc.cs, I tried to catch this.Context.Request.UserAgent. But it gives the following error:
this.Context.Request.UserAgent 'MySoapService.MyService' does not contain a definition for 'Context' and no extension method 'Context' accepting a first argument of type 'MySoapService.MyService' could be found (are you missing a using directive or an assembly reference?)
I also tried System.Web.HttpContext.Current.Request.UserAgent and it says:
'System.Web.HttpContext.Current' is null
Edit note:
I tried to activate the ASP.NET compatibility mode. I added <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> in the config file and added [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] on the top of the class that implements the service interface. Then using System.Web.HttpContext.Current.Request.UserAgent gives me the user agent as desired.
There is another way to get the user agent without enabling ASP.NET compatibility in web.config:
string userAgent = WebOperationContext.Current.IncomingRequest.Headers["User-Agent"];
You can use also:
WebOperationContext.Current.IncomingRequest.UserAgent
You can read user agent from the HttpContext.Current.Request object if you enable ASP.NET compatibility in web.config:
What a totally unhelpful response!
This is not a trivial task. Yes it is obviously possible to get te user-agent string but how does one actually do it? I spent 2 hours checking google and so on but found the answer buried in MSDN documentation. In Visual Studio, from within a WebMethod try
this.Context.Request.UserAgent
That should do it!
User-Agent is a standard HTTP header. It'll be available to your web service just like it's available to anything CGI-like.
Did you even bother searching for this before posting your question? There must be millions of hits for it on Google.