How to configure endpoint - wcf

I had a WCF Service
My Web.config looks like this:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyNameSpace.MyService">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="crossDomain" contract="MyNameSpace.IMyService" behaviorConfiguration="EndpBehavior"/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
I recently found this code for array parameter from one of the website
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
namespace ArraysInQueryStrings
{
public class ArrayInQueryStringWebHttpBehavior : WebHttpBehavior
{
WebMessageFormat defaultOutgoingResponseFormat;
public ArrayInQueryStringWebHttpBehavior()
{
this.defaultOutgoingResponseFormat = WebMessageFormat.Json;
}
public override WebMessageFormat DefaultOutgoingResponseFormat
{
get
{
return this.defaultOutgoingResponseFormat;
}
set
{
this.defaultOutgoingResponseFormat = value;
}
}
protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
{
return new ArrayQueryStringConverter();
}
}
}
How to use this extended class in the web.config.
It seems to be an Endpoint behaviour but dont know how to use it.
Any help is appreciated

To add custom behaviors, you need to add your derived behavior as a behavior extension in config file and need to add a new Behavior extension type. Refer to this post - Custom Behavior won't register in my web.config
public class ArrayInQueryStringBehaviorExtension : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(ArrayInQueryStringWebHttpBehavior);
}
}
protected override object CreateBehavior()
{
return new ArrayInQueryStringWebHttpBehavior();
}
}
Config file (you need to specify your assembly name where I have marked square brackets below)
<extensions>
<behaviorExtensions>
<add name=" ArrayInQueryStringWebHttpBehavior " type="[Namespace]. ArrayInQueryStringBehaviorExtension, [Assembly Name], [Assembly Version], [Assembly Culture], PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="arrayInQueryBehavior">
<webHttp/>
< ArrayInQueryStringWebHttpBehavior />
</behavior>
</endpointBehaviors>
<behaviors>

Related

WCF Service Error 400 Bad Request In VS2017

I have a very simple WCF Service Project in VS2017. But I keep getting error 400 when I try to visit the endpoints. I have read the other questions posted here about the same issue and I have tried them with no luck so far.
My Service Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetData/{value}")]
string GetData(string value);
}
My Service:
public class Service : IService
{
public string GetData(string value)
{
return string.Format("You entered: {0}", value);
}
}
My Web.Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="myBehavior" name="WCGFService1.Service">
<endpoint address="" contract="WCGFService1.IService" binding="webHttpBinding">
</endpoint>
</service>
</services>
When I visit http://localhost:61648/Service.svc/GetData/12, I get HTTP 400 Bad Request. I've tried with browser and POSTman. What am I doing wrong?
I am using VS2017. My IService.cs and Service.cs are inside the App_Code folder whereas the
Service.svc is in the root folder. Also, when I try to add the name & contract in web.config, VS2013 suggests me the namespace and the interface/class name, whereas, VS2017 is not suggesting me anything so I have to manually type it.
Also, in VS2013, the Interface and Class were located in the root folder instead of the App_Code folder. The project is a WCF Application in VS2017. My .NET Version is 4.5.2.
Fixed it, had a few problems in the web.config file:
<system.serviceModel>
<behaviors>
<!-- Fix 1: Added a endpointBehavoir with webHttp -->
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!-- Fix 2: Instead of using the full name (WCGFService1.Service), used just the class name (Service) -->
<service behaviorConfiguration="myBehavior" name="Service">
<!-- Fix 3: Same thing here, used just the IService instead of full name, also, used the aforementioned endpointBehavoir -->
<endpoint address="" contract="IService" binding="webHttpBinding" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
That did it for me, for whatever reason, in VS2013, it would not work if you don't provide the full name (namespace and class/interface name) but in VS2017, it works only if you provide just the class/interface name.

WCF service host cannot find any service metadata. Please Check if metadata is enabled

