The remote server returned an error: (400) Bad Request - wcf

I am trying to consume the WCF Restful Service. The Service config is as follows
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttp" maxReceivedMessageSize ="50000000" maxBufferPoolSize="50000000" >
<readerQuotas maxDepth="500000000" maxArrayLength="500000000" maxBytesPerRead="500000000" maxNameTableCharCount="500000000" maxStringContentLength="500000000"/>
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ItemTracker.ItemTrackerServiceBehavior" name="ItemTracker.ItemTrackerService">
<endpoint address="http://localhost:8003/ItemTracker/ItemTrackerService.svc" binding="wsHttpBinding" contract="ItemTracker.IItemTrackerService" bindingConfiguration="wsHttp">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ItemTracker.ItemTrackerServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The Interface is defined as follows
Imports System.ServiceModel.Web
<ServiceContract([Namespace]:="http://localhost:8003/ItemTracker/")> _
Public Interface IItemTrackerService
<OperationContract()> _
<WebInvoke(Method:="POST", RequestFormat:=WebMessageFormat.Xml, ResponseFormat:=WebMessageFormat.Xml, UriTemplate:="GetItemTrackingDetails")> _
Function GetItemTrackingDetails(ByVal TrackingNo As String) As String
End Interface
The Calling of Restful service in client application is as follows
Dim req As HttpWebRequest = Nothing
Dim res As HttpWebResponse = Nothing
Dim url As String = "http://localhost:8003/ItemTracker/ItemTrackerService.svc?wsdl/GetItemTrackingDetails/"
req = DirectCast(WebRequest.Create(url), HttpWebRequest)
req.Method = "POST"
req.ContentType = "application/soap+xml; charset=utf-8"
req.Timeout = 30000
req.Headers.Add("SOAPAction", url)
Dim xmlDoc As New System.Xml.XmlDocument()
xmlDoc.XmlResolver = Nothing
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory & "\test.xml")
Dim sXML As String = xmlDoc.InnerXml
req.ContentLength = sXML.Length
Dim sw As New System.IO.StreamWriter(req.GetRequestStream())
sw.Write(sXML)
sw.Close()
res = DirectCast(req.GetResponse(), HttpWebResponse)
The input xml is this.
<GetItemTrackingDetails xmlns="http://localhost:8003/ItemTracker/">
<TrackingNo>A10001</TrackingNo>
</GetItemTrackingDetails>
Instead of localhost system name is used
The output of GetItemTrackingDetails is xml. With this I am getting bad request 400 instead of xml
Is there anyone to help me out.

This url looks strange:
Dim url As String = "http://localhost:8003/ItemTracker/ItemTrackerService.svc?wsdl/GetItemTrackingDetails/"
Does it work better if you remove ?wsdl?
Dim url As String = "http://localhost:8003/ItemTracker/ItemTrackerService.svc/GetItemTrackingDetails/"

You don't need to specify the url to the actual service, just the url mask:
http://localhost:8003/ItemTracker/GetItemTrackingDetails/
Furthermore you have to add a placeholder into your url mask to contain the input parameter to your operation:
UriTemplate:="GetItemTrackingDetails/{0}"
This allows you to call the actual url and pass the TrackingNo variable at the end of the url:
http://localhost:8003/ItemTracker/GetItemTrackingDetails/999AAA

Related

How to invoke web service in client which has CustomBinding endpoints?

I have WCF web service with custombinding as endpoint. I would like to invoke this web service (hosted on IIS) from my client application.
The service contract looks as below:
[ServiceContract(Namespace = "http://schemas.microsoft.com/windows/management/2012/01/enrollment")]
[XmlSerializerFormat]
public interface IDiscoveryService
{
[OperationContract(Name = "Get")]
[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Xml, ResponseFormat=WebMessageFormat.Xml)]
string DiscoveryGet();
}
The Web.COnfig file contents looks like:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<services>
<service name="DiscoveryWebService.DiscoveryService">
<endpoint address="" binding="customBinding" bindingConfiguration="NewBinding0"
contract="DiscoveryWebService.IDiscoveryService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
The client application codes looks like:
string uri = " http://localhost/EnrollmentServer/Discovery.svc";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
req.ContentType = "unknown";
req.Method = "GET";
WebResponse response = req.GetResponse();
StreamReader loResponseStream = new StreamReader(response.GetResponseStream(), false);
string responseString = loResponseStream.ReadToEnd();
I am getting HTML content of WSDL file instead of the string returned by Get method. I am not getting whether I am doing it in the right way or not?
I would appreciate the help in this regard.
The [WebGet] (and [WebInvoke]) attribute is only honored for an endpoint which uses the webMessageEncoding binding element; with a HTTP transport with the manualAddressing property set to true, and also the <webHttp/> endpoint behavior - which your service doesn't have. If you make the changes listed below, it should work:
Service contract:
[ServiceContract(Namespace = "http://schemas.microsoft.com/windows/management/2012/01/enrollment")]
[XmlSerializerFormat]
public interface IDiscoveryService
{
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
string DiscoveryGet();
}
Web.config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NewBinding0">
<webMessageEncoding />
<httpTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>
<services>
<service name="DiscoveryWebService.DiscoveryService">
<endpoint address="" binding="customBinding" bindingConfiguration="NewBinding0"
contract="DiscoveryWebService.IDiscoveryService" behaviorConfiguration="Web" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="Web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Client code:
string uri = "http://localhost/EnrollmentServer/Discovery.svc/DiscoveryGet";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
req.Method = "GET";
WebResponse response = req.GetResponse();
StreamReader loResponseStream = new StreamReader(response.GetResponseStream(), false);
string responseString = loResponseStream.ReadToEnd();

WCF restful service, server did not provide a meaningful reply

