Wcf wsDualHttpBinding Max message length 16384 reached - wcf

I cannot get to work a wsDualHttpBinding endpoint on my WCF service.
I'm facing this problem on the client.
I get an exception that suggests to increment MaxArrayLength from 16384 to allow to read the whole xml data.
I tried the following configuration:
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="MyBinding" maxReceivedMessageSize="2147483647" />
</wsDualHttpBinding>
</bindings>
<client>
<endpoint name="WSDualHttpBinding_IDataService" binding="wsDualHttpBinding" bindingConfiguration="MyBinding"
address="http://localhost:8733/DataProvider/" contract="DataStorageService.IDataService" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
But the above configuration seems to be ignored.
I instantiate my client like this:
var instanceContext = new InstanceContext( new CallbackHandler() );
_clientService = new DataServiceClient( instanceContext );
and i read somewhere that these line of codes override the configuration in app.config; if that't the problem, how can i increment quotas?
Any help appreciated.

You have to configure more than just maxReceivedMessageSize.
As Jonathan Coffey said, there is BytePerRead, TableCharCount, StringContentLenght, etc.
You also have to configure the readerQuotas : https://msdn.microsoft.com/en-us/library/ms731325(v=vs.110).aspx
Note that you have to configure the server the exact same way you configured your client, and you can't set a maxbytearraylengh't greater than your maxreceivedmessagesize, obviously.
If the server doesn't have the same MaxReceivedMessageSize or whatever, it won't work as you expected, for example.
GL.

You do exactly what the error tells you :)
For this it might be best to see visually how to do it rather than copy and paste code.
In your project, Right click your service "app.config" and choose "Edit WCF Configuration" from there click on "Bindings" and you should see your custom binding. If not just right click and create a new binding. From here you can change the "ReaderQuotas Properties" what I use is
MaxArrayLength = 2147483647
MaxBytesPerRead = 4096
MaxDepth = 32
MaxNameTableCharCount = 2147483647
MaxStringContentLength = 2147483647
Once that is done, go ahead and press "File" and then "Save"
Now go view your app.config code and it should have updated.
Run your service and then right click your service references and "Update Service Reference"
Now if you look at your client app.config file it should match what your service app.config attributes looked like. If this is not the case then right click your clients app.config and "Edit WCF Configuration" again, go to bindings and then choose your service endpoint and change the values to the same as the service.
Be aware though settings the values that high will leave you vulnerable to ddos attacks etc. so find out what you need and change it after testing.
Hope this helps :)
Make sure your service is running as administrator also

Related

Getting "EndPoint Not Found" error with WCF service deployed to SharePoint 2010 site

