WCF URL Length Causing IIS 400 Bad Request Error - wcf

I have a wcf webHttp endpoint and noticed today that when called httpGet with a long url ~364 total characters (http:// etc counted) IIS throws a 400 bad request error. Throwing a breakpoint in the code never gets reached. If I remove some parameters and have a url that is 354 the web service runs as expected.
I'm not sure where the issue is since urls can be like 2k. I'm not posting any data so I don't think I'm hitting a 4mb limit like from here
What gives?
Here's some wcf xml stuff.
<behaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<endpoint address="" behaviorConfiguration="REST" binding="customBinding" bindingConfiguration="jsonpBinding" contract="Interface"/>
<bindings>
<customBinding>
<binding name="jsonpBinding">
<jsonpMessageEncoding/>
<httpTransport manualAddressing="true"/>
</binding>
</customBinding>
</bindings>
<extensions>
<bindingElementExtensions>
<add name="jsonpMessageEncoding" type="Microsoft.Ajax.Samples.JsonpBindingExtension, service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bindingElementExtensions>
</extensions>
I just removed the callback function name which significantly reduced the size of the url and it still threw a 400 error. This makes me think that there is a WCF size limit on the text that can be sent in as a string parameter.
here;'s some Contract stuff
[OperationContract]
[WebGet(UriTemplate = #"{userName}/layer({layerName})returnAttributes({attributeList})where({attributeName})({op})({attributeValue})", ResponseFormat = WebMessageFormat.Json)]
[JSONPBehavior(callback = "callback")]
DojoGrouping GetAttributes(string userName, string layerName, string attributeList, string attributeName, string attributeValue);
the issue is with attributeList which can be comma separated list.
so with a url call like
http://../demo/layer(OfficialsLookup)returnAttributes(USHOUSE,US_Photo,US_Web,US_Name,SENDIST,SEN_Name,SEN_Email,SEN_Party,SEN_Photo,REPDIST,REP_Name,REP_Email,REP_Party,REP_Web,REP_Photo)utmX(430)utmY(4502)
it busts. But if i shorten the return attribute text then it functions properly.
I've added I added the following entry into the registry:
Key Name: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters
Class Name: <NO CLASS>
Last Write Time: 1/25/2011 - 3:34 PM
Value 0
Name: UrlSegmentMaxLength
Type: REG_DWORD
Data: 0x200
I rebooted the machine after adding it and am still receiving the same error. Is this the correct spot to be modifying the HTTP.sys settings that WCF and IIS are using? Is there a way to test that WCF is being affected by this registry value?
Here is a related post with no answer but saying that the httpsys stuff did not fix a 64 bit server which is what we are using.
Related Post

To fix our issue we had to use the .NET 4.0 framework. We moved the web service to run under a .net 4.0 app pool and changed the target framework to 4.0. This caused the site to spit out url is too long error instead of just a bad request. After adding a web config entry in
<system.web>
added
<httpRuntime maxUrlLength="500" />
for max url length, the service is up and running as expected.

WCF uses HTTP.sys to handle HTTP traffic. HTTP.sys has system wide settings to handle various restrictions around URL. You might be hitting one of them.
See the following article to find out those settings:
http://support.microsoft.com/kb/820129
You will need to restart http service and your WCF service. If it is hosted in IIS, restart IIS. UrlSegmentMaxLength seems to be an interesting for your URI template.

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.

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

Running a .net 4.0 WCF data service on a subdomain

I have two domains running my WCF data services:
a) http://www.domain-a.com/
b) http://api.domain-b.com/
When I address my service like this:
http://domain-a.com/odata.svc - IT WORKS.
When I address my service like this:
http://www.domain-a.com/odata.svc - I GET THE FOLLOW EXCEPTION:
Message: Service 'cf.Svc.odata_v0' has
zero application (non-infrastructure)
endpoints. This might be because no
configuration file was found for your
application, or because no service
element matching the service name
could be found in the configuration
file, or because no endpoints were
defined in the service element.
ExceptionStackTrace: at
System.ServiceModel.Description.DispatcherBuilder.EnsureThereAreApplicationEndpoints(ServiceDescription
description) at
System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription
description, ServiceHostBase
serviceHost) at
The problem, is that I need moving forward to run my service on:
http://api.domain-b.com/ and I do not have the option to reference it as http://domain-b.com/ because the root domain is already in use.
I even tried downloading the WCF Data Services Toolkit (http://wcfdstoolkit.codeplex.com/releases/view/65119) april release thinking I'd get around the problem with setting up a nice clean route - like:
http://api.domain-b.com/odata
But I'm still getting this error. Can anyone tell me what's going on?
My web.config looks like below - I am also running WCF Rest Services that do not have any issues in the same application.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true"
automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>

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>

WCF not running under IIS 6.0

Trying to get my WCF service running under IIS 6.
I have created the .svc and aspnet_isapi.dll mapping according to: http://msdn.microsoft.com/en-us/library/ms752241.aspx
When viewing the Server1.svc page, I am getting a 404.
I have tested the site with a simple .aspx page to ensure the URL is working, but again the .svc extension isn't.
I have .NET 3.5 SP1 installed, my web.config is referencing 3.5 assemblies, and I don't get an error when viewing a .aspx page so it is picking those assemblies up fine, presumably.
What could be wrong?
More than likely the .svc extension is not registered under IIS as being handled by ASP.NET (WCF).
Try these 2 steps (replace Framework with Framework64 if it's needed):
Go to:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\
and then run:
aspnet_regiis -i
Go to:
C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation
and then run:
ServiceModelReg.exe -i
Under Internet Information Service (IIS) Manager, open the node called Web Service Extension. Make sure that ASP.NET v2.0.5.0727 is set to Allowed. I spent hours looking for different settings and found it was set to Prohibited. Just click Allow button to enable ASP.NET.
There are two things I can think of:
The .svc extension is not correctly set up (least probable according to your description). You can check this post for more details.
Or your web site has multiple host headers. To resolve this issue, you must have a single host header or use a factory. Here’s an example:
namespace MyNamespace
{
public class MultipleHostServiceFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
List<Uri> addresses = new List<Uri>();
addresses.Add(baseAddresses[0]);
return base.CreateServiceHost(serviceType, addresses.ToArray());
}
}
}
Next, you need to set the factory in the markup of your .svc file:
<%# ServiceHost Language="C#"
Debug="false"
Factory="MyNamespace.MultipleHostServiceFactory"
Service="MyNamespace.MyService"
CodeBehind="MyService.svc.cs" %>
I had the same problem. It ended up being I was running a 64-bit version of Windows 2003 Server, and had my assemblies configured for "Any CPU". Once I changed the assemblies over to x86 and uploaded to the server, everything worked.
I don't know why nobody has mentioned it anywhere else in the 30 threads I read about, but my friend recommended it to me, and it worked like a charm.
Just throwing it out there just in case someone has the same issue.
I had the same issue and solved it by allowing ISAPI extensions. Under Internet Information Service (IIS) Manager, open the node called Web Service Extension. Make sure that "All Unknown ISAPI Extensions" is set to Allowed.
I battled for hours with this until I finally used this example and it worked first go: http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide
I know link only answers aren't good and others have used this CP link to solve this type of problem here at Stackoverflow so here are the basic steps if the article ever goes down:
STEP 1
First of all launch Visual Studio 2010. Click FILE->NEW->PROJECT. Create new "WCF Service Application".
STEP 2
Once you create the project, you can see in solution that By Default WCF service and interface file are already created (Service1.cs & IService.cs). Delete these two files and we will create our own interface and WCF service file.
STEP 3
Now right click on solution and create one new WCF service file. I have given name to the service file as “RestServiceImpl.svc”.
STEP 4
As I explained at the start of the article that we will be writing an API which can return data in XML and JSON format, here is the interface for that. In IRestServiceImpl, add the following code
In the above code, you can see two different methods of IRestService which are XMLData and JSONData. XMLData returns result in XML whereas JSONData in JSON.
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "xml/{id}")]
string XMLData(string id);
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "json/{id}")]
string JSONData(string id);
}
STEP 5
Open the file RestServiceImpl.svc.cs and write the following code over there:
public class RestServiceImpl : IRestServiceImpl
{
public string XMLData(string id)
{
return "You requested product " + id;
}
public string JSONData(string id)
{
return "You requested product " + id;
}
}
STEP 6
Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" 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.
-->
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- 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>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
STEP 7
In IIS: