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

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>

Related

WCF JSON Format - while consuming in Client side getting an error message

Client side Code
I have created web application and added service reference to the Client Project
I tried creating a client Object like this:
Service1Client a = new Service1Client();
but getting an error message :
Could not find default endpoint element that references contract 'ServiceReference_test.IService1' in the ServiceModel client
configuration section. This might be because no configuration file was
found for your application, or because no endpoint element matching
this contract could be found in the client element.
Could you please let me know what mistake am I doing, I am new to WCF please help me
WCF service which returns JSON Format:
namespace WcfService1
{
public class Service1 : IService1
{
public string GetData(string Id)
{
return ("You entered: " + Id);
}
}
}
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetData/{Id}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped
)]
string GetData(string Id);
// TODO: Add your service operations here
}
}
Web.Config file
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="WcfService1.IService1"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
You should add following tags in your client App.config or Web.config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/fine_service/FineService/soap"
binding="webHttpBinding" bindingConfiguration="WebHttpBinding"
contract="ServiceReference1.IService1" name="WebHttpBinding" />
</client>
</system.serviceModel>
if you have this tags in your cofig file then make sure that client endpoint contract name should be the same as it is in your service endpoint. In your case contract name is IService1
EDIT:
also see this

How to return an xml response from a WCF Service

I'm not fluent in WCF Services so I'm struggling to return XmlElement as the return type.
I'm getting the message from the WCF Test Client (running in debug mode):
The operation is not supported from the wcf test client because it uses type XmlElement.
[ServiceContract]
public interface IClientService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml)]
XmlElement GetClientXml(int value);
}
namespace testWCF
{
public class testSvc: IClientService
{
public XmlElement GetClientXml(int value)
{
string appDir = AppContext.BaseDirectory;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(appDir + #"Xml\ResponseTempl.xml");
return xDoc.DocumentElement;
}
}
}
I've referred to this as well but it might be too old, as I'm using 4.6.1 framework: Returning XML From a WCF Service
my Web.Debug.config file :
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web>
</system.web>
<system.serviceModel>
<services>
<service name="AucklandRegionalPatientWCF.PatientDemographicService" >
<!-- these endpoint are necessary to return SOAP service -->
<endpoint address=""
binding="basicHttpBinding"
contract="AucklandRegionalPatientWCF.IPatientDemographicService" />
<endpoint address="mex"
contract="IMetadataExchange" binding="mexHttpBinding"/>
<!-- REST service return xml -->
<!--To call this endpoint use: [service].svc/xml/[method_Name]-->
<endpoint address="xml"
binding="webHttpBinding" behaviorConfiguration="xmlBehavior"
contract="AucklandRegionalPatientWCF.IPatientDemographicService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<!-- use XML serialization -->
<behavior name="xmlBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Best way to get XML element from WCf as response use XML formatted string.. Best at performance as well as light weight.....
Create response class and use XML serialization.... It will be helpful

WCF Error : Relative end point addresses

Um quite new to WCF . I think I have messed up a bit. So this is what I did so far and I ve hosted my WCF service in IIS
First the Contracts
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using YangkeeServer.dto;
namespace YangkeeServer
{
public class Service1 : IService1
{
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "single")]
public YangkeeTrailerDTO getTrailor()
{
return new YangkeeTrailerDTO()
{
loanFrom = "heaven"
};
}
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "datum/{id}")]
public Test getName(string id)
{
return new Test()
{
Id = Convert.ToInt32(id) * 12,
Name = "Leo Messi"
};
}
}
}
and this is my web.config file
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="YangkeeServer.Service1">
<endpoint
contract="YangkeeServer.IService1"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="http://localhost:7000/Service1.svc">
</endpoint>
</service>
<service name="YangkeeServer.Service2">
<endpoint
contract="YangkeeServer.IService2"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="http://localhost:7000/Service2.svc">
</endpoint>
</service>
<service name="YangkeeServer.YangkeeTrailer">
<endpoint
contract="YangkeeServer.IYangkeeTrailor"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="http://localhost:7000/YangkeeTrailor.svc">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebHttp">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
and um using this urlhttp://localhost:7000/Service1.svc and um getting this error
Server Error in '/' Application.
When 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' is set to true in configuration, the endpoints are required to specify a relative address. If you are specifying a relative listen URI on the endpoint, then the address can be absolute. To fix this problem, specify a relative uri for endpoint 'http://localhost:7000/Service1.svc'.
can any one tell me where did I do wrong? Thank you in advance.
Set the service endpoint address to just the service filename (this is the relative part):
address="Service1.svc"
or set the address to blank for each endpoint (I don't think its needed when hosting in the development environment or in IIS)
address=""
See this answer to another question
The relevant part is:
the virtual directory (in IIS) where your *.svc file exists defines your service endpoint's address.
To fix this error, I added... listenUri="/" ... to the service endpoint.
Example:
<service name="_name_">
<endpoint address="http://localhost:_port_/.../_servicename_.svc"
name="_servicename_Endpoint"
binding="basicHttpBinding"
bindingConfiguration="GenericServiceBinding"
contract="_contractpath_._contractname_"
listenUri="/" />
</service>
MSDN: Multiple Endpoints at a Single ListenUri
This works for me:
1. Insert this lines inside service:
<host>
<baseAddresses>
<add baseAddress="http://localhost:7000/Service1.svc" />
</baseAddresses>
</host>
2. Set the value of address as bellow:
address=""
The full code:
<service name="YangkeeServer.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7000/Service1.svc" />
</baseAddresses>
</host>
<endpoint
contract="YangkeeServer.IService1"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="">
</endpoint>
</service>

WCF rest service: unable to call methods

Please tell me I'm doing something stupid in setting up my wcf rest service.
I've create a web application and added a wcf service to it.
Here is my web.config
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WebApplication1.Service1">
<endpoint address="../Service1" behaviorConfiguration="httpBehavior"
binding="webHttpBinding"
contract="WebApplication1.IService1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="httpBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
And my service interface:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate = "data/{value}", ResponseFormat = WebMessageFormat.Json)]
Person GetData(string value);
}
And my service code:
public class Service1 : IService1
{
public Person GetData(string value)
{
return new Person()
{
Id = Convert.ToInt32(value),
Name = "John Doe"
};
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
I have no problems browsing to the service
http://localhost/RoleProviderSite/Service1.svc
but as soon as I add the data/10
http://localhost/RoleProviderSite/Service1.svc/data/10
"There was no channel actively listening at 'http://mymachinename/RoleProviderSite/Service1.svc/data/10"
I would have thought that adding the "[WebGet(UriTemplate = "data/{value}", ResponseFormat = WebMessageFormat.Json)]" would mean that this url would be accessible, but maybe I'm missing something?
I'm using :
Internet Information Services, Version: 5.1
and XP OS
Thanks very much for any help.
remove the address in the endpoint and your URI should work as expected. You cannot use relative addressing like that for your endpoint

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.