I'm struggling to have my WCF web service output a wsdl file with no luck so far (it's empty?).
the svc file:
<%# ServiceHost Language="C#" Debug="true" Service="xxx.WCF.SubsetMID" CodeBehind="SubsetMID.svc.cs"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
%>
the cs file :
namespace xxx.WCF
{
[ServiceContract(Namespace = "SubsetMID")]
public interface ISubsetMID
{
[OperationContract]
[WebInvoke(BodyStyle=WebMessageBodyStyle.Wrapped)]
long[] GetMIDs(Guid guid, int subsetID);
}
[DataContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class SubsetMID : ISubsetMID
{
public long[] GetMIDs(Guid guid, int subsetID)
{
[...]
return returnValue;
}
}
}
My web config file :
<system.serviceModel>
<services>
<service name="xxx.WCF.SubsetMID">
<endpoint address=""
binding="wsHttpBinding"
contract="xxx.WCF.ISubsetMID" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment
multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true"
/>
</system.serviceModel>
I don't get any error when I access the wsd (http://.../SubsetMID.svc?wsdl) but it's just a blank page.
The following is a best guess based on some research I did - I'm not that familiar with RESTful WCF services, so I might be wrong but this should give you a starting point at least.
You didn't specify, but it looks like you're trying to write a RESTful WCF service. I'm not entirely certain, because you use wsHttpBinding in your endpoint, but you also decorate the method in the service with [WebInvoke].
In any event, REST services do not have WSDLs - that's a SOAP thing. Additionally, I believe WCF supports REST with the webHttpBinding. As you are using WebServiceHostFactory in your .svc file, I think this is what is happening:
You do not have any webHttpBinding endpoints defined. WCF will create a default webHttpBinding endpoint, with the address based on the location of the .svc file. However, when default endpoints are used according to WebServiceHost Class:
...the WebServiceHost also disables the HTTP Help page and the Web Services Description Language (WSDL) GET functionality so the metadata endpoint does not interfere with the default HTTP endpoint.
If you're writing a REST service, you won't need a WSDL. If you're planning on having a SOAP service, then use ServiceHostFactory in your .svc file and remove the [WebInvoke] attribute from the method.
Again, this is a (relatively) educated guess, and it may be wrong, but it's a place to start.
Im guessing that you are using a wcf service website project which contains the svc file. if you dont, i strongly recommend you to do that and set it as the startup project in your solution, so you could debug it properly. for me, and good chances that for you too if you followed codeproject step by step instructions, the problem was that i didn't reference the wcf services from the website, thus the directive in the svc couldn't find the service. hope i helped
Related
I am very new to WCF and I have questions about it.
After going through some articles I found that in the web.config file if I change the endpoint binding to webHttpBinding from basicHttpBinding and httpGetEnabled from true to false it uses REST.
My question is are these the only two things that I need to change to make a service SOAP or REST? Or do I need to change/add any other things?
You can expose the service in two different endpoints. the SOAP one can use the binding that support SOAP e.g. basicHttpBinding, the RESTful one can use the webHttpBinding. I assume your REST service will be in JSON, in that case, you need to configure the two endpoints with the following behaviour configuration
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
An example of endpoint configuration in your scenario is
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="ITestService"/>
</service>
</services>
Apply [WebGet] to the operation contract to make it RESTful. e.g.
public interface ITestService
{
[OperationContract]
[WebGet]
string HelloWorld(string text)
}
SOAP request client endpoint configuration for SOAP service after adding the service reference,
<client>
<endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
contract="ITestService" name="BasicHttpBinding_ITestService" />
</client>
in C#
TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");
I am totally new to WCF and I am still learning the basics. What I've learned so far was that I can create a service and configure its endpoints and behaviors in the service's config file. And when I run my service through visual studio, a default application will be created and the service will be hosted in IIS successfully and everything works great.
Now when I create a host application for my service, I figured out that I should add the service endpoints (and behaviors) for my service again in the code as following:
ServiceHost host = new ServiceHost(typeof(HelloService));
host.AddServiceEndpoint(typeof(IHelloWorld),
new WSHttpContextBinding(),
"http://localhost:8873/helloworld/ws");
host.Open();
foreach (var se in host.Description.Endpoints)
{
Console.WriteLine(se.Address);
}
host.Close();
Console.Read();
or I can do it in the host application's config file
So here are my question :
what is the point of defining endpoints in service's own config file when it is not even useful in a host application?
Or is it that service's config file only applies to IIS and managed hosts only?
and finally is there a way to have the service's own configurations in the host application (not defining the endpoints and behaviors in the host application again) or the two mentioned configurations are completely different?
EDIT
my ultimate question is that how can I use the configurations defined in service's config file in the host application?(Without using host application's own config file or creating additional code to define new endpoints and behaviors
)
Now when I create a host application for my service, I figured out
that I should add the service endpoints (and behaviors) for my service
again in the code
This is incorrect. You don't have to define your service endpoint in code at all. That is what the config file is for.
Simply pass in the name of your service (as defined in your config file) as a type into your servicehost contructor:
var host = new ServiceHost(typeof(MyNamespace.MyService));
With the config defined as:
<system.serviceModel>
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="MyService"
binding="basicHttpBinding"
contract="MyNamespace.IMyService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8456/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
WCF will work out that you want to use the config file to define the service to run.
i have created a wcf service but i have used 3 projects for it;
1) ServiceLibrary (WCF library)
2) Web
3) ConsoleTestClient
my ServiceLibrary app.config file looks like this;
<system.serviceModel>
<services>
<service name="MrDAStoreJobs.ServiceLibrary.AdvertisementService">
<clear />
<endpoint address="basic"
binding="basicHttpBinding" bindingConfiguration=""
contract="MrDAStoreJobs.ServiceLibrary.Interface.IAdvertisementService" />
<endpoint name="mexHttpBinding"
contract="IMetadataExchange"
binding="mexHttpBinding"
address="mex" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:13758/" />
</baseAddresses>
</host>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false 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>
</behaviors>
</system.serviceModel> <br />
Now, to host this library, i have done the following settings in my Web.Config file of the Web Project.
The svc file name is WcfDataService1.svc
public class WcfDataService1 : DataService<AdvertisementService>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
config.UseVerboseErrors = true;
ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
<system.serviceModel>
<services>
<service name="MrDAStoreJobs.ServiceLibrary.AdvertisementService">
<clear />
<endpoint address="basic"
binding="basicHttpBinding" bindingConfiguration=""
contract="MrDAStoreJobs.ServiceLibrary.Interface.IAdvertisementService" />
<endpoint name="mexHttpBinding"
contract="IMetadataExchange"
binding="mexHttpBinding"
address="mex" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:13758/WcfDataService1.svc" />
</baseAddresses>
</host>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false 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>
</behaviors>
</system.serviceModel>
Now, when i test this service using directly (ServiceLibrary project) using WCF test client, i see the following and works everything great;
The issue is when i try to run my Web project(which i use as a host for wcf service). And then go to the console test client and want to add reference using add reference. I don't see my Get and Set methods (like test client)
Why i don't see my IAdvertisementService interface and the methods
Do i have to deploy this to actuall IIS?
To develop a service using ASP.NET, we must add the WebService attribute to the class and WebMethodAttribute to any of the class methods.
Example
[WebService]
public class Service : System.Web.Services.WebService
{
[WebMethod]
public string Test(string strMsg)
{
return strMsg;
}
}
To develop a service in WCF, we will write the following code:
[ServiceContract]
public interface ITest
{
[OperationContract]
string ShowMessage(string strMsg);
}
public class Service : ITest
{
public string ShowMessage(string strMsg)
{
return strMsg;
}
}
The ServiceContractAttribute specifies that an interface defines a WCF service contract,
OperationContract attribute indicates which of the methods of the interface defines the operations of the service contract.
A class that implements the service contract is referred to as a service type in WCF.
Hosting the Service
ASP.NET web services are compiled into a class library assembly and a service file with an extension .asmx will have the code for the service. The service file is copied into the root of the ASP.NET application and Assembly will be copied to the bin directory. The application is accessible using URL of the service file.
WCF Service can be hosted within IIS or WindowsActivationService.
Compile the service type into a class library
Copy the service file with an extension .SVC into a virtual directory and assembly into bin sub directory of the virtual directory.
Copy the web.config file into the virtual directory.
Client Development
Clients for the ASP.NET Web services are generated using the command-line tool WSDL.EXE.
WCF uses the ServiceMetadata tool (svcutil.exe) to generate the client for the service.
For more detail goto this link
http://www.codeproject.com/Articles/139787/What-s-the-Difference-between-WCF-and-Web-Services
Previous Post Removed:
Update:
The Microsoft Developer Network actually covers this in great detail, some of the resources they provide are:
Overview
Tutorial From Code Project
There are also several books that my solve this particular endeavor. Since someone stated that providing links to solve this issue doesn't truly answer your question I'll attempt to.
Inside Visual Studio click File, then proceed to New Project.
In the dialog expand Visual C#, Select Web and ASP.NET Web Forms Application.
Give your project a name of your choice NorthwindWeb.
At this point you've created a project; due to the complexity of a Service overlooking a tiny detail can be catastrophic in the outcome. That is why I'm starting from scratch.
In my example I'll link it to a Database. So I'll add a Ado.Net Entity Data Model. I'll name my model: NorthwindModel. I'm also going to generate based upon an existing Database. So up at this point just follow the Visual Studio Wizard. Choose your Database Objects within those tables, then Finish.
The important part, building my Data Service.
Project Add New Item.
Select Web and choose WCF Data Service.
Put a name, NorthwindCustomer- Then Add.
Locate the first Todo: Comment and remove the code then put:
public class DemonDbCustomer : DataService<demonDbEntities>
Then find the comments in the InitializeService Event Handler:
config.SetEntitySetAccessRule("*", EntitySetRights.All);
At this point hit CTRL + F5 to run the service. The browser will open and the XML Schema for the service will generate. In the Address Bar type in Customers at the end of the URL for NorthwindCustomers.svc and hit Enter.
** Sometimes Internet Explorer will mess this up, so additional troubleshooting may be required. **
Now we will create our Client Portion.
Add a New Project
Select Windows Forms Application
Name the file of your choice, NorthwindClient then click Ok.
In the Solution Explorer select the NorthwindClient Project and Set As Startup Project.
Right Click on Project: Add Service Reference Click Discover.
At this point your URL for NorthwindCustomers Service will appear in that Address field. This is generated from that .svc file.
Now we have to provide data binding to our service.
On the Data Menu we want to Show Data Sources.
Add New Data Source
Choose the type of Data Source and follow the Wizard (Click Object).
Select the Object you wish to bind.
Now at this point you just need to create a User Interface. To do so just simply drag your Customers Node from your Data Sources to the Form.
DataGridView
BindingSource
BindingNavigation
They are all added automatically. Then simply double click your Form and add the following to your Form1_Load Event Handler.
ServiceReference1.northwindModel.northwindEntities proxy = new
ServiceReference1.northwindModel.northwindEntities(new
Uri("http://localhost:53397/NorthwindCustomers.svc/"));
// As you see it pointed to our SVC file, because that includes our Address, Binding, Contract information.
this.customersBindingSource.DataSource = proxy.Customers;
Now in your Solution Explorer right click that NorthwindCustomers.svc and click View In Browser. The XML Schema will be added, so you just copy that URL from the Address Bar. Then replace the Uri with the one you just copied.
Run your application and you've down the following:
Host
Client
Service
Consumed
That is how to consume a WCF Data Service the article that has even more detail is here:
Hopefully that helps.
Allmost all day today I am trying to research on WCF and one of my aim was to create a WCF service manually (or almost so).
Based on few articles on web on how to structure WCF application I have created contracts project which contain service interfaces and implementation project. Both have Runtime.Serialization
I have created app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="FulFillmentServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="FulFillmentServiceBehaviour"
name="Project.Services.Fulfillment">
<endpoint address="http://localhost:8080/Services" binding="basicHttpBinding"
bindingConfiguration="" contract="P.Infrastructure.Services.IFulfillment" />
<endpoint binding="mexHttpBinding" bindingConfiguration="" />
</service>
</services>
</system.serviceModel>
</configuration>
1) How can I host this service in IIS
I already created virtual directory pointing to folder containing project Services (url http://localhost:8080/Services)
2) How to create wsdl file so that I can use SOAPUI to test it
I tried adding a file "fulfillment.svc" with markup
<%# ServiceHost Language="C#" Debug="true" Service="Project.Services.Fulfillment" CodeBehind="Fulfillment.cs" %>
for the purpose of testing but it gave error
The type Project.Services.Fulfillment', provided as the Service attribute value in the ServiceHost directive could not be found.
Update 1******
just found this on net - may be this will help. one imp ino is that i will need web.config
http://wncadmb026d.na-idm.na-gad.nec.com/Services/Fulfillment.svc?wsdl
Update 2:*****
SOAP UI is able to generate SOAP request but gers http 404 as response...
http://www.aspfree.com/c/a/ASP.NET/Developing-a-WCF-Service-Library-and-Hosting-it-as-WCF-Web-Service-Using-VS2K8/
I was able to get the basic service up with help from
http://www.aspfree.com/c/a/ASP.NET/Developing-a-WCF-Service-Library-and-Hosting-it-as-WCF-Web-Service-Using-VS2K8/
and
http://msdn.microsoft.com/en-us/library/ms733766(v=VS.90).aspx
I copied service model section from app.congig to web.config
I also had to chaNGE BUILD FOLDER TO /BIN Instead of /bin/debug/
will add more code tomorrow morning
For WSDL page you have the correct attribute:
<serviceMetadata httpGetEnabled="true" />
And you can access it by adding ?wsdl to the URL, ie http://localhost:8080/Service.svc?wsdl
As for the error, I think the problem is that you are not using the .svc extension:
<%# ServiceHost Language="C#" Debug="true"
Service="Project.Services.Fulfillment" CodeBehind="Fulfillment.svc.cs" %>
You are using a .svc file, right?
If you are not using an .svc file one thing to do is use routing, see this link for an example: http://geekswithblogs.net/michelotti/archive/2010/08/21/restful-wcf-services-with-no-svc-file-and-no-config.aspx
I have a test project, WCF Service Library, and I published the project. Have a 2003 server with all the right installation. I browse to my application and upon clicking on .svc I get this error.
The type 'SearchService', provided as the Service attribute value in the ServiceHost directive could not be found.
This is the snippet from my web.config
<endpoint address="" binding="wsHttpBinding" contract="TestService.ISearchService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
My Interface:
[ServiceContract]
public interface ISearchService
{
[OperationContract]
string GetName();
}
My Implementation:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class SearchService :ISearchService
{
#region ISearchService Members
public string GetName()
{
returnn "HAL-2001"
}
}
Well, the wsHttpBinding requires you to connect to your service using SOAP - a web browser alone won't cut it, so that's why it's not working when you browse to the .svc file. Nothing wrong there, really.
You need to create a real full-fledged SOAP client to connect to your service and test it. Alternatively, you could also use the WcfTestClient.exe test client which sits in your VS2008\Common7\IDE folder.
Marc
ANo, the error indicates the host could not find the definition for service implementation "SearchService" in your web.config. In you web.config, you need to wrap the <endpoint> tag in a <service> tag. The name attribute of the <service> should be set to the full name of you SearchService class ( including all namespaces). You also need to define a behavior to enable the service to show WSDL in a browser. You may also want to remove the <dns value="localhost" /> when you deploy the service to a server.
Here is an example snippet, make sure your put the full class name of SearchService in <service> tag, and also make sure the full class name is in your .svc file:
<system.serviceModel>
<services>
<service name="SearchService" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="wsHttpBinding" contract="TestService.ISearchService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<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="false"/>
</behavior>
</serviceBehaviors>
</behaviors> </system.serviceModel>
ANo, you should switch over to the basicHttpBinding and test to make sure everything is working. You're using the WSHttpBinding and by default it has authentication turned on. You're client will need to pass credentials for it to actually get a response, that's why the browser call isn't working.
What is your client code calling? For this to work it should be calling a proxy class like the following.
class SearchServiceProxy : ClientBase<ISearchService>, ISearchService
{
public string GetName()
{
return Channel.GetName();
}
}