My App.config file is
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1">
<endpoint address="http://localhost:8733/service1"
binding="webHttpBinding"
contract="WcfJsonRestService.IService1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
My service1.cs code is as below
using System;
using System.ServiceModel.Web;
namespace WcfJsonRestService
{
public class Service1 : IService1
{
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "data/{id}")]
public Person GetData(string id)
{
// lookup person with the requested id
return new Person()
{
Id = Convert.ToInt32(id),
Name = "Leo Messi"
};
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Initially this was giving issue as
WCF Service Host Configuration - Please try changing the HTTP port to 8733
So I had followed Executing the following code in CMD
netsh http add urlacl url=http://+:8733/ user=WORK\Clara
After executing this code I am facing new error as below
How can I resolve this issue?
I have also tried updating the App.Config as said over below link but then after I was getting some another error
WCF service host cannot find any service metadata
You are missing service metadata behavior configuration. Please add below configuration:
<configuration>
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733"/>
</baseAddresses>
</host>
<endpoint address="service1"
binding="webHttpBinding"
contract="WcfJsonRestService.IService1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled ="true"/>
</behavior>
</serviceBehaviors>
</behaviors>

end point not found in wcf restful service through iis

i am just checking whether the method is working or not .but i am getting end point not found .
in the url i provided the link as below:
http://localhost/WcfService1/Service1.svc/kuna/hai
// my web.config file://
<services>
<service name="WcfService1.Service1">
<endpoint address="" behaviorConfiguration="restfulBehaviour" binding="webHttpBinding" bindingConfiguration="" contract="WcfService1.IService1"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfService1/Service1.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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="restfulBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
---------------------------------------------------------
my service file
jus passing two parameters as input and expecting true as o/p
public class Service1 : IService1
{
public bool CheckLoginDetails(string UN, string P)
{
return true;
}
}
interface for service file:
Iservice file:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate = "CheckLoginDetails/{UN}/{P}")]
bool CheckLoginDetails(string UN, string P);
}
sorry i forgot to give the method name in the url.
the url should be :
http://localhost/WcfService1/Service1.svc/CheckLoginDetails/kuna/hai

Consume Wcf Rest Service Issue

