Consuming a WCF service from Javascript - getting HTTP 400 on requests for jsdebug - wcf

I'm trying to create a simple JavaScript test front-end for my WCF service, but the front-end isn't working. I've traced the problem back to where the web page asks the service for http://..../myservice.svc/jsdebug (which, as I understand it, returns the JavaScript code for the proxy client that the web page can use to access the service) - this request is returning HTTP 400 -Bad Request.
In an effort to reduce the problem to its essentials, I've found I can replicate the problem simply:
Open Visual Studio 2010
Create a new project of
type WCF Service Application
Build
Run
In a browser navigate to http://localhost:portnumber/Service1.svc/jsdebug
The result is that the server returns HTTP 400 - Bad Request
What's going on here?
UPDATE:
The .svc file in is:
<%# ServiceHost Language="C#" Debug="true" Service="WebDataProxy.WebDataProxy" CodeBehind="WebDataProxy.svc.cs" %>
The service interface looks like:
namespace WebDataProxy
{
[ServiceContract(Namespace = "http://example.com/WebDataProxy")]
public interface IWebDataProxy
{
[OperationContract]
List<DataResponse> GetDataEx(List<DataRequest> requests);
[OperationContract]
DataResponse GetDataTest(DataRequest request);
[OperationContract]
string Hello(string input);
}
}

Hi you can check this post will help you
Article is about calling cross domain wcf service but it also works for same domain
http://pranayamr.blogspot.com/2011/06/calling-cross-domain-wcf-service-using.html

Related

How to host Web API in Windows Service

I have several resources that I'd like to expose using the WCF Web API. I've investigated the Web API using a Web host but our services all run as Windows Services in production so it's time for me to put the tests aside and verify that everything will work as we need it. I've looked as the sample app here: http://webapicontrib.codeplex.com/SourceControl/changeset/view/2d771a4d6f6f#Samples%2fSelfHosted%2fserver%2fProgram.cs but this does not work with the current version (preview 5) because the HttpConfigurableServiceHost class is not accessible from our code.
One of the most appealing aspects of the Web API is the simple startup using MapServiceRoute and the new WebApiConfiguration. I don't see, however, a way to define the base url and port for the services. Obviously, hosting the service in IIS eliminates this because we configure this information in IIS. How can I accomplish this when hosting in a Windows Service?
It's actually pretty simple. In a nutshell you need to instantiate HttpSelfHostServer and HttpSelfHostConfiguration and then call server.OpenAsync().
public void Start()
{
_server.OpenAsync();
}
public void Stop()
{
_server.CloseAsync().Wait();
_server.Dispose();
}
For an example on how to do this using Windows service project template and/or Topshelf library see my blog post: http://www.piotrwalat.net/hosting-web-api-in-windows-service/
The latest version just uses HttpServiceHost. http://webapicontrib.codeplex.com/SourceControl/changeset/view/ddc499585751#Samples%2fSelfHosted%2fserver%2fProgram.cs
Ping me on twitter if you continue to have problems.
This is the basic code using a console app. A Windows Service uses the same basic approach except you use the start and stop methods to start and stop the service and don't need to block.
static void Main(string[] args)
{
var host = new HttpServiceHost(typeof(PeopleService), "http://localhost:8080/people");
host.Open();
foreach (var ep in host.Description.Endpoints)
{
Console.WriteLine("Using {0} at {1}", ep.Binding.Name, ep.Address);
}
Console.ReadLine();
host.Close();
}
See this blog post.

WCF POST method doesn't get called

