How to call WCF REST/JSON Service from client application - c#

I have WCF REST/JSON Service, I create it by using this template. In my service I have a method
[WebInvoke(UriTemplate = "Create", Method = "*",RequestFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.Bare)]
public void Create(PictureData pictureData)
{
var context = new EFDBContext();
context.PictureData.Add(pictureData);
context.SaveChanges();
}
PictureData this my entity data, which I try to save in DB via EF.
In my WPF client application I try to call this method:
using (var client = new HttpClient("http://localhost:8080/ScreenPictureService/Create"))
{
var dataContract = HttpContentExtensions.CreateJsonDataContract(pictureData);
client.Post("", dataContract);
}
But nothing happen
I also try to use Method="POST" in WebInvoke attribute
Also I try to use address without "Create" in HttpClient and then use it in client.Post in first parameter
UPDATE
After I try this
var dataContract = HttpContentExtensions.CreateJsonDataContract(pictureData, typeof (PictureData));
var client = new HttpClient();
using(var response = client.Post("http://localhost:8080/ScreenPictureService/Create", dataContract))
{
response.EnsureStatusIs(HttpStatusCode.OK);
}
I have received Bad Request 400
UPDATE 2
I found my problems:
I use JSON.NET to serialize my object, and when I receive byte array it convert to base64 format, but my service expect byte array - it solved to use list of bytes.
And second problem - I try to receive screnshot of my desctop with high defenition, and i have the same response(Bad Request 400), if I change picture resolution to 800x600, service works well, and there is my question - How to increase quota of request message. I try yo use, inside standardEndpoint section(web.config)
readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"
But it doesn't work

Have you tried monitoring the exact request / response with a tool like Fiddler? Perhaps your post is not as you would expect it to be?
Does the WCF service know to accept REST? If you are not using the WCF.WebApi there is usually the horrible wcf bindings to configure, eg:
<service name="MyWcfServiceWebRole.xyz.IAbcService">
<endpoint address="" behaviorConfiguration="webby" binding="webHttpBinding" bindingConfiguration="RestBinding" contract="MyWcfServiceWebRole.xyz.IAbcService" />
</service>
<behaviors>
<endpointBehaviors>
<behavior name="webby">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
Does a simple REST Get work?

I suggest Hammock, it's easy and works well.

The error 400 Bad request can be due to many possiblities. Try enabling tracing on your service. It can be done by following the link here.
Also if you have a config file with configuration make sure you have the readerQuotas sepecified as below if you are using webHttpBinding:
<webHttpBinding>
<binding name="RestBinding">
<readerQuotas maxStringContentLength="5242880" maxArrayLength="16384"
maxBytesPerRead="4096" />
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
If you are using the REST API with defining your service with routes in global.asax and using a standard endpoint use the below:
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true">
<readerQuotas maxStringContentLength="5242880" maxArrayLength="4194304"
maxBytesPerRead="4194304" />
</standardEndpoint>

Related

Byte[]/stream through namedPipe WCF is faulted

