WCF Configuration for https and JSON Post - asp.net

As it normally happens, I accidentally overwrote my web.config file this morning that has my WCF settings already working perfectly. As you would expect, no backup...shame shame shame on me.
That being said, I can't seem to get my configuration working again.
Here is the error that I keep getting back from IIS/ASP.NET
The message with Action '' cannot be processed at the receiver, due to
a ContractFilter mismatch at the EndpointDispatcher. This may be
because of either a contract mismatch (mismatched Actions between
sender and receiver) or a binding/security mismatch between the sender
and the receiver. Check that sender and receiver have the same
contract and the same binding (including security requirements, e.g.
Message, Transport, None).
Here is an overview of what I have setup.
My Web Config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="Binding1" maxReceivedMessageSize="10000000">
<readerQuotas maxArrayLength="10000000" />
<security mode="Transport"></security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="MyService">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="Binding1" contract="IMyService" />
</service>
</services>
</system.serviceModel>
Here is the declaration in my Service Contract:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/SSMX", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
sqlStudio_Table_Permissions SSMX(string TableName);
Sadly I just can't seem to remember what I did in my previous configuration to make this work.
Any help would be appreciated.

Related

WebServiceHost not working after disabling anonymous authentication in IIS

I have an rest wcf service integrated with asp.net and deployed in IIS. This is working fine when anonymous authentication is enabled. When it's disabled it's throwing 401 error when i use the rest api call in postman. In IIS anonymous authentication and Forms authentication are enabled. Now i disabled Anonymous and Forms and enabled windows authentication only.
My code is below:
public class SampleWebServiceHostFactory : WebServiceHostFactory
{
private Type ContractServiceType;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public SampleWebServiceHostFactory(Type contractServiceType):base()
{
ContractServiceType = contractServiceType;
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
WebServiceHost host = (WebServiceHost)base.CreateServiceHost(serviceType,baseAddresses);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
WebHttpBinding mybinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
mybinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
mybinding.MaxReceivedMessageSize = 2147483647;
mybinding.TransferMode = TransferMode.StreamedRequest;
mybinding.ReaderQuotas.MaxDepth = 1204;
mybinding.ReaderQuotas.MaxStringContentLength = 2147483647;
mybinding.ReaderQuotas.MaxArrayLength = 2147483647;
mybinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
mybinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
mybinding.SendTimeout = new TimeSpan(4,0,0);
mybinding.ReceiveTimeout = new TimeSpan(4,0,0);
host.AddServiceEndpoint(ContractServiceType, mybinding, "");
host.Description.Behaviors.Add(new RestServiceBehavior());
log.Info("Testing1");
return host;
}
}
the below code in config file
<system.serviceModel>
<client/>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
<serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
I have enabled logging in Global.asax to see where issue occurs. After the Session_Start method fired i see the log line "Testing1" in the above code. After that no logging and it threw 401 error in postman and keep on asking for username and password when i use the url in in browser.
Now that we have already set up the configuration in the constructor of the WebServiceHostFactory, It is unnecessary to configure it in the configuration file separately.
<webHttpBinding>
<binding receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
I suggest you refer to the below configuration for Windows Authentication.
<system.serviceModel>
<services>
<service name="WcfService3.Service1">
<endpoint address="" behaviorConfiguration="rest" contract="WcfService3.IService1" binding="webHttpBinding" bindingConfiguration="https"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="https">
<security mode="Transport">
<transport clientCredentialType="Windows">
</transport>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
After that, disable other authentication modes in IIS. We need to provide a pair of windows credentials while calling the service.
The credential is actually the windows account on the server-side, which enables us to access the website.
Feel free to let me know if the problem still exists.

the resource cannot be found wcf service with SSL