I've created a WCF REST service and initially used .Net Framework version 4. The service has two methods, one returns a plain string with the service status. The second allows a file to be uploaded. Both methods were working fine.
I was asked to see if the project could be moved back to only depend on .Net Framework 3.5 instead of version 4. I changed some references, and it built ok, and when I use the existing C++ client I can use the GetStatus method fine. However, now when a file gets uploaded, the client sees successful return codes to all methods, but, when I set a breakpoint at the start of WCF service's FileUpload method, it never gets executed. The file doesn't gets uploaded, it just disappears into the ether.
[ServiceContract]
internal interface IMyWebService
{
[OperationContract]
[WebGet(UriTemplate = "/Status", BodyStyle=WebMessageBodyStyle.Bare)]
Stream GetStatus();
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/FileUpload/{fileName}")]
Stream FileUpload(string fileName, Stream fileStream);
}
I've tried to use the WFetch tool as an alternative client. When I call the FileUpload method, I get this log:
started....WWWConnect::Close("localhost","80")\nclosed source port: 15800\r\n
WWWConnect::Connect("localhost","80")\nIP = "[::1]:80"\nsource port: 15866\r\n
REQUEST: **************\nPOST http://myMachine/MyService/FileUpload/hello.txt HTTP/1.1\r\n
Host: localhost\r\n
Accept: */*\r\n
Content-Length:11\r\n
\r\n
hello thereRESPONSE: **************\nHTTP/1.1 415 Missing Content Type\r\n
Content-Length: 0\r\n
Server: Microsoft-HTTPAPI/2.0\r\n
Date: Thu, 22 Sep 2011 13:26:09 GMT\r\n
\r\n
finished.
Could anybody give me any pointers for how I can diagnose this issue? I'm having trouble seeing where to start because no breakpoints get hit, and there are no error codes to investigate.
The WCF service must be doing something, because if I stop it, the client then fails to upload files, I just can't understand why execution never gets to the method that implements the POST operation.
Hmm, when using WFetch, even if I misspell the name of the method, it still seems to succeed with no error.
Thanks.
I'd start troubleshooting with the original 4.0 version of the service and a C# WCF-based test client to verify the service code will actually upload a file successfully. You could use the code in this Technet article for developing the test client.
Next, use your C++ client against the 4.0 service to verify your client will successfully send a file. Lastly, set the service back to 3.5 and see if it still works. To log messages the service is receiving for troubleshooting, look at this MSDN post to configure the built-WCF message logging capability.

WCF Service Deployment

I have created an ASP.NET web application that contains a WCF Service. I have successfully tested this application locally. In addition, I can successfully use my WCF service. I then deployed it to my remote IIS 7 web server which has an HTTPS binding setup. I don't know if that makes a difference.
When I attempt to access the svc file in my browser (via something like https://www.mydomain.com/myService.svc), I see the service description page. However, when I attempt to execute my operation through the browser (like https://www.mydomain.com/myService.svc/Test) I get a 404 error. The only thing my "Test" operation does is return "Hello World" as shown here:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = false)]
[ServiceContract]
public class MyService
{
[OperationContract]
[WebGet(UriTemplate = "/Test", ResponseFormat = WebMessageFormat.Json)]
public string Test()
{
return "Hello World";
}
}
In an attempt to diagnose the problem further, I created a new ASP.NET web application. In this new application, I attempted to add a new service reference to "https://www.mydomain.com/myService.svc". When I do this, I get a long error message that says:
The document at the url https://www.mydomain.com/myService.svc was not recognized as a known document type.
The error message from each known type may help you fix the problem:
- Report from 'XML Schema' is 'The document format is not recognized (the content type is 'text/html; charset=UTF-8').'.
- Report from 'https://www.mydomain.com/myService.svc' is 'The document format is not recognized (the content type is 'text/html; charset=UTF-8').'.
- Report from 'DISCO Document' is 'There was an error downloading 'http://computername.com/myService.svc?disco'.'.
- The request failed with HTTP status 502: Fiddler - DNS Lookup Failed.
- Report from 'WSDL Document' is 'The document format is not recognized (the content type is 'text/html; charset=UTF-8').'.
Metadata contains a reference that cannot be resolved: 'https://www.mydomain.com/myService.svc'.
There was no endpoint listening at https://www.mydomain.com/myService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
The remote server returned an error: (404) Not Found.
If the service is defined in the current solution, try building the solution and adding the service reference again.
What am I doing wrong? Thank you!
Ah ha! The problem was I did not have "bindingConfiguration="SSL"" in my configuration on the deployment server. Added that and everything is peachy.
Thank s for your help!

WCF GZip Compression Request/Response Processing

How do I get a WCF client to process server responses which have been GZipped or Deflated by IIS?
On IIS, I've followed the instructions here on how to make IIS 6 gzip all responses (where the request contained "Accept-Encoding: gzip, deflate") emitted by .svc wcf services.
On the client, I've followed the instructions here and here on how to inject this header into the web request: "Accept-Encoding: gzip, deflate".
Fiddler2 shows the response is binary and not plain old Xml.
The client crashes with an exception which basically says there's no Xml header, which ofcourse is true.
In my IClientMessageInspector, the app crashes before AfterReceiveReply is called.
Some further notes:
(1) I can't change the WCF service or client as they are supplied by a 3rd party. I can however attach behaviors and/or message inspectors via configuration if this is the right direction to take.
(2) I don't want to compress/uncompress just the soap body, but the entire message.
Any ideas/solutions?
* SOLVED *
It was not possible to write a WCF extension to achieve these goals. Instead I followed this CodeProject article which advocate a helper class:
public class CompressibleHttpRequestCreator : IWebRequestCreate
{
public CompressibleHttpRequestCreator()
{
}
WebRequest IWebRequestCreate.Create(Uri uri)
{
HttpWebRequest httpWebRequest =
Activator.CreateInstance(typeof(HttpWebRequest),
BindingFlags.CreateInstance | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance,
null, new object[] { uri, null }, null) as HttpWebRequest;
if (httpWebRequest == null)
{
return null;
}
httpWebRequest.AutomaticDecompression =DecompressionMethods.GZip |
DecompressionMethods.Deflate;
return httpWebRequest;
}
}
and also, an addition to the application configuration file:
<configuration>
<system.net>
<webRequestModules>
<remove prefix="http:"/>
<add prefix="http:"
type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
</webRequestModules>
</system.net>
</configuration>
What seems to be happening is that WCF eventually asks some factory or other deep down in system.net to provide an HttpWebRequest instance, and we provide the helper that will be asked to create the required instance.
In the WCF client configuration file, a simple basicHttpBinding is all that is required, without the need for any custom extensions.
When the application runs, the client Http request contains the header "Accept-Encoding: gzip, deflate", the server returns a gzipped web response, and the client transparently decompresses the http response before handing it over to WCF.
When I tried to apply this technique to Web Services I found that it did NOT work. Although the helper class was executed in the same was as when used by the WCF client, the http request did not contain the "Accept-Encoding: ..." header.
To make this work for Web Services, I had to edit the Web Proxy class, and add this method:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest rq = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
rq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return rq;
}
Note that it did not matter whether the CompressibleHttpRequestCreator and block from the application config file were present or not. For web services, only overriding GetWebRequest in the Web Service Proxy worked.
Thanks for your WCF tip! We're going to be enabling IIS compression for services at my shop, and I'm hoping your solution will work.
By "To make this work for Web Services" - did you mean old school SoapHttpProtocol clients?
Because the SoapHttpProtocol class has a built-in EnableDecompression property, which will automatically handle the Compression header and response handling.
Here's an answer I gave to another question on the subject. That questio was asked from the perspective of ADO.NET Data Services, but my answer was purely about WCF.

WCF access through script manager

Question: 1
I am a beginner to WCF , I have taken a web application and hosted on IIS(with some port(250) and added a new WCF file, added an operation contract and tried to call the WCF service from the client web app through javascript, i was not able to get the jsdebug file itself to check wheteher proxy is created or not.
But when i add an new AjaxEnabledWCF file and added an operation contract and tried to call the WCF service from the client web app through javascript, i was able to get the jsdebug file, i am able to get the proxy object.
In the client side i have the code like this.
.aspx
function TestWCF()
{
Service.DoWork(onsuccess,onError,true);
}
function onsuccess(result)
{
alert(result);
}
function onError(error)
{
alert("Error: " + error.message);
}
function onfailed(error)
{
var i = 'failed';
}
function oncompleted()
{
var i = 'completed';
}
But while invoking an operation contract i am getting 404 error and not able to figure out what is the problem
Question2 : Is there any possibility that i can make an WCF file to AjaxEnabledWCF file type
can you please help me
Here is a basic check list to debug your problem:
Check your IIS log to make sure that the request is coming in where it is supposed to.
Check rights in IIS that the request is being allowed through.
Check authentication / authorization in web.config.
If impersonate is false check rights of identity of application pool
Check security settings on disk where WCF service files are located.
Make sure that the dll referenced in the WCF service file is in the bin directory.
Check that ASP.net is set to 2.0 in IIS.