I am trying to utilize the autocompleteextender from the ajaxcontroltoolkit in one of my sharepoint solutions (which requires an older version of the library since all of the recent ones require the .NET Framework 4.0) and unfortunately I can't use a page method in a UserControl, only in an actual page. Therefore I am left with only the one option which is to use a method from an actual web service. The problem is that I can't seem to figure out how to correctly deploy the service and configure the web.config. When I try to view the metadata information in the browser I get an error message saying "endpoint not found". However, when I try to enter the URL with the name of a method appended to the URL it actually finds AND executes the method returning JSON data -which obviously means that it can find my service. Also, I can use jQuery to call my service and return the JSON data -but I don't want to use jQuery for this project and would rather just keep everything pure C#.
What I want to know is, why can't I get the "pretty metadata information" to display in the browser so I get the "warm fuzzy" and allow the proper discovery of the service by other applications the way it should be working?
I triple checked the web.config and I have both the metadataExchange endpoint as well as the one that references my service both entered and I have httpGetEnabled set to "true". I tried running svcutil /t:metadata and pointed it to my service but I get several errors, the first telling me that it can't obtain the metadata, the second that the Metadata contains a reference that cannot be resolved and the third is an HTTP GET Error that says the HTML document does not contain Web service discovery information. Even though I have my svc file in the same ISAPI directory as the OOTB SharePoint services and can generate the XSD files for those services but not for mine.
Here is what my current web.config file looks like...
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" />
<identity impersonate="true"/>
</system.web>
<system.serviceModel>
<!-- we need this to enable session -->
<client>
</client>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<behaviors>
<endpointBehaviors>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataSupportBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://myserver/sites/mysitecollection/_vti_bin/WebServices/MyService.svc" policyVersion="Policy15"/>
<!-- 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"/>
<serviceAuthorization impersonateCallerForAllOperations="false"/>
<serviceCredentials>
<windowsAuthentication includeWindowsGroups="true" />
</serviceCredentials>
</behavior>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
</bindings>
<services>
<service behaviorConfiguration="metadataSupportBehavior" name="Sample.WebServices.MyService">
<clear />
<endpoint address="" binding="basicHttpBinding" contract="Sample.WebServices.IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://myserver/sites/mysitecollection/_vti_bin/WebServices/MyService.svc" />
</baseAddresses>
</host>
</service>
</services>
I'm at a real loss here. Any thoughts?
Thanks in advance!!!
UPDATE #1: OK, I almost got it working. I mean I "technically" did but only in the browser and with a few caveats.
The first thing I did was add the following code to my web.config file:
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
And then updated my service endpoint to include a reference to the new configuration like so:
<endpoint address="" binding="webHttpBinding" contract="Sample.WebServices.IMyService" behaviorConfiguration="webBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
I also changed the binding from basicHttpBinding to webHttpBinding.
Now for the caveats...
I can get it to fully function and return an XML response in the browser but ONLY if I run the service in debug mode, which means that it's being hosted in Visual Studio and not IIS so it doesn't really count.
When I don't run the service in debug mode I get an error that says something to the effect of "The exception message is 'Value cannot be null. Parameter name: source'".
After stepping through my code in the debugger I see the real error which is:
Request for the permission of type 'IBM.Data.DB2.DB2Permission, IBM.Data.DB2, Version=9.0.0.2, Culture=neutral, PublicKeyToken=7c307b91aa13d208' failed.
Which in simple English means that I am trying to load a 32-Bit version of the IBM.Data.DB2 DLL in my SharePoint site that unfortunately only allows 64-Bit assemblies.
So my first reaction is "Ah ha!" this should be simple right? I mean I either need to find a 64bit version of the DLL or just configure the Application Pool that my SharePoint site in IIS uses to allow 32bit assemblies to be loaded and everything should be peachy! Aren't I smart? But NO says SharePoint! Not only am I not going to let you do either of those things* but I'm going to completely render your entire SharePoint farm unusable for even attempting to implement such ludicrous solutions!!!
So now when I try to navigate to any resource within my SharePoint farm I'm greeted with this.
[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_ApplicationProperties() +134
Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_PartitionIDs() +44
Microsoft.Office.Server.Administration.UserProfileApplicationProxy.IsAvailable(SPServiceContext serviceContext) +329
Microsoft.Office.Server.WebControls.MyLinksRibbon.get_PortalAvailable() +44
Microsoft.Office.Server.WebControls.MyLinksRibbon.EnsureMySiteUrls() +60
Microsoft.Office.Server.WebControls.MyLinksRibbon.get_PortalMySiteUrlAvailable() +15
Microsoft.Office.Server.WebControls.MyLinksRibbon.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +65
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2427
Even if I undo all of my changes to IIS, the App Pool, the DLLs, restart IIS, restart my server etc. nothing works. I'm just totally screwed.
Good times.
*Well to be fair SharePoint had nothing to do with the 64-Bit IBM driver being unavailable but I'm just gonna assume that even if there was one that I could techically use that SharePoint would find a way to punish me for trying to get any work done.
UPDATE #2: OK, I fixed the whole "SharePoint site not working thing". Basically the Application Pools in use for all SharePoint related sites seemed to have changed to enable 32-Bit applications, including the SecurityTokenServiceApplication (kudos to the dude over at this site for not only having the same problem but also posting the solution). Now while I don't remember specifically setting the value to true for every SharePoint related Application Pool I'm willing to play along and say that perhaps in an act of desperation I may have just said to hell with it and started recklessly changing configuration settings. You know, because that's just what seasoned developers do.
Anyhow...
Now my Central Administration website is back up and running but the UserProfileApplication service is still wonky and I am still inclined to think that my SecurityTokenServiceApplication service is still on the fritz since I get an error (details hidden of course since the web.config is configured to do just that) telling me that "The server was unable to process the request due to an internal error".
Details to follow...
UPDATE #3: OK, I got everything back to it's original working form. I confirmed that merely enabling 32-Bit applications for one Application Pool used by a SharePoint resource effectively updates all the other ones to follow suit. I know this for a fact because I positively did not change that value for EVERY SharePoint related Application Pool myself. I would have remembered going through something like that. As it turns out all of those Application Pools with the funky looking "GUID-like" names that the SharePoint Web Services use were also all updated to allow 32-Bit applications to run which is what caused my environment to go all screwy.
In addition, I got my SecurityTokenService to display it's metadata in the browser correctly by following the suggestions provided here. Although they seem like a bit of a "hack", they are small and reversable hacks so I'm game.
In short, you edit the config files for each service like so:
In the spStsActAsBinding binding rename httpTransport to httpsTransport.
Add allowInsecureTransport=”true” and enableUnsecuredResponse=”true” to the binding security.
Ensure that you define only 1 binding configuration (for example in Profile Service, you will find 2 binding configuration for the same service each for http and https protocol).
After doing all this you should be able to get the "warm metadata fuzzy" that I'm trying to get for the custom WCF service I'm working on.
So now I just need to get back to fixing my initial problem which was to get the 32-Bit version of the IBM.Data.DB2 DLL to work with SharePoint 2010. The one thing I haven't tried yet is creating an IIS hosted service that runs COMPLETELY independent of SharePoint. Doing this would allow me to create a separate Application Pool that CAN in fact run 32-Bit applications without causing SharePoint to flip out -hopefully.
UPDATE #4: OK, so first of all I am going to tell you to ignore my advice above about messing around with the SecurityTokenService. Sure you get the "warm metadata fuzzy" with the changes but then you'll probably cause your SharePoint site's to break.
So anyway...I have now created a site that is totally independent of SharePoint that uses it's own Application Pool that is configured to allow 32-Bit applications so that technically should take care of all of my issues. Well, when I try typing text into my textbox it does not "autocomplete" but there is network activity happening because I see it in Fiddler. The strange part is that it only happens once. Meaning, if I hit backspace and retype something else no additional calls are made to the web service. I have to reload the page to test it out again. The error message I get when it does call the method is "405 Method Not Allowed". Now my method interface signature uses WebInvoke with the Method property set to "GET" which I've been told should work fine and has in the past when making REST calls that return JSON data, only now it doesn't work. Oh, in the web browser it works and I see wonderful XML results returned from the method. But when I try to use the AutoCompleteExtender in my SharePoint UserControl to call the method (or using any other client for that matter) it doesn't. I have tried using the WebGet() attribute but then nothing is returned in the web browser either. I think I got a 415 error for that one.
UPDATE #5: I found another post where some guy seems to be having the exact same problem that I am having now, only difference is that I can't get the autocomplete to work even if I have the webservice in the same project. I also tried the suggestions that were made in his post and they didn't work either. Here is a link to the post for those interested.
For webpart project (with ASCX) you can:
1) Enable Anonymous Authentication for SP SIte in IIS
2) Add SP Mapped folder ISAPI
3) Create YourService.asmx in ISAPI
<%# WebService Language="C#" Class="YourNamespace.YourService, YourAsm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=YourPublicKeyToken"%>
4) Edit user control code:
public partial class YourControl : UserControl
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
FixFormAction();
CheckScriptManager();
EnsureUpdatePanelFixups();
}
private void FixFormAction()
{
// Fix problem with postbacks and form actions (DevDiv 55525)
Page.ClientScript.RegisterStartupScript(GetType(), ID, "_spOriginalFormAction = document.forms[0].action;", true);
// By default, the onsubmit event for forms in SharePoint master pages call "return _spFormOnSubmitWrapper()"
// which blocks async postbacks after the first one. Not calling "_spFormOnSubmitWrapper()" breaks all postbacks
// and defeats the purpose of _spFormOnSubmitWrapper() which is to block repetitive postbacks.
// To call _spFormOnSubmitWrapper() and allow partial postbacks, remove "return" from the original call.
if (Page.Form != null)
{
string formOnSubmitAtt = Page.Form.Attributes["onsubmit"];
if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
}
}
private void EnsureUpdatePanelFixups()
{
if (this.Page.Form != null)
{
var fixupScript = #"
_spBodyOnLoadFunctionNames.push(""_initFormActionAjax"");
function _initFormActionAjax()
{
if (_spEscapedFormAction == document.forms[0].action)
{
document.forms[0]._initialAction = document.forms[0].action;
}
}
var RestoreToOriginalFormActionCore = RestoreToOriginalFormAction;
RestoreToOriginalFormAction = function()
{
if (_spOriginalFormAction != null)
{
RestoreToOriginalFormActionCore();
document.forms[0]._initialAction = document.forms[0].action;
}
}
";
ScriptManager.RegisterStartupScript(this, this.GetType(), "EnsureUpdatePanelFixup", fixupScript, true);
}
}
private ScriptManager CheckScriptManager()
{
ScriptManager sm = ScriptManager.GetCurrent(Page);
if (sm == null)
{
if (Page.Form != null)
{
sm = new ScriptManager();
sm.ID = Page.Form.ID + "_ScriptManager";
Page.Form.Controls.Add(sm);
//Page.Form.Controls.AddAt(0, sm);
}
}
sm.EnablePageMethods = true;
var sharedPath = #"~/_layouts/Share/";
var path = #"~/_layouts/YourWebPart/";
sm.Scripts.Add(new ScriptReference { Path = #"/_vti_bin/YourService.asmx/JS" });
//Registering ExtJS
Page.ClientScript.RegisterClientScriptInclude(GetType(), "ext-all", sharedPath + "scripts/ext-all.js");
ScriptManager.RegisterClientScriptBlock(this, GetType(), "ext-css",
"<link href='" +
sharedPath + "resources/css/ext-all.css' rel='stylesheet' type='text/css' />", false);
Page.ClientScript.RegisterClientScriptInclude(GetType(), "YourScript", path + "scripts/Script.js");
return sm;
}
}
5) Edit your service code:
[WebService(Namespace = "http://tempuri/ws")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class YourService : WebService
{
//[WebMethod]
[ScriptMethod]
[WebMethod(EnableSession = true)]
//[ScriptMethod(UseHttpGet = true)]
public string YourWebMethod(string arg)
{
return arg;
}
}
6) Use you web service methods in control javascript:
YourNamespace.YourService.YourWebMethod(arg, function (result) {
if (result) {
if (typeof result == 'string') {
alert(result);
}
}
}, function (error) { alert('YourWebMethod failed! ' + error.get_message()); });
}
No webconfig
For svc in ISAPI subfolder
<%# ServiceHost Debug="true" Language="C#"
Service="Namespace.MyService, MyAsm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=MyPublicKeyToken"
%>
web.config can be:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2097151"/>
</requestFiltering>
</security>
</system.webServer>
<system.web>
<httpRuntime executionTimeout="60" maxRequestLength="2097151" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyHttpBinding"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
<readerQuotas maxArrayLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CustomServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="CustomServiceBehaviour" name="Namespace.MyService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyHttpBinding" contract="Namespace.IMyService" bindingNamespace="http://tempuri/ws" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
So I still can't get the autocompleteextender to work with my WCF service but I did figure out how to fix the EndPoint Not Found error.
So there are three things at play here that I didn't fully understand or overlooked.
The WCF Client Test Utility from Microsoft only tests SOAP requests.
How all of the different bindings worked and what they meant.
That you need to make sure the right account is being used for the Anonymous User Identity in IIS.
With items #1 and #2 I needed to add another endpoint to handle soap requests that either used basichttpbinding or wshttpbinding. I had only one binding specified that was webhttpbinding and although that gave me the warm fuzzies in the browser it essentially caused the WCF Client Utility not to work because I basically didn't have any SOAP endpoints defined. Read more about the differences here.
As for item #3, I found my answer here. It took days of weaving through posts about changing the web.config, writing stuff in code with usernames and passwords to enabling and disabling every form of authentication type known to man in IIS. This was what ultimately did the trick and allowed me to use the WCF Client Test Utility without the pesky EndPoint Not Found error.
Also, for those of you that are interested, I've actually started a new post that focuses specifically on the ajaxcontroltookkit autocompleteextender issue that can be found here.
FYI: I have managed to get to the point where I can return identical JSON data from my WCF service that looks just like the JSON data that gets returned when the code is executed from the ASPX's CodeBehind page and actually works...but for some reason when using the WCF method nothing gets autocompleted. The only thing I notice that's different when using the WCF service method is that before getting the sweet http 200 message with the JSON data there is always an http 401 authentication error that precedes it.