I created a REST api using asp.net vb and I was trying to invoke the api through secure connection (https) but I had an error
The resource cannot be found
I can invoke any method using (http), but with (https) I can't. And I can access the main page of api (service.svc) using the (https) but the problem with functions!! below are my config and function header.
<system.serviceModel>
<services>
<service name="RESTAPI" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address="customBinding" binding="customBinding" bindingConfiguration="basicConfig" contract="RESTAPI"/>
<endpoint address="" behaviorConfiguration="HerbalAPIAspNetAjaxBehavior"
binding="webHttpBinding" contract="HerbalAPI" />
<endpoint contract="RESTAPI" binding="mexHttpBinding" address="mex" />
</service>
</services>
<!-- **** Services ****-->
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="HerbalAPIAspNetAjaxBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="basicConfig">
<binaryMessageEncoding/>
<httpTransport transferMode="Streamed" maxReceivedMessageSize="67108864"/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
API Class
<ServiceContract(Namespace:="")>
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
Public Class RESTAPI
<OperationContract()>
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json, RequestFormat:=WebMessageFormat.Json)>
Public Function test(ByVal st As String) As JSONResultString
//any code
End Function
End Class
You need to define a special binding configuration in your web.config file to allow the SVC service to bind correctly for HTTPS requests.
Please have a look at this blog post: https://weblogs.asp.net/srkirkland/wcf-bindings-needed-for-https
Your service will already be defined in the web.config, just add the bindingConfiguration attribute:
<services>
<service name="TestService">
<endpoint address="" behaviorConfiguration="TestServiceAspNetAjaxBehavior"
binding="webHttpBinding" bindingConfiguration="webBindingHttps" contract="TestService" />
</service>
</services>
Then define the special binding settings for the webHttpBinding as so, the magic part that fixes the HTTPS request is the <security mode="Transport" />:
<bindings>
<webHttpBinding>
<binding name="webBindingHttps">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
This will effectively switch the service over to HTTPS, but if you want to have both HTTP and HTTPS to work you need to define 2 binding configurations and then have 2 identical endpoints per service, where the one uses the http bindingConfiguration and the other uses the https bindingConfiguration like so:
<bindings>
<webHttpBinding>
<binding name="webBindingHttps">
<security mode="Transport">
</security>
</binding>
<binding name="webBindingHttp">
<!-- Nothing special here -->
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="TestService">
<endpoint address="" behaviorConfiguration="TestServiceAspNetAjaxBehavior"
binding="webHttpBinding" bindingConfiguration="webBindingHttps" contract="TestService" />
<endpoint address="" behaviorConfiguration="TestServiceAspNetAjaxBehavior"
binding="webHttpBinding" bindingConfiguration="webBindingHttp" contract="TestService" />
</service>
</services>

How can I host a WCF service without an SVC file in IIS