I am creating a restful service using WCF, I keep getting the error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
It is a time clock application, which takes in the username and the current time and stores it in a database for logging in/out.
I am new to the REST world can anyone help me?
My service interface:
ServiceContract(Namespace:="WCFRESTService")> _
Public Interface IService1
<OperationContract()> _
<WebInvoke(UriTemplate:="/login", Method:="PUT")> _
Function InsertUserDetails(ByVal username As String, ByVal time As DateTime) As String
End Interface
Service code:
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)> _
<ServiceBehavior(Namespace:="WCFRESTService")> _
Public Class Service1
Implements IService1
Private con As New SqlConnection("Data Source=TE-LAPTOP-001\SQL2008R2;Initial Catalog=timeClock;Integrated Security=True")
Public Function InsertUserDetails(ByVal username As String, ByVal time As DateTime) As String Implements IService1.InsertUserDetails
Dim strMessage As String = String.Empty
Dim errorMessage As String = String.Empty
Dim numcount As Integer = 0
numcount = getusercount(username)
If (numcount = 0) Then
Try
con.Open()
Dim cmd As New SqlCommand("spInsertLog", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#username", username)
cmd.Parameters.AddWithValue("#timein", time)
cmd.ExecuteNonQuery()
Catch ex As Exception
errorMessage = ex.ToString
Finally
con.Close()
End Try
strMessage = "You have Signed In at: " + time
ElseIf (numcount = 1) Then
strMessage = "Error: You need to SignOut before you can SignIn"
End If
Return errorMessage + strMessage
End Function
Public Function getusercount(ByVal username As String) As Integer
Dim count As Int32 = 0
Try
con.Open()
Dim cmd As New SqlCommand("spgetcount", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#username", username)
count = Convert.ToInt32(cmd.ExecuteScalar())
Catch ex As Exception
Finally
con.Close()
End Try
Return count
End Function
End Class
My client code
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim objervice As New ServiceReference1.Service1Client()
Dim result As String = objervice.InsertUserDetails("User1", DateTime.Now)
MsgBox(result)
End Sub
Service webconfig:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfRESTService1.Service1" behaviorConfiguration="WcfRESTService1.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="http://localhost:62131/Service1.svc" binding="webHttpBinding" contract="WcfRESTService1.IService1" behaviorConfiguration="web">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfRESTService1.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Client config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="WebHttpBinding_IService1">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost:62131/Service1.svc" binding="customBinding" bindingConfiguration="WebHttpBinding_IService1"
contract="ServiceReference1.IService1" name="WebHttpBinding_IService1" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="test">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
You don't need REST here (for such kind of client).
But if you want - try use stream for WebGet-responding from from REST method:
[OperationContract, WebGet(UriTemplate = "/SendMessage?login={login}&password={password}&phoneNum={phoneNum}&message={message}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
System.IO.Stream SendMessage(string login, string password, string phoneNum, string message, TimeSpan timeout);
//..
public Stream SendMessage(string login, string password, string phoneNum, string message, TimeSpan timeout)
{
//..
return new MemoryStream(Encoding.Default.GetBytes(jsonString));
}

WCF REST WebGet for user defined parameters

I have below operation contract with WebGet defined as follows.
[OperationContract]
[WebGet(UriTemplate = "UpdateUserDetails/?configdata={_userConfigData}&configresult={_configResult}&clientip={_clientIP}&adminname={AdminName}")]
public void UpdateUserDetails(UserConfigData _userConfigData, ConfigResult _configResult, string _clientIP, string AdminName)
When I run the service, I am getting below error. Any ideas how to fix this issue?
Operation 'UpdateUserDetails' in contract 'UserConfigService' has a query variable named '_userConfigData' of type Service1.WCF.UserConfig.UserConfigData', but type 'Service1.WCF.UserConfig.UserConfigData' is not convertible by 'QueryStringConverter'. Variables for UriTemplate query values must have types that can be converted by 'QueryStringConverter'.
I will assume that you use Json object to request data.
it should be like this:
[OperationContract]
[WebInvoke(UriTemplate = "UpdateUserDetails?_clientIP={_clientIP}&AdminName={AdminName}", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
public void UpdateUserDetails(UserConfigData _userConfigData, ConfigResult _configResult, string _clientIP, string AdminName)
And JSON data seems to be like this:
{
"_userConfigData":{
"Property1":"value",
"Property2":"value",
"Property3":"value"
..and so on...
},
"_configResult":{
"Property1":"value",
"Property2":"value",
"Property3":"value"
..and so on...
}
}
There is a good application for testing Rest services, you can try to use:
Fiddler
Additional Info
In response to the result "getting Method not found"
You may not have defined the endpoint or the service address properly. Your webconfig file should have this kind of config.
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="soapBinding">
<security mode="None"></security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webBinding"></binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!-- USING SOAP-->
<service behaviorConfiguration="defaultServiceBehavior" name="MyProject.WCF.UserConfig.UserConfigService">
<endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding" contract="MyProject.WCF.UserConfig.IUserConfigService"></endpoint>
</service>
<!-- USING JSON-->
<service behaviorConfiguration="defaultServiceBehavior" name="MyProject.WCF.UserConfig.UserConfigService">
<endpoint address="json" binding="webHttpBinding" bindingConfiguration="webBinding" behaviorConfiguration="jsonBehavior" contract="MyProject.WCF.UserConfig.IUserConfigService"></endpoint>
</service>
</services>
</system.serviceModel>
The address seems like this:
SOAP
localhost:1706/soap/UserConfigService.svc
JSON
localhost:1706/json/UserConfigService.svc
For better reference you could try to watch here:
How to create simple REST Based WCF Service with JSON format
you have to use string, u cant use an object as query string prameters. it wont convert your query string to an object. those variables should be defined as string.
Here's a link on implementing a custom QueryStringConverter, which will do what you want it to. Note also (mentioned in that post) that it might be better to pass a (possibly) complicated object like UserConfigData or ConfigResult as POST data, rather than in the URL. Considering your method is called "UpdateUserDetails", it's probably best to use a POST (WebInvoke) instead of a GET (WebGet) anyway, in the spirit of REST.

WCF problem with uploading large file, hosted in IIS

I am trying to upload large files to a WCF Service hosted in IIS.
I am using Restful and Streaming method.
But I am not able to upload files which is more than 64KB.
I tried lot by changing all the size-related elements in web.config file, but failed to fix the issue.
Here is my code and config, please let me know if anyone find any issues in the code and how can I fix.
Operation Contract
[OperationContract]
[WebInvoke(UriTemplate = "/UploadImage/{filename}")]
bool UploadImage(string filename, Stream image);
Implementation of Operation Contract
public bool UploadImage(string filename, Stream image)
{
try
{
string strFileName = ConfigurationManager.AppSettings["UploadDrectory"].ToString() + filename;
FileStream fileStream = null;
using (fileStream = new FileStream(strFileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 1024;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = image.Read(buffer, 0, bufferLen)) > 0)
{
fileStream.Write(buffer, 0, count);
}
fileStream.Close();
image.Close();
}
return true;
}
catch (Exception ex)
{
return false;
}
}
web.config
<system.serviceModel>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<endpoint address="http://localhost/WCFService1" behaviorConfiguration="web"
binding="webHttpBinding" bindingConfiguration="webBinding"
contract="IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding"
transferMode="Streamed"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
openTimeout="00:25:00" closeTimeout="00:25:00" sendTimeout="00:25:00"
receiveTimeout="00:25:00" >
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
and
<httpRuntime maxRequestLength="2097151"/>
Service is hosted in hosted in IIS
Client side Code (console application)
private static void UploadImage()
{
string filePath = #"F:\Sharath\TestImage\TextFiles\SampleText2.txt";
string filename = Path.GetFileName(filePath);
string url = "http://localhost/WCFService1/Service.svc/";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "UploadImage/" + filename);
request.Accept = "text/xml";
request.Method = "POST";
request.ContentType = "txt/plain";
FileStream fst = File.Open(filePath, FileMode.Open);
long imgLn = fst.Length;
fst.Close();
request.ContentLength = imgLn;
using (Stream fileStream = File.OpenRead(filePath))
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0)
{
requestStream.Write(buffer, 0, byteCount);
}
}
string result;
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
Console.WriteLine(result);
}
With this much of code I am able to upload 64KB of file, but when I try to upload a file of more than 64KB in size, I am getting error like,
The remote server returned an error: (400) Bad Request
i did what you told but still I am getting same problem, this is how my config looks like now, can you please tell me what is still missing here
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<endpoint address="http://localhost/WCFService1" behaviorConfiguration="web"
binding="webHttpBinding" bindingConfiguration="webBinding"
contract="IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding transferMode="Streamed"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
openTimeout="00:25:00" closeTimeout="00:25:00" sendTimeout="00:25:00" receiveTimeout="00:25:00"
name="webBinding">
<readerQuotas maxDepth="64"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
The large data transfer issue with wcf:
I have wcf 4.0 service hosted on IIS 7, windows 2008 server. When I call my service with small data say 4K or 5K bytes then request get processed easily but while trying to upload large size it gave me following errors
Bad Request 400
File not found 404 13 as seen in IIS 7 logs
There is no end point listening to the service "myservice url"
In all caseses I was able to transfer small data request with my client application to server but for large size message. Request failed.
I have tried all methods available to solve this issues but nothing worked for me.
After a scratching my head for a week and reading all articles and blogs finally I figured following
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="myBinding" closeTimeout="00:10:00" maxBufferPoolSize="250000000" maxReceivedMessageSize="250000000" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" messageEncoding="Text">
<readerQuotas maxDepth="4500000" maxStringContentLength="4500000" maxBytesPerRead="40960000" maxNameTableCharCount="250000000" maxArrayLength="4500000"/>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
<system.web>
<httpRuntime executionTimeout="4800" maxRequestLength="500000000"/>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="500000000"></requestLimits>
</requestFiltering>
</security>
</system.webServer>
<!-- other useful setting -->
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
So I think It may help someone days....
Based on the size mentioned by you, it seems error due to limit hit at the binding level i.e. readerQuota values. You can confirm if denial of server is due to exceeding the limit at binding level by capturing WCF traces. We can't see the configuration you've posted so, providing our best guess besed on information which is visible.
I'd capture WCF traces at verbose level to troubleshoot the issue.
Btw, have you tried increasing maxRequestLength?
http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.maxrequestlength.aspx
HTH,
Amit Bhatia
what fixed 404 size of the message too big problem for me was a part of WaseemM's example:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="500000000"></requestLimits>
</requestFiltering>
</security>
See...all of us who are facing this problem of 64KB upload thingy are missing the very basic point. We are setting high values for maxAllowedContentLength, maxReceivedMessageSize...blah blah but still nothing works :). We all miss the very basic point(...well at least I was) is no matter whatever binding configuration we set, are we anywhere mentioning that our ENDPOINT SHOULD FOLLOW THE BINDING CONFIG????...no where...So basically we must let the ENDPOINT know that it must follow our BINDING CONFIG.
<endpoint address=""
binding="webHttpBinding"
behaviorConfiguration="Your behaviour config name"
bindingConfiguration="YOUR BINDING CONFIG NAME"
contract="Your contract service" />
If transferring large data is if your task you should use MTOM. Just search for "MTOM WCF".
Chandrachur is correct, whatever you specify in your <binding/> or <readerQuotas/>, you need to add "bindingConfiguration="my binding config name" in your <endpoint/>. Otherwise it won't work even if your binding config is correct. you need to make sure your configs are applied to your endpoint. to do so, you need "bindingConfiguration" set correctly.

How to read stream from WCF service

I have created a WCF service to stream files(download). Code for the service is below
public Stream GetCoverScan(List<string> productIDs)
{
FileStream stream = new FileStream("", FileMode.Open, FileAccess.Read);
return stream;
}
Can some one tell me how do i consume this on the client side. I have already created a proxy on client and i can see the method by creating an object of the service, but how do i read the stream.
Please advise
Configuration
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="StreamedHttp" transferMode="StreamedResponse"
maxReceivedMessageSize="67108864">
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Streaming.Service1"
behaviorConfiguration="Streaming.Service1Behavior">
<endpoint address="" bindingConfiguration="StreamedHttp"
binding="basicHttpBinding" contract="Streaming.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Streaming.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Contract
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(string name);
[OperationContract]
System.IO.Stream GetCoverScan(List<string> productIDs);
}
bindings
</bindings>
You need to configure streaming on the binding you use. Streaming is supported for BasicHttpBinding, NetTcpBinding, and NetNamedPipeBinding. So if you have a BasicHttpBinding, your configuration should look like this:
<basicHttpBinding>
<binding name="HttpStreaming" maxReceivedMessageSize="67108864"
transferMode="StreamedResponse"/>
</basicHttpBinding>
I use StreamedResponse here because you only have a response that should be a stream, not a request.
How you read the stream itself depends on what's in it. Suppose you send a text file over a stream, you can use a StreamReader:
var reader = new StreamReader(service.GetCoverScan(...));
string contents = reader.ReadToEnd();
If you send an xml file, you can read it through XDocument:
var doc = XDocument.Load(service.GetCoverScan(...));
So it really depends on what you're sending over the wire.
If you mention
response.ContentType = "text/xml"
just before returning stream, the receiving application can know the type of the stream thus can invoke standard way of stream as a reference.