WebHttpBinding message size quota exceeded

I am getting the following error:
The maximum message size quota for incoming messages (65536) has been exceeded.
To increase the quota, use the MaxReceivedMessageSize property on
the appropriate binding element.
I am using WebhttpBinding which uses REST service.
There is no configuration setting from client side.
I am using MVC3 application.
Need help in stream more than 65536 bytes.
Is there any way to edit the ServiceHostFactory behaviour so that somewhere I can set MaxReceivedMessageSize property to 2GB
thanks for your response.
Since I am using WebHttpBinding,I would like to know how to override the ServiceHostFactory .
Creating a custom class and overriding the OnOpening() method of WebServiceHost can resolve the problem or not?
MaxReceivedMessageSize is a property of the binding element; if you need to change it from the defaults you have two options:
Use a configuration file, and set it from within a binding element.
Create the bindings in code and set the property there.
To do this on the client side, without a configuration file, you'll need to bypass the normal service reference code and create the client channel yourself. You can see an example of how to do this on my blog post about using WCF without the auto-generated client proxy: Proxy-Free WCF. In essence, you do something like this in code:
var binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
var factory = new ChannelFactory<IServiceInterfaceChannel>(binding);
var client = factory.CreateChannel(new Endpoint(SERVICE_URL));
If you need to change the behavior on the service side, you can specify a binding by calling AddServiceEndpoint on the service host class, for example:
var host = new WebServiceHost();
var binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
host.AddServiceEndpoint(typeof(IServiceInterface), binding, SERVICE_URL);
Also, I think that you could accomplish this by overriding the OnOpening method of a custom web service host, as per your question. Be aware that the base OnOpening behavior potentially creates endpoints and edits binding behavior, so you will want to let it do all of that first, before you try to change the binding configurations yourself. But I'm not really sure why you would go to all that trouble...
Easiest way is to configure it in web.config where you can change it later if needed. First create binding configuration as mentioned below in your web.config or app.config
<bindings>
<basicHttpBinding>
<webHttpBinding>
<binding name="Binding_Name" maxReceivedMessageSize="2147483647">
</binding>
</webHttpBinding>
</bindings>
Then mention the same in your service endpoint as written below
<services>
<service behaviorConfiguration="ServiceBehaviour" name="Servicename">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="Binding_Name" contract="Contractname" />
</service>
</services>