I'd like to deploy a dual interface (SOAP/REST/XML/JSON) WCF service in IIS with just a config file and the binaries and no svc file in the URL
We use VS2012 and .Net 4.5
We have something like it working, I followed a guide here:
http://blogs.msdn.com/b/rjacobs/archive/2010/04/05/using-system-web-routing-with-data-services-odata.aspx
I added a Global class with
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
DataServiceHostFactory factory = new DataServiceHostFactory();
RouteTable.Routes.Add(new ServiceRoute("wrap", factory, typeof(NeOtheWrapper)));
}
}
And I used my existing web.config which defines all the endpoints:
<system.serviceModel>
<!-- Clients -->
<client>
<endpoint name="MySoftLive" address="https://backof.somewebsitett.com/Cmp.MySoft.bl/MySoft.svc" binding="basicHttpsBinding" bindingConfiguration="soapSecureBindingConfig" contract="Cmp.MySoft.BL.WCF.MySoftInterface" />
<endpoint name="MySoftTest" address="http://localhost:49957/MySoft.svc" binding="basicHttpBinding" bindingConfiguration="soapBindingConfig" contract="Cmp.MySoft.BL.WCF.MySoftInterface" />
</client>
<!-- Services -->
<services>
<service name="Cmp.MySoft.BL.NeOthe.NeOtheWrapper">
<endpoint name="rest" address="rest" behaviorConfiguration="restEndpointBehaviour" binding="webHttpBinding" bindingConfiguration="restBindingConfig" contract="Cmp.MySoft.BL.NeOthe.INeOtheWrapper"/>
<endpoint name="restSecure" address="rest" behaviorConfiguration="restEndpointBehaviour" binding="webHttpBinding" bindingConfiguration="restSecureBindingConfig" contract="Cmp.MySoft.BL.NeOthe.INeOtheWrapper"/>
<endpoint name="mex" address="mex" behaviorConfiguration="" binding="mexHttpBinding" bindingConfiguration="mexBindingConfig" contract="Cmp.MySoft.BL.NeOthe.INeOtheWrapper"/>
<endpoint name="mexSecure" address="mex" behaviorConfiguration="" binding="mexHttpsBinding" bindingConfiguration="mexSecureBindingConfig" contract="Cmp.MySoft.BL.NeOthe.INeOtheWrapper"/>
<endpoint name="soap" address="soap" behaviorConfiguration="" binding="basicHttpBinding" bindingConfiguration="soapBindingConfig" contract="Cmp.MySoft.BL.NeOthe.INeOtheWrapper"/>
<endpoint name="soapSecure" address="soap" behaviorConfiguration="" binding="basicHttpsBinding" bindingConfiguration="soapSecureBindingConfig" contract="Cmp.MySoft.BL.NeOthe.INeOtheWrapper"/>
</service>
</services>
<!-- Binding Configurations -->
<bindings>
<webHttpBinding>
<binding name="restBindingConfig">
<security mode="None"/>
</binding>
<binding name="restSecureBindingConfig">
<security mode="Transport"/>
</binding>
</webHttpBinding>
<mexHttpBinding>
<binding name="mexBindingConfig"/>
</mexHttpBinding>
<mexHttpsBinding>
<binding name="mexSecureBindingConfig"/>
</mexHttpsBinding>
<basicHttpsBinding>
<binding name="soapSecureBindingConfig">
<security mode="Transport"/>
</binding>
</basicHttpsBinding>
<basicHttpBinding>
<binding name="soapBindingConfig">
<security mode="None"/>
</binding>
</basicHttpBinding>
</bindings>
<!-- Behaviour Configurations -->
<behaviors>
<endpointBehaviors>
<behavior name="restEndpointBehaviour">
<webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true" faultExceptionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<!-- Hosting Environment Settings -->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
It compiles, runs and if I browse to http://mypc:12345/wrap/rest/help I get the auto generated ASP.NET REST help page.
But, if I go to http://mypc:12345/wrap/soap/ I get 400 Bad Request.
I can't suffix that with ?wsdl to get the wsdl, or pass the url to svcutil (soap+xml not expected)
I was hoping the .SVC SOAP place holder page would appear, same as /help does for REST.
If I browse to the .svc file (it's at the same level as /wrap) that works and the soap service works, as does meta data publishing.
Am I using the wrong URL or is my configuration wrong?
If you're using WCF 4.0 or later, you can use "file-less" activation. Add something like the following to config your file:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add factory="System.ServiceModel.Activation.ServiceHostFactory"
relativeAddress="Soap.svc"
service="Cmp.MySoft.BL.NeOthe.NeOtheWrapper" />
</serviceActivations>
</serviceHostingEnvironment>
This allows you to host a WCF service without a physical .svc file. The relativeAddress is relative to the base address of the site, and you'll need to create the IIS application as usual.
See the "File-Less activation" section in A Developer's Introduction to Windows Communication Foundation 4 for more information.

Jquery call wcf service giving 200 Parser Error

I'm new to WCF world. i'm having a solution which contains Web App(which has JQuery Ajax call to WCF services application which is another project in the solution. After 2 days of working(cracking) i'm in a state which i able pass request and get response
but while try to show that in alert gives me 200 parser Error.
Any help will be highly appreciate
Further Ref
$.ajax({
async: true,
type: 'GET', //GET or POST or PUT or DELETE verb
url: 'http://localhost:61057/Service1.svc/GetCustomer', // Location of the service
dataType: 'jsonp', //Expected data format from server
success: function (data) {//On Successfull service call
ServiceSucceeded(data);
},
error: function () { ServiceFailed(Data); } // When Service call fails
});
Web.config
<system.serviceModel>
<services>
<service name="FIN.Services.Service1" behaviorConfiguration="DefaultBehavior">
<endpoint address="http://localhost:61057/service1.svc" binding="webHttpBinding" contract="FIN.Services.IService1" behaviorConfiguration="AjaxBehavior">
<identity>
<dns value="locahost"/>
</identity>
</endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="None">
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
service interface :
[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "GET", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json)]
[OperationContract]
string GetCustomer();
If you need no argument, add following in your ajax call ..
data: "{}",
You are using jsonp,means you want to call cross domain service.
For cross domain service you url should be like below
http://localhost:61057/Service1.svc/GetCustomer?callback=?
and also you have to make some changes in web.config
Check out the following link for complete example
Calling cross domain service in wcf

Hide REST methods from SOAP WCF Client

I created a simple WCF Service interface:
namespace ApiDoc.SampleApi
{
/// <summary>
/// Contract
/// </summary>
/// <webMethodsPrefix>Web</webMethodsPrefix>
[ServiceContract(Namespace = "apidoc.sampleapi.com", Name = "SampleApi")]
public interface IService
{
[WebGet( UriTemplate = "Add?value1={value1}&value2={value2}&apiKey={apiKey}", BodyStyle = WebMessageBodyStyle.Bare)]
AddRs AddWithHttpGet(int value1, int value2, string apiKey);
[WebInvoke(Method = "POST", UriTemplate = "Add", BodyStyle = WebMessageBodyStyle.Bare)]
AddRs Add(AddRq rq);
}
}
In this case it is just a simple Add operation.
It works well for Xml, Soap and Json. Both Get and Post.
The issue I am having is in Soap when I create a Service Reference to this service. I can call both functions "Add" and "AddWithHttpGet", while I only would like to see "Add".
I originally thought it was related to using "OperationContract" attribute, but it seems like it is not used any longer. I tried adding this attribute only to POST Add, but it doesn't make any difference. I am using ASP.NET 4.0.
Another solution would be to create a different IService for Soap, but I would rather keep this all in one interface.
Here is my config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="jsonHttpBinding" />
<binding name="xmlHttpBinding" />
</webHttpBinding>
</bindings>
<services>
<service name="ApiDoc.SampleApi.Service" behaviorConfiguration="ApiDocSampleApiBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost/ApiDoc.SampleApi/" />
</baseAddresses>
</host>
<endpoint name="soap" address="" binding="basicHttpBinding" bindingNamespace="apidoc.sampleapi.com" contract="ApiDoc.SampleApi.IService" lockAttributes="bindingNamespace" />
<endpoint name="json" address="json" binding="webHttpBinding" bindingNamespace="apidoc.sampleapi.com" bindingConfiguration="jsonHttpBinding" contract="ApiDoc.SampleApi.IService" behaviorConfiguration="JsonBehavior" />
<endpoint name="xml" address="xml" binding="webHttpBinding" bindingNamespace="apidoc.sampleapi.com" bindingConfiguration="xmlHttpBinding" contract="ApiDoc.SampleApi.IService" behaviorConfiguration="XmlBehavior" />
<endpoint name="mex" address="mex" binding="mexHttpBinding" bindingNamespace="apidoc.sampleapi.com" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="JsonBehavior">
<webHttp defaultOutgoingResponseFormat="Json" />
</behavior>
<behavior name="XmlBehavior">
<webHttp defaultOutgoingResponseFormat="Xml" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ApiDocSampleApiBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" minFreeMemoryPercentageToActivateService="0" />
</system.serviceModel>
...
I would create a separate interface.
Think of your interface like a real contract between two parties. You are using it to define what operations are available to a client. If it's in the contract, it's available.
Instead of looking for some sort "invisible ink" that would make certain parts of the contract available to certain clients, I'd simply create two contracts.
I'm a little confussed. The OperationContractAttribute is required. A WebGetAttribute on it's own shouldn't do anything, as the method is not expossed as an operation.
As for hiding an operation, that is not possable either. If the interface is your contract, and you definatly want two different contracts then you will need two different interfaces.
If you don't want to duplicate your code then you can still use inheritace. Have one interace define your SOAP operation Add and then inherit from that to add AddWithHttpGet. Then by targeting the different interfaces in your endpoints, the SOAP endpoint would have one operation and REST endpoint would have two.
try this you want hide webmethod form soap header in c#
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare), WebMethod]
public string Operation(RIL_OB_MSG RIL_OB_MSG)
{
}

Resources