I am developping a namedpipe Duplex WCF service.
For the basic things, the client and the server are communicating without issue. The server can callback the client sending him strings, and it does it without any issue.
But, when i want it to send a bitmap with byte[] or stream, everything is faulting. Just note i tried to use the stream because the byte[] is not working...
In server side, the byte[]/stream is generated without issue.
But when the server sends the byte[]/stream to the client,if the byte[]/stream is empty it goes through but when it has data it is faulting.
I already checked all my configurations, and tried to set a large buffer/message/poolsize/stringcontent/arraylenght/byteperread/whatever size/lenght because i know that's a classic issue in WCF.
Here is a C/P of the main part of my WCF Config file.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true"/>
</system.web>
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NamedPipeBinding_ICameraService" closeTimeout="00:05:00" openTimeout="00:20:00" receiveTimeout="00:20:00" sendTimeout="00:20:00" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" maxConnections="10" maxBufferPoolSize="500000000" maxBufferSize="500000000" maxReceivedMessageSize="500000000">
<readerQuotas maxDepth="32" maxStringContentLength="500000000" maxArrayLength="500000000" maxBytesPerRead="500000000" maxNameTableCharCount="500000000"/>
<security mode="Transport"/>
</binding>
</netNamedPipeBinding>
</bindings>
<services>
<service name="EOSDigital.CameraService" behaviorConfiguration="MEX">
<endpoint address="net.pipe://localhost/EOSDigital/CameraService" binding="netNamedPipeBinding" bindingConfiguration="NamedPipeBinding_ICameraService" contract="EOSDigital.ICameraService"/>
<endpoint address="net.pipe://localhost/EOSDigital/CameraService/mex" binding="mexNamedPipeBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MEX">
<serviceMetadata httpGetEnabled="False"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Here is the service callback contract
[ServiceContract]
public interface ICameraServiceCallBack
{
[OperationContract(IsOneWay = true)]
void CallBackFunction(string str);
[OperationContract(IsOneWay = true)]
void LiveviewUpdated(byte[] img);
}
And here is the declaration of my Service contract.
[ServiceContract(CallbackContract = typeof(ICameraServiceCallBack))]
public interface ICameraService
I wont put everything, this is too huge.
This is how i use it
private void CurrentCamera_LiveViewUpdated(object sender, Stream img)
{
MemoryStream data = new MemoryStream();
img.CopyTo(data);
_callback = OperationContext.Current.GetCallbackChannel<ICameraServiceCallBack>();
_callback.CallBackFunction("this is a test"); // ok
_callback.LiveviewUpdated(data.ToArray()); //Faulted
}
I get the Stream from a Canon digital Camera and it is around byte[146242]. When i send a byte[10] it works.
It has to be a problem of size, and I guess i missed something in the config file ...
I also tried to generate and take a look to the scvclog file of my service to see some details of the occurring faulted exception.
But, well... There is not less than 50k characters in one line. This is not readable.
Thank you.
Check your client WCF configuration.
Your client configuration must have the same netNamedPipeBinding as your host.
Put that in your client config file
<netNamedPipeBinding>
<binding name ="duplexEndpoint" closeTimeout="00:05:00" openTimeout="00:20:00" receiveTimeout="00:20:00" sendTimeout="00:20:00" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="50000000" maxBufferSize="50000000" maxConnections="10" maxReceivedMessageSize="50000000">
<readerQuotas maxDepth="32" maxStringContentLength="50000000" maxArrayLength="50000000" maxBytesPerRead="50000000" maxNameTableCharCount="50000000"/>
</binding>
</netNamedPipeBinding>
This have to be put bellow the serviceModel.Bindings bracket.
Then, bind the configuration in your endpoint bracket
bindingConfiguration="duplexEndpoint"
That should do what you expected.

How to supply both UserName and Client Certificate in WCF client (why does this example work)?