I have created a Rest WCF Service.
Service Contract
[ServiceContract]
public interface IPracticeService
{
[OperationContract]
int AddInt(int value1, int value2);
[OperationContract]
double AddDouble(double value1, double value2);
[OperationContract]
string Hello();
[OperationContract]
Person GetPerson();
}
Class
public class PracticeService : IPracticeService
{
public int AddInt(int value1, int value2)
{
return value1 + value2;
}
[OperationBehavior]
public double AddDouble(double value1, double value2)
{
return value1 + value2;
}
public string Hello()
{
return "hello";
}
[WebInvoke(Method="GET",ResponseFormat=WebMessageFormat.Json)]
public Person GetPerson()
{
Person p = new Person();
p.Name = "Abc";
p.Age = 5;
return p;
}
Web Config
<system.serviceModel>
<services>
<service name="RestService.IRestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<endpoint address="*" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</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"></behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
So When I want Add ServiceRefrence This In the client It is giving me error.
The HTML document does not contain Web service discovery information.
Metadata contains a reference that cannot be resolved: 'http://mydomain:1121/Rest/RestServiceImpl.svc'.
Content Type application/soap+xml; charset=utf-8 was not supported by service http://mydomain:1121/Rest/RestServiceImpl.svc. The client and service bindings may be mismatched.
The remote server returned an error: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'..
If the service is defined in the current solution, try building the solution and adding the service reference again.
So How can it will be resolved.
You need to modify your config like this ,
<system.serviceModel>
<services>
<service name="PracticeService.IPracticeService" behaviorConfiguration="ServiceBehaviour">
<endpoint address="*" binding="webHttpBinding" contract="PracticeService.IPracticeService" behaviorConfiguration="web"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</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"></behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

Securing WCF service endpoint with custom authentication

I want to secure some endpoint of a WCF service, i dont know if you can secure some endpoint and some not. Below I have the stripped WCF service (self hosted). The same WCF serves also the CA Policy file. If I secure this WCF service or some endpoints of ut the CA Policy part must not ask me a username password. The policy file must be accessible all the time. Is that also possible?
I found alot WCF custom blogs/postings. There are alot of ways to do security. All I want is that I can secure some endpoints with username/password but the credentials must not be visible with tools like Fiddler. The data however it can be visible in this case.
I implemented already a Customvalidator but the app.config file is also importent to define things. And I am not very good at that.
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public ServiceHost _host = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
_host = new ServiceHost(typeof(WmsStatService));
_host.AddServiceEndpoint(typeof(IPolicyProvider), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
_host.Open();
}
}
// Define a service contract.
[ServiceContract(Namespace = "http://WindowsFormsApplication11")]
public interface IWmsStat
{
[OperationContract]
string getConnectedViewers(string channelName);
[OperationContract]
string sayHello(string name);
}
[ServiceContract]
public interface IPolicyProvider
{
[OperationContract, WebGet(UriTemplate = "/ClientAccessPolicy.xml")]
Stream ProvidePolicy();
}
//[DataContract]
public class Ads
{
// [DataMember]
public string AdFileName { get; set; }
//[DataMember]
public string AdDestenationUrl { get; set; }
public string ConnectedUserIP { get; set; }
}
//
public class CustomValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if(null == userName || null == password)
{
throw new ArgumentNullException();
}
if(userName == "Oguz" && password == "2009")
{
return;
}
FaultCode fc = new FaultCode("ValidationFailed");
FaultReason fr = new FaultReason("Good reason");
throw new FaultException(fr,fc);
}
}
//
public class WmsStatService : IWmsStat, IPolicyProvider
{
public string sayHello(string name)
{
return "hello there " + name + " nice to meet you!";
}
public Stream ProvidePolicy()
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
return new MemoryStream(File.ReadAllBytes("ClientAccessPolicy.xml"), false);
}
public string getConnectedViewers(string channelname)
{
// do stuff
return null;
}
}
}
The app.config. This config file does not work. I wanted to put the custom authentication for a endpoint. I have no clue.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex">
<host>
<baseAddresses>
<add baseAddress="http://192.168.0.199:87" />
</baseAddresses>
</host>
<endpoint address="http://192.168.0.199:87/Test" binding="basicHttpBinding" bindingConfiguration="" contract="WindowsFormsApplication11.IWmsStat" behaviorConfiguration="MyServiceBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<!--<bindings>
<wsHttpBinding>
<binding name="wshttp">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>-->
<behaviors>
<serviceBehaviors>
<behavior name="mex">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
<behavior name="MyServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I want to secure some endpoint of a
WCF service, i dont know if you can
secure some endpoint and some not.
Sure - you just need to create two separate binding configurations, and use one on those endpoints that are secured, the other on the others:
<bindings>
<basicHttpBinding>
<binding name="secured">
<security mode="Message">
<message ...... />
</security>
</binding>
<binding name="unsecured">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex">
<host>
<baseAddresses>
<add baseAddress="http://192.168.0.199:87" />
</baseAddresses>
</host>
<endpoint address="/Secured/Test"
binding="basicHttpBinding" bindingConfiguration="secured"
contract="WindowsFormsApplication11.IWmsStat"
behaviorConfiguration="MyServiceBehavior" />
<endpoint address="/Unsecured/Test"
binding="basicHttpBinding" bindingConfiguration="unsecured"
contract="WindowsFormsApplication11.IWmsStat"
behaviorConfiguration="MyServiceBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Marc
PS: not sure if that's just a problem with your postings not being up to date anymore - have you noticed, that you have two separate behavior configurations:
<behaviors>
<serviceBehaviors>
<behavior name="mex">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
<behavior name="MyServiceBehavior">
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
and your service is only referencing the "mex" behavior? That means, your service is indeed using the <serviceMetadata> behavior - but NOT the <serviceCredentials> one!
You need to merge these into one and then reference just that:
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="...." behaviorConfiguration="Default"
Marc
If you want to protect entire message, Transport security mode is a way to go. If you want to only your headers to be encrypted/signed, Message security mode allows this, but you'll have to use wsHttpBinding. You may also consider using Digest to protect credentials.
As for your example, I think your commented part should look like this:
<bindings>
<basicHttpBinding>
<binding name="secure">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
You'll also have to update your endpoint declaration:
<endpoint
address="https://192.168.0.199:87/Test"
binding="basicHttpBinding" bindingConfiguration="secure"
contract="WindowsFormsApplication11.IWmsStat" />
You won't be allowed to use plain HTTP with transport security mode.