Content Type text/xml; charset=utf-8 was not supported by service

I have a problem with a WCF service.
I have a console application and I need to consume the service without using app.config, so I had to set the endpoint, etc. by code.
I do have a service reference to the svc, but I can't use the app.config.
Here's my code:
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://localhost:8731/WcfServicio/MiServicio");
MiServicioClient svc = new MiServicioClient(binding, address);
object ob = svc.PaisesObtener();
At the last line when I do svc.PaisesObtener() I get the error:
Content Type text/xml; charset=utf-8 was not supported by service
http://localhost:8731/WcfServicio/MiServicio. The client and service bindings may be mismatched.
First Google hit says:
this is usually a mismatch in the client/server bindings, where the message version in the service uses SOAP 1.2 (which expects application/soap+xml) and the version in the client uses SOAP 1.1 (which sends text/xml). WSHttpBinding uses SOAP 1.2, BasicHttpBinding uses SOAP 1.1.
It usually seems to be a wsHttpBinding on one side and a basicHttpBinding on the other.
Do not forget check the bindings-related code too.
So if you wrote:
BasicHttpBinding binding = new BasicHttpBinding();
Be sure that all your app.config files contains
<endpoint address="..."
binding="basicHttpBinding" ...
not the
<endpoint address="..."
binding="wsHttpBinding" ...
or so.
I've seen this behavior today when the
<service name="A.B.C.D" behaviorConfiguration="returnFaults">
<endpoint contract="A.B.C.ID" binding="basicHttpBinding" address=""/>
</service>
was missing from the web.config. The service.svc file was there and got served. It took a while to realize that the problem was not in the binding configuration it self...
I saw this problem today when trying to create a WCF service proxy, both using VS2010 and svcutil.
Everything I'm doing is with basicHttpBinding (so no issue with wsHttpBinding).
For the first time in my recollection MSDN actually provided me with the solution, at the following link How to: Publish Metadata for a Service Using a Configuration File. The line I needed to change was inside the behavior element inside the MEX service behavior element inside my service app.config file. I changed it from
<serviceMetadata httpGetEnabled="true"/>
to
<serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>
and like magic the error went away and I was able to create the service proxy. Note that there is a corresponding MSDN entry for using code instead of a config file: How to: Publish Metadata for a Service Using Code.
(Of course, Policy15 - how could I possibly have overlooked that???)
One more "gotcha": my service needs to expose 3 different endpoints, each supporting a different contract. For each proxy that I needed to build, I had to comment out the other 2 endpoints, otherwise svcutil would complain that it could not resolve the base URL address.
I was facing the similar issue when using the Channel Factory. it was actually due to wrong Contract specified in the endpoint.
For anyone who lands here by searching:
content type 'application/json; charset=utf-8' was not the expected type 'text/xml; charset=utf-8
or some subset of that error:
A similar error was caused in my case by building and running a service without proper attributes. I got this error message when I tried to update the service reference in my client application. It was resolved when I correctly applied [DataContract] and [DataMember] attributes to my custom classes.
This would most likely be applicable if your service was set up and working and then it broke after you edited it.
I was also facing the same problem recently. after struggling a couple of hours,finally a solution came out by addition to
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
to your SVC markup file. e.g.
ServiceHost Language="C#" Debug="true" Service="QuiznetOnline.Web.UI.WebServices.LogService"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
and now you can compile & run your application successfully.
Again, I stress that namespace, svc name and contract must be correctly specified in web.config file:
<service name="NAMESPACE.SvcFileName">
<endpoint contract="NAMESPACE.IContractName" />
</service>
Example:
<service name="MyNameSpace.FileService">
<endpoint contract="MyNameSpace.IFileService" />
</service>
(Unrelevant tags ommited in these samples)
In my case, I had to specify messageEncoding to Mtom in app.config of the client application like that:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="IntegrationServiceSoap" messageEncoding="Mtom"/>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:29495/IntegrationService.asmx"
binding="basicHttpBinding" bindingConfiguration="IntegrationServiceSoap"
contract="IntegrationService.IntegrationServiceSoap" name="IntegrationServiceSoap" />
</client>
</system.serviceModel>
</configuration>
Both my client and server use basicHttpBinding.
I hope this helps the others :)
I had this error and all the configurations mentioned above were correct however I was still getting "The client and service bindings may be mismatched" error.
What resolved my error, was matching the messageEncoding attribute values in the following node of service and client config files. They were different in mine, service was Text and client Mtom. Changing service to Mtom to match client's, resolved the issue.
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMySevice" ... messageEncoding="Mtom">
...
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
I had this problem in .net 6.0
The problem was the Soap Version, the BasicHttpBinding targets Soap 1.1 by default, but the service uses Soap 1.2.
The solution was to create a custom binding that targets Soap 1.2:
private Binding GetBindingConfiguration()
{
var textBindingElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
};
var httpsBindingElement = new HttpsTransportBindingElement()
{
MaxReceivedMessageSize = int.MaxValue,
RequireClientCertificate = true //my service require certificate
};
return new CustomBinding(textBindingElement, httpsBindingElement);
}
var binding = GetBindingConfiguration();
var address = new EndpointAddress("https://nfe.sefa.pr.gov.br/nfe/NFeAutorizacao4"); //Brazil NF-e endpoint that I had to consume.
var svc = new MyService(binding, address);
//my service requires certificate
svc.ClientCredentials.ClientCertificate.Certificate = certificado;
object ob = svc.PaisesObtener(); //call the method

