This is my first WCF service and I am getting an error:
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
Code:
namespace WcfMathServiceLibrary
{
[ServiceContract]
public interface IMath
{
[OperationContract]
double Add(double i, double j);
[OperationContract]
double Sub(double i, double j);
[OperationContract]
Complex AddComplexNo(Complex i, Complex j);
[OperationContract]
Complex SubComplexNo(Complex i, Complex j);
}
[DataContract]
public class Complex
{
private int _real;
private int _imaginary;
[DataMember]
public int real { get; set; }
[DataMember]
public int imaginary { get; set; }
}
namespace WcfMathServiceLibrary
{
public class MathService : IMath
{
public double Add(double i, double j)
{
return (i + j);
}
public double Sub(double i, double j)
{
return (i - j);
}
public Complex AddComplexNo(Complex i, Complex j)
{
Complex result = new Complex();
result.real = i.real + j.real;
result.imaginary = i.imaginary + j.imaginary;
return result;
}
public Complex SubComplexNo(Complex i, Complex j)
{
Complex result = new Complex();
result.real = i.real - j.real;
result.imaginary = i.imaginary - j.imaginary;
return result;
}
}
Web.Config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfMathServiceLibrary.MathService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/WcfMathServiceLibrary/MathService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="WcfMathServiceLibrary.MathService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" >
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I am not sure what is the issue. Could you please guide me?
I think your contract may need to point to the interface and not the concrete implementation
<endpoint address="" binding="wsHttpBinding" contract="WcfMathServiceLibrary.IMath">
Related
I try to write simple subscription service with soap and rest operations. This is my code:
SubsService.svc:
namespace SubscriptionService
{
public class SubsService : ISubsService
{
public string RegisterEvent(string serviceId, string name, string description)
{
return "ok";
}
public void UnregisterEvent(string serviceId, string name)
{
// TO DO
}
public void RiseEvent(string serviceId, string name)
{
// TO DO
}
public string EventsList(string token)
{
return token;
}
public void Subscribe(string token, string serviceId, string name)
{
// TO DO
}
public void UnSubscribe(string token, string serviceId, string name)
{
// TO DO
}
}
}
ISubsService.cs:
namespace SubscriptionService
{
[ServiceContract]
public interface ISubsService
{
// SOA
[OperationContract]
string RegisterEvent(string serviceId, string name, string description);
[OperationContract]
void UnregisterEvent(string serviceId, string name);
[OperationContract]
void RiseEvent(string serviceId, string name);
// REST
[OperationContract]
[WebGet(UriTemplate = "events?token={token}")]
string EventsList(string token);
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "subscribe?token={token}&serviceId={serviceId}&name={name}")]
void Subscribe(string token, string serviceId, string name);
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "unsubscribe?token={token}&serviceId={serviceId}&name={name}")]
void UnSubscribe(string token, string serviceId, string name);
}
}
and web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="SubscriptionService.SubsService">
<endpoint address="soap" binding="basicHttpBinding" contract="SubscriptionService.ISubsService"></endpoint>
<endpoint address="rest" binding="webHttpBinding" contract="SubscriptionService.ISubsService" behaviorConfiguration="web"></endpoint>
</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="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
When I try to access http://localhost:2354/SubsService.svc, I get error:
Operation 'RegisterEvent' of contract 'ISubsService' specifies multiple request body parameters to be serialized without any wrapper elements. At most one body parameter can be serialized without wrapper elements. Either remove the extra body parameters or set the BodyStyle property on the WebGetAttribute/WebInvokeAttribute to Wrapped.
But RegisterEvent has to be soap operation. What is wrong with my code? Something in web.config?
I have build a simple WCF service using wsDualHttpBinding. It is working fine at local end but it throws a error when I publish the service on a different server and try to consume that service in a WPF project.
Error:
System.ServiceModel.SecurityNegotiationException "The caller was not authenticated by the service."
InnerException:
System.ServiceModel.FaultException "The caller was not authenticated by the service."
Server Config:
<system.serviceModel>
<services>
<service name="VetChat.Service.VetChatService" behaviorConfiguration="wsDualHttpBinding.SampleServiceBehavior">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress="http://service.softprodigy.com:8090/VetChatService.svc"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsDualHttpBinding" contract="VetChat.Service.IVetChatService">
<!--
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.
-->
<identity>
<dns value="VPS" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wsDualHttpBinding.SampleServiceBehavior">
<!-- 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"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="VetChat.Service.UserNamePassValidator, VetChat.Service" />
<serviceCertificate findValue="MyName" storeLocation="CurrentUser" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Client Config:
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IVetChatService" />
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://service.softprodigy.com:8090/VetChatService.svc"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IVetChatService"
contract="ServiceReference1.IVetChatService" name="WSDualHttpBinding_IVetChatService">
<identity>
<dns value="VPS" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="MyName" x509FindType="FindBySubjectName"
storeLocation="CurrentUser" storeName="TrustedPeople" />
<serviceCertificate>
<defaultCertificate findValue="MyName" storeLocation="CurrentUser" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Interface:
[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
public interface IVetChatService
{
[OperationContract(IsOneWay = true)]
void DoWork();
}
public interface ICallback
{
[OperationContract(IsOneWay = true)]
void Notify(string value);
}
Interface Implementation:
public class VetChatService : IVetChatService
{
public void DoWork()
{
//Thread.Sleep(5000);
OperationContext.Current.GetCallbackChannel<ICallback>().Notify("Hello");
}
}
Validte username password service class:
namespace VetChat.Service
{
class UserNamePassValidator :
System.IdentityModel.Selectors.UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName == null || password == null)
{
throw new ArgumentNullException();
}
if (!(userName == UserName && password == Password))
{
//throw new FaultException("Incorrect Username or Password");
}
}
}
public class Service
{
}
}
Call method:
InstanceContext instanceContext = new InstanceContext(new SampleServiceCallback());
ServiceReference1.VetChatServiceClient sampleServiceClient = new ServiceReference1.VetChatServiceClient(instanceContext);
sampleServiceClient.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.TrustedPeople,
X509FindType.FindBySubjectName,
"MyName");
sampleServiceClient.ClientCredentials.UserName.UserName = UserName;
sampleServiceClient.ClientCredentials.UserName.Password = Password;
//sampleServiceClient.Open();
sampleServiceClient.DoWork();
Response Callback:
public class SampleServiceCallback : ServiceReference1.IVetChatServiceCallback
{
#region ISampleServiceCallback Members
public void Notify(string value)
{
MessageBox.Show(value);
}
#endregion
}
Thanks
I am creating a WCF service with self hosting. I have found the following error i.e.:
The target assembly contains no service types. You may need to adjust the Code Access Security policy of this assembly.
The codes are as follows:
namespace MyJobs
{
public interface IJobsSvc
{
[OperationContract]
DataSet GetJobs();
[OperationContract]
Job GetJobInfo(int JobId);
[OperationContract]
List<Job> GetAllJobs();
}
}
namespace MyJobs
{
[DataContract]
public class Job
{
[DataMember]
public int JobId { get; set;}
[DataMember]
public string Description{get;set;}
[DataMember]
public int MinLevel { get; set; }
[DataMember]
public int MaxLevel { get; set; }
}
}
namespace MyJobs
{
public class JobsSvc:IJobsSvc
{
#region IJobsSvc Members
public System.Data.DataSet GetJobs()
{
string str = #"data source=PERSONAL-659BE4;database=practice;integrated security=true";
DataSet ds = new DataSet();
SqlConnection cn = new SqlConnection(str);
SqlDataAdapter da = new SqlDataAdapter("select * from Job1",cn);
da.Fill(ds);
return ds;
}
public Job GetJobInfo(int JobId)
{
string str = #"data source=PERSONAL-659BE4;database=practice;integrated security=true";
SqlConnection cn = new SqlConnection(str);
SqlCommand cmd = new SqlCommand("select * from Job1 where JobId="+JobId,cn);
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
Job obj = new Job();
if (dr.Read())
{
obj.JobId = JobId;
obj.Description = dr[1].ToString();
obj.MinLevel = Convert.ToInt32(dr[2]);
obj.MaxLevel = Convert.ToInt32(dr[3]);
}
else
{
obj.JobId = -1;
}
return obj;
}
public List<Job> GetAllJobs()
{
throw new NotImplementedException();
}
#endregion
}
}
The app.config file is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="MyJobs.Job">
<endpoint address="" binding="wsHttpBinding" contract="MyJobs.IJobsSvc">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/Jobs/MyJobs/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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>
</behaviors>
</system.serviceModel>
</configuration>
You need to add [ServiceContract] attribute to your IJobSvc interface
Update
Create the behavior to expose the metadata.
<serviceBehaviors>
<behavior name="SimpleServiceBehavior">
<!-- 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>
Then configure your service with this behavior:
<service name="MyJobs.Job" behaviorConfiguration="SimpleServiceBehavior">
<endpoint address="" binding="wsHttpBinding" contract="MyJobs.IJobsSvc">
Hi a have WCF service libary with this configuration:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="Default" name="ComDocs.ControlServerServiceLibary.Concrete.TokenService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/TokenService" />
</baseAddresses>
</host>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="basic" binding="basicHttpBinding" contract="ComDocs.ControlServerServiceLibary.Abstract.ITokenService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
If I build it in debug, everything works fine on localhost. But if I make a Windows Service library with the same configuration:
public partial class TokenService : ServiceBase
{
ServiceHost _host = null;
public TokenService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Trace.WriteLine("Starting Token Service...");
_host = new ServiceHost(typeof(TokenService));
_host.Open();
}
protected override void OnStop()
{
Trace.WriteLine("Shutting down Token Service...");
if (_host != null)
{
_host.Close();
_host = null;
}
}
}
Install it with InstallUtil and start it:
but error:
I suspect this line is the culprit.
_host = new ServiceHost(typeof(TokenService));
TokenService is your Windows service class, not your WCF service class.
Hey, here is my class code
namespace WcfServicepractice
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WebDataService1 : IMyclass
{
public int add(int a, int b)
{
return a + b;
}
public int multi(int a, int b)
{
return a * b;
}
}
}
this is my Interface code,
namespace WcfServicepractice
{
[ServiceContract]
public interface IMyclass
{
[OperationContract]
int add(int a,int b);
[OperationContract]
int multi(int a, int b);
}
}
this is my web.config for my service
<behavior name="WcfServicepractice.WebDataService1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<service name="WcfServicepractice.WebDataService1" behaviorConfiguration="WcfServicepractice.WebDataService1Behavior" >
<endpoint address="" binding="wsHttpBinding" contract="WcfServicepractice.IMyclass" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
When i run the code i get this error
The webpage cannot be found
Can someone help ?
Thanks..
From your error I assume you're trying to host the service in IIS (in this case probably using the Cassini server)
Do you have a svc file in your project?
What address are you browsing to?
You should be browsing to something like: http://localhost:someport/service.svc