Consider a WCF service in which the intent is to have Client Certificates required at the Transport layer (Client Certificates set to "Required" in IIS). As well, there will be username authentication at the message layer.
Now I've seen this question already:
WCF Client Certificate AND UserName Credentials forbidden
and I can somewhat understand what's going on there and realize that inherently WCF does not allow both. I went through the same steps in code as the poster in the link referenced above and found the same result...the message-level UserName credentials were being passed (in the SOAP header in my case), but the Client Cert (despite being attached when the request client is viewed in VS debug) was not actually being processed by the endpoint.
So now comes the part that has me confused. I decided to hack it somewhat. I'm wondering why this works exactly like I'm wanting...it gets past IIS Client Cert requirement, the UserName gets passed to the WCF Service and all just works. Yet WCF does not allow me to do it just using WCF config files or code (that I can find). Why?
// sets up a proxy client based on endpoint config
// basically just here to get the URL.
this.InitializeSubmitClient();
// these get used to create the HttpWebRequest
string url = this.submitClient.Endpoint.Address.ToString();
string action = "SubmitCDA";
// this deserializes an XML file which is the "shell" of SOAP document and inject username/password into SOAP Security node
XmlDocument soapEnvelopeXml = XMLHelper.CreateSoapDocument(this.txtSubmitCdaXmlFile.Text, this.txtAdAccount.Text, this.txtPassword.Text);
HttpWebRequest webRequest = XMLHelper.CreateWebRequest(url, action);
// saves the SOAP XML into the webRequest stream.
XMLHelper.InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// attach the cert
if (this.chkSendClientCert.Checked)
{
X509Certificate myCert = X509Certificate.CreateFromCertFile(#"C:\temp\CDX-IHAT_DevClientCert.cer");
webRequest.ClientCertificates.Add(myCert);
}
else
{
webRequest.ClientCertificates.Clear();
}
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
To further complicate matters, the WCF Service that this applies to is a BizTalk service.
Here's how I ended up doing it.
The Server Config:
<customBinding>
<binding name="CustomCDARequestEndpointBinding">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="UserNameOverTransport" />
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
The Client Config:
<system.ServiceModel>
<bindings>
<customBindings>
<binding name="CustomBinding_ITwoWayAsync">
<security defaultAlgorithmSuite="Default"
authenticationMode="UserNameOverTransport"
requireDerivedKeys="true"
includeTimestamp="true"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
>
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ohBehave">
<clientCredentials useIdentityConfiguration="false">
<clientCertificate findValue="6D0DBF387484B25A16D0E3E53DBB178A366DA954" storeLocation="CurrentUser"
x509FindType="FindByThumbprint" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="https://myservice/CDASubmitService/CDASubmit.svc"
binding="customBinding" bindingConfiguration="SubmitDev" behaviorConfiguration="ohBehave"
contract="CDASubmitService.CDASubmit" name="SubmitDev" />
</client>
</system.serviceModel>
The key to getting it working was the <httpsTransport requireClientCertificate="true" /> element and the <security authenticationMode="UserNameOverTransport" element/attribute.
This configuration allowed me to submit a message to a WCF (BizTalk) service completely through configuration files, with no changes to actual code. It still allows me to submit to it VIA WebRequest as well, as shown above.
I have to give credit to this post:
WCF Client Certificate AND UserName Credentials forbidden
as well as this one:
Translate non-BizTalk WCF config into BizTalk WCF-Custom endpoint
for finally getting me on the right track. I always shied away from Custom Bindings in WCF because I assumed it was overkill, but they are really nothing crazy, just a way to supply more detailed config than is available out of the box.

WCF service returns HTML when request exceeds 4MB

Calling my WCF service from my client silverlight app, I sometimes get a ProtocolException:
The content type text/html; charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8).
Normally, I can step into the WCF service code and see it build an object then return it in serialised form.
But when the request exceeds ~4MB (as reported by Fiddler2), breakpoints in the WCF service code are not hit, and the content of the response (where the serialised object should be) is the HTML for the standard HTML page you'd see if you browsed to the service - the one that looks like this:
I can make any request fail or succeed by randomly adding characters to strings within the request object graph, or trimming chunks off the graph, so I'm fairly confident this is about the size of the request.
I'd be really grateful if anyone could explain why the response contains HTML, and even more grateful if you can tell me how to fix it.
I'm using VS2010. My server side config is:
<httpRuntime executionTimeout="10800"
maxRequestLength="10240" />
...
<system.web>
<httpRuntime maxRequestLength="2147483647" />
</system.web>
...
<serviceBehaviors>
<behavior name="StandardServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
...
<binding name="BasicHttpBinding_SilverlightService"
useDefaultWebProxy="false"
transferMode="Streamed"
bypassProxyOnLocal="true"
receiveTimeout="00:20:00"
sendTimeout="00:20:00"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
maxBufferPoolSize="2147483647">
<readerQuotas maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxDepth="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None"/>
</security>
</binding>
And client-side I have:
<binding name="BasicHttpBinding_SilverlightService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
Update
I've also tried removing the name from the binding tag, as suggested by this post.
Have you had a look at this post:
http://smehrozalam.wordpress.com/2009/01/29/retrieving-huge-amount-of-data-from-wcf-service-in-silverlight-application/
You obviously have the dataContractSerializer section covered, just wondering whether anything else is missing.