Silverlight application requesting a file from a WCF service

I have a Silverlight (v3) application that is communicating to a WCF service on my server. One of the things the Silverlight application does is request a dynamically generated data file - this data file is created by the service and needs to (ultimately) be saved on the local user's machine via the SaveFileDialog.
My question is, what is the best way in Silverlight to get this file? The file in question may be quite large.
Any help would be appreciated.
If you already know that the file being requested might be quite large, then you might want to create your own specific endpoint for this request, which supports streaming.
So you would have a regular endpoint (e.g. http://yourserver:8080/YourService) which you use for "normal" method calls, and a second endpoint (http://yourserver:8085/YourService) which would support streaming to send back the file with a reasonable amount of memory overhead.
Configuring this should be fairly simple - both on the server and the client, you need to specify a binding configuration to support streaming:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="streamed"
transferMode="StreamedResponse" />
</basicHttpBinding>
</bindings>
<services>
<service name="YourService">
<endpoint name="normal"
address="http://yourserver:8080/YourService"
binding="basicHttpBinding"
contract="IYourServiceContract" />
<endpoint name="filetransfer"
address="http://yourserver:8085/YourService"
binding="basicHttpBinding"
bindingConfiguration="streamed"
contract="IYourServiceContract" />
</service>
</services>
</system.serviceModel>
On the client, of course, you'd have to have the two endpoints inside a <client> tag, but otherwise, everything should be the same.
The "transferMode" is "buffered" by default, e.g. the whole message is buffered and sent in one block.
Your other options are "Streamed" (streaming both ways), "StreamedRequest" (if you have really large requests) or "StreamedResponse" (if only the response, the file being transferred, is really large).
In this case, you'd have a single method on your service that would return a stream (i.e. the file). From your client, when you call this service method, you get back a stream that you can then read in chunks, just like a MemoryStream or a FileStream.
Marc

Can IIS-hosted WCF service be configured for BOTH Windows Auth and Anonymous?

I've got a small WCF webservice working with the built-in WCF Service Host and with hosting by the Visual Studio 2008 built-in development webserver.
I these hosting enviroments I have relied on the WCF Test Client for invoking the service methods.
Now I am running into problems with my next phase of testing:
I have it hosted in IIS 5.1 on my WinXP dev machine and I think maybe the problem is I cannot continue to use WCF Test Client anymore. Here is what's happening:
Case 1: "Anonymous Access" is CHECKED (ENABLED)
WCF Test Client UI comes up properly, exposing the WebMethods and the INVOKE button.
Yet when I click INVOKE it fails to connect with a backend data store (a 3rd party product) that requires Windows authentication. I could post the error I get back from the product.DLL but I don't think it is relevant.
Case 2: "Anonymous Access" is un-CHECKED (DISABLED)
WCF Test Client UI fails to even initialize properly. My researching of this tells me that MEX (WS-Metadata Exchange) requires "Anonymous Access" and (apparently) WCF Test Client requires MEX. Here are key snippets of the error being returned:
Error: Cannot obtain Metadata from http://localhost/wcfiishost
The remote server returned an error: (401) Unauthorized.HTTP GET Error
URI: http://localhost/wcfiishost
There was an error downloading 'http://localhost/wcfiishost'.
The request failed with the error message:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service
The are lots of explanations of binding options, message security, etc. and stuff I honestly do not understand. Here is my take on where I am but I would love your opinions:
(a) Because I know my WCF webservice MUST be configured to use Windows Authentication, I conclude I cannot continue to use the WCF Test Client when hosting my service in IIS. That it has effectively outlived it's usefulness to me. I will just have to take the time to write a web client because WCFTestClient won't work without Anonymous.
(or)
(b) It is possible to use WCF Test Client if it and the hosted service are configured propertly (I just don't know what the special configuration techniques are for this).
Which is correct? Time to stop using WCFTestClient or is there a way to have it both ways? Thanks in advance for your advice.
EDIT: 11 June 09
Is there anything else I can provide to help someone else help me on this question?
I just tried to have the same setup - but in my case, everything seems to work just fine.
ASP.NET web site
WCF service, using basicHttpBinding without any special settings at all
IIS Application with anonymous = enabled and Windows authentication = enabled (both turned on)
I can easily connect to it with the WcfTestClient and retrieve the metadata, and I can then call it, no problem.
Inside my service function, I check to see whether the current user is a known user or not, it is correctly identified as a Windows authenticated user:
ServiceSecurityContext ssc = ServiceSecurityContext.Current;
if (ssc.IsAnonymous)
{
return "anonymous user";
}
else
{
if(ssc.WindowsIdentity != null)
{
return ssc.WindowsIdentity.Name;
}
if (ssc.PrimaryIdentity != null)
{
return ssc.PrimaryIdentity.Name;
}
}
return "(no known user)";
I don't really know, what more to check for (except I'm on Vista with IIS7). Any chance you could include this code to check for the user in your service code? Just to see....
Marc
Marc, your setup is not even close to Johns.
John uses WSHttpBinding that uses Windows Credentials for Message mode transport. The Windows Authentication isn't being used with BasicHttpBinding. Furthermore, John had AnonymousAuthentication disabled, which is why the Metadata Exchange (mex) is failing.
The call won't even reach inside the service side function, because we get a Error 401 (Unauthorized) when we try to call.
Just know John, I have the same issue, and I'm trying to somehow set up separate bindings per endpoint. Hopefully that will work.
When I set the title/subject of this question and reached a dead end here, I opened up the same issue in the MSDN forum with a different emphasis on the title (content of question essentially the same).
For me, the real issue was how to use WCFTestClient in IIS without Anonymous Authentication being set (because my service needed Integrated Windows Authentication only).
Mex apparently requires Anonymous and by default WCFTestClient seems to need Mex. The key seems to be accomodating both my doctoring up the web.config file carefully.
Anyway, I got it working with this web.config below (the MSDN link is here:
<?xml version="1.0"?>
<configuration>
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="wsBindingConfig"
contract="sdkTrimFileServiceWCF.IFileService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="basic"
binding="basicHttpBinding"
bindingConfiguration="bindingConfig"
contract="sdkTrimFileServiceWCF.IFileService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="bindingConfig">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="wsBindingConfig">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</serviceBehaviors>
</behaviors>