Large Binary (byte[]) File transfer through WCF

I am trying to build a WCF service that allows me to send large binary files from clients to the service.
However I am only able to successfully transfer files up to 3-4MB. (I fail when I try to transfer 4.91MB and, off course, anything beyond)
The Error I get if I try to send the 4.91MB file is:
Exception Message: An error occurred while receiving the HTTP response to http://localhost:56198/Service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
Inner Exception Message: The underlying connection was closed: An unexpected error occurred on a receive.
Inner Exception Message: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Inner Exception Message: An existing connection was forcibly closed by the remote host
This error occurs at client side as soon as the byte[] file is sent as a method parameter to the exposed service method.
I have a breakpoint at the service method's first line, in case of successful file transfers (below 3MB) that break point is hit and the file gets transferred. However in this case as soon as the method is called, the error comes. The breakpoint in the service is not hit in case of this error.
I am going to paste my sections of my Service Web.config and Asp Page (Client) Web.config. If you also require the code that send the file and accepts the file, let me know, I'll send that as well.
Service Web.Config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpEndpointBinding" closeTimeout="01:01:00"
openTimeout="01:01:00" receiveTimeout="01:10:00" sendTimeout="01:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483646" maxBufferPoolSize="2147483646" maxReceivedMessageSize="2147483646"
messageEncoding="Mtom" textEncoding="utf-8" transferMode="StreamedRequest"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483646" maxStringContentLength="2147483646" maxArrayLength="2147483646"
maxBytesPerRead="2147483646" maxNameTableCharCount="2147483646" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="DragDrop.Service.ServiceBehavior" name="DragDrop.Service.Service">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpEndpointBinding" contract="DragDrop.Service.IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DragDrop.Service.ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Client (Asp.net page) Web.Config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483646" maxBufferPoolSize="2147483646" maxReceivedMessageSize="2147483646"
messageEncoding="Mtom" textEncoding="utf-8" transferMode="StreamedResponse"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483646" maxStringContentLength="2147483646" maxArrayLength="2147483646"
maxBytesPerRead="2147483646" maxNameTableCharCount="2147483646" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="">
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="debuggingBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://localhost:56198/Service.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference.IService"
name="BasicHttpBinding_IService" behaviorConfiguration="debuggingBehaviour" />
</client>
</system.serviceModel>
(While I agree that streaming transfer would be preferrable, the below should make it work without any other changes)
You also need to increase the maximum message length in the Web.config:
<configuration>
<system.web>
<httpRuntime maxMessageLength="409600"
executionTimeoutInSeconds="300"/>
</system.web>
</configuration>
This will set the maximum message length to 400 MB (parameter is in kB). Check this MSDN page for more information.
As pointed out, try using Streaming Transfer, here's some example code showing both sending and receiving (possibly) large amounts of data using streamed transfer.
Use a binding like this, notice the MaxReceivedMessageSize and TranferMode settings.
<binding name="Streaming_Binding" maxReceivedMessageSize="67108864"
messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed">
</binding>
Add some service code:
[OperationContract]
public Stream GetLargeFile()
{
return new FileStream(path, FileMode.Open, FileAccess.Read);
}
[OperationContract]
public void SendLargeFile(Stream stream)
{
// Handle stream here - e.g. save to disk
ProcessTheStream(stream);
// Close the stream when done processing it
stream.Close();
}
And some client code:
public Stream GetLargeFile()
{
var client = /* create proxy here */;
try
{
var response = client.GetLargeFile();
// All communication is now handled by the stream,
// thus we can close the proxy at this point
client.Close();
return response;
}
catch (Exception)
{
client.Abort();
throw;
}
}
public void SendLargeFile(string path)
{
var client = /* create proxy here */;
client.SendLargeFile(new FileStream(path, FileMode.Open, FileAccess.Read));
}
Also, make sure you are not getting a timeout, a large file might take a while to transfer (the default receiveTimeout is 10 minutes though).
You can download Microsoft WCF/WF sample code here (top C# link is broken at the time of writing but other samples code seems ok).
Have you had a look at using Streaming Transfer?
Windows Communication Foundation (WCF)
can send messages using either
buffered or streamed transfers. In the
default buffered-transfer mode, a
message must be completely delivered
before a receiver can read it. In
streaming transfer mode, the receiver
can begin to process the message
before it is completely delivered. The
streaming mode is useful when the
information that is passed is lengthy
and can be processed serially.
Streaming mode is also useful when the
message is too large to be entirely
buffered.
http://msdn.microsoft.com/en-us/library/ms789010.aspx
I'll echo what others have said and say that using a Streaming Transfer is the way to go when using Windows Communication Foundation. Below is an excellent guide that explains all of the steps in order to stream files over WCF. It's quite comprehensive and very informative.
Here it is: Guide on Streaming Files over WCF.

WCF Service Client: The content type text/html; charset=utf-8 of the response message does not match the content type of the binding

I've got a WCF Service running on my local IIS server. I've added it as a service reference to a C# Website Project and it adds fine and generates the proxy classes automatically.
However, when I try and call any of the service contracts, I get the following error:
Description: An unhandled exception occurred during the
execution of the current web request.
Please review the stack trace for more
information about the error and where
it originated in the code.
Exception Details: System.ServiceModel.ProtocolException:
The content type text/html;
charset=utf-8 of the response message
does not match the content type of the
binding (application/soap+xml;
charset=utf-8). If using a custom
encoder, be sure that the
IsContentTypeSupported method is
implemented properly. The first 1024
bytes of the response were: '
function
bredir(d,u,r,v,c){var w,h,wd,hd,bi;var
b=false;var p=false;var
s=[[300,250,false],[250,250,false],[240,400,false],[336,280,false],[180,150,false],[468,60,false],[234,60,false],[88,31,false],[120,90,false],[120,60,false],[120,240,false],[125,125,false],[728,90,false],[160,600,false],[120,600,false],[300,600,false],[300,125,false],[530,300,false],[190,200,false],[470,250,false],[720,300,true],[500,350,true],[550,480,true]];if(typeof(window.innerHeight)=='number'){h=window.innerHeight;w=window.innerWidth;}else
if(typeof(document.body.offsetHeight)=='number'){h=document.body.offsetHeight;w=document.body.offsetWidth;}for(var
i=0;i
I also have a console application which also communicates with the WCF Service and the console app is able to call methods fine without getting this error.
Below are excerpts from my config files.
WCF Service Web.Config:
<system.serviceModel>
<services>
<service name="ScraperService" behaviorConfiguration="ScraperServiceBehavior">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IScraperService"
contract="IScraperService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://example.com" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IScraperService"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2000000" maxReceivedMessageSize="2000000"
messageEncoding="Text" textEncoding="utf-8"
useDefaultWebProxy="true" allowCookies="false">
<readerQuotas
maxDepth="2000000" maxStringContentLength="2000000"
maxArrayLength="2000000" maxBytesPerRead="2000000"
maxNameTableCharCount="2000000" />
<reliableSession
enabled="false" ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ScraperServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Website Project Service Client Web.Config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IScraperService"
closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8"
useDefaultWebProxy="true" allowCookies="false">
<readerQuotas
maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384" maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<reliableSession enabled="false"
ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint name="WSHttpBinding_IScraperService"
address="http://example.com/ScraperService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IScraperService"
contract="ScraperService.IScraperService" >
<identity>
<servicePrincipalName value="host/FreshNET-II" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I had a similar issue. I resolved it by changing
<basicHttpBinding>
to
<basicHttpsBinding>
and also changed my URL to use https:// instead of http://.
Also in <endpoint> node, change
binding="basicHttpBinding"
to
binding="basicHttpsBinding"
This worked.
Try browsing to http://localhost/ScraperService.svc in the web browser on the server hosting the service, using the same Windows credentials that the client normally runs under.
I imagine that IIS is displaying an html error message of some description instead of returning xml as expected.
This also can occur when you have an http proxy server that performs internet filtering. My experience with ContentKeeper is that it intercepts any http/https traffic and blocks it as "Unmanaged Content" - all we get back is an html error message. To avoid this, you can add proxy server exception rules to Internet Explorer so that the proxy doesn't intercept traffic to your site:
Control Panel > Internet Options > Connections > LAN Settings > Advanced > Proxy Settings
An HTML response from the web server normally indicates that an error page has been served instead of the response from the WCF service. My first suggestion would be to check that the user you're running the WCF client under has access to the resource.
what's going on is that you're trying to access the service using wsHttpBind, which use secured encrypted messages by default (secured Messages).
On other hand the netTcpBind uses Secured encrypted channels. (Secured Transport)... BUT basicHttpBind, doesn't require any security at all, and can access anonymous
SO. at the Server side, Add\Change this into your configuration.
<bindings>
<wsHttpBinding>
<binding name="wsbind">
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
then add change your endpoint to
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsbind" name="wshttpbind" contract="WCFService.IService" >
That should do it.
As with many, in my situation I was also getting this because of an error. And sadly I could just read the CSS of the html error page.
The source of my problem was also a rewrite rule on the server. It was rewriting http to https.
I tried all the suggestions above, but what worked in the end was changing the Application Pool managed pipeline from Integrated mode to Classic mode.
It runs in its own application pool - but it was the first .NET 4.0 service - all other servicves are on .NET 2.0 using Integrated pipeline mode.
Its just a standard WCF service using is https - but on Server 2008 (not R2) - using IIS 7 (not 7.5) .
In my WCF serive project this issue is due to Reference of System.Web.Mvc.dll 's different version. So it may be compatibility issue of DLL's different version
When I use
System.Web.Mvc.dll version 5.2.2.0 -> it thorows the Error The content type text/html; charset=utf-8 of the response message
but when I use
System.Web.Mvc.dll version 4.0.0.0 or lower -> it works fine.
I don't know the reason of different version DLL's issue but by changing the DLL's verison it works for me.
This Error even generate when you add reference of other Project in your WCF Project and this reference project has different version of System.Web.Mvc DLL or could be any other DLL.
NOTE: If your target server endpoint is using secure socket layer (SSL) certificate
Change your .config setting from basicHttpBinding to basicHttpsBinding
I am sure, It will resolve your problem.
In my case a URL rewrite rule was messing with my service name, it was rewritten as lowercase and I was getting this error.
Make sure you don't lowercase WCF service calls.
You may want to examine the configuration for your service and make sure that everything is ok. You can navigate to web service via the browser to see if the schema will be rendered on the browser.
You may also want to examine the credentials used to call the service.
I had a similar situation, but the client config was using a basicHttpBinding. The issue turned out to be that the service was using SOAP 1.2 and you can't specify SOAP 1.2 in a basicHttpBinding. I modified the client config to use a customBinding instead and everything worked. Here are the details of my customBinding for reference. The service I was trying to consume was over HTTPS using UserNameOverTransport.
<customBinding>
<binding name="myBindingNameHere" sendTimeout="00:03:00">
<security authenticationMode="UserNameOverTransport" includeTimestamp="false">
<secureConversationBootstrap />
</security>
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="4194304"
maxReceivedMessageSize="4194304" allowCookies="false" authenticationScheme="Basic"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="4194304" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" requireClientCertificate="false" />
</binding>
</customBinding>
Even if you don't use network proxy, turning 'Automatically detect settings' in proxy dialog makes this exception go off.
If your are using both wshttpbinding along with https request, then i resolved it by using the below configuration change.
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate" />
</security>
I had a similar issue in my asp.net core 5 web api project to call a soap service. I resolved it by :
1.changing its url : return new System.ServiceModel.EndpointAddress("http://ourservice.com/webservices/service1.asmx?wsdl"); to https://ourservice.com/...
use these config in its Reference.cs :
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.TaxReturnSoap))
{
System.ServiceModel.BasicHttpsBinding result = new System.ServiceModel.BasicHttpsBinding();
result.TextEncoding = System.Text.Encoding.UTF8;
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
return result;
}
if ((endpointConfiguration == EndpointConfiguration.TaxReturnSoap12))
{
System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
System.ServiceModel.Channels.TextMessageEncodingBindingElement textBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
textBindingElement.WriteEncoding = System.Text.Encoding.UTF8;
textBindingElement.MessageVersion = System.ServiceModel.Channels.MessageVersion.CreateVersion(System.ServiceModel.EnvelopeVersion.Soap12, System.ServiceModel.Channels.AddressingVersion.None);
result.Elements.Add(textBindingElement);
System.ServiceModel.Channels.HttpsTransportBindingElement httpBindingElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
httpBindingElement.AllowCookies = true;
httpBindingElement.MaxBufferSize = int.MaxValue;
httpBindingElement.MaxReceivedMessageSize = int.MaxValue;
result.Elements.Add(httpBindingElement);
return result;
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
X++
binding = endPoint.get_Binding();
binding.set_UseDefaultWebProxy(false);
Hy,
In my case this error appeared because the Application pool of the webservice had the wrong 32/64 bit setting. So this error needed the following fix: you go to the IIS, select the site of the webservice , go to Advanced setting and get the application pool. Then go to Application pools, select it, go to "Advanced settings..." , select the "Enable 32 bit applications" and make it Enable or Disable, according to the 32/64 bit type of your webservice.
If the setting is True, it means that it only allows 32 bit applications, so for 64 bit apps you have to make it "Disable" (default).
For me, it was the web app connection string pointing to the wrong database server.
In my case it was happening because my WCF web.config had a return character as its first line. It was even more frustrating because it was behind a load balancer and was happening only half the time (only one of the two web.configs had this problem).
This error happens also when :
targetNamespace is wrongly defined in the wsdl
or
when the ns2 is wrongly defined in the response (different from the ns in the request) . For example
request
<.. xmlns:des="http://zef/">
response
<ns2:authenticateResponse xmlns:ns2="http://xyz/">
i was getting this error in NavitaireProvider while calling BookingCommit service (WCF Service Reference)
so, when we get cached proxy object then it will also retrived old SigninToken which still may not be persisted
so that not able to authenticate
so as a solution i called Logon Service when i get this exception to retrieve new Token
I solved this problem by setting UseCookies in web.config.
<system.web>
<sessionState cookieless="UseCookies" />
and setting enableVersionHeader
<system.web>
<httpRuntime targetFramework="4.5.1" enableVersionHeader="false" executionTimeout="1200" shutdownTimeout="1200" maxRequestLength="103424" />
For me the issue was resolved when I commented the following line in Web.config
<httpErrors errorMode="Detailed" />
My solution was rather simple: backup everything from the application, uninstall it, delete everything from the remaining folders (but not the folders so I won't have to grant the same permissions again) then copy back the files from the backup.

Categories

Resources