Creating a single file WCF for testing IIS setup - wcf

Is it possible to create a single .svc file (WCF Service) that I can upload to my server and test if it correctly handles WCF files? i.e. it is configured to host WCF services.
(I have a IIS6 box that I have to test)

You can use inline coding in your svc file:
%# ServiceHost Language="C#" Debug="true" Service="MyService.MyService" %>
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace MyService
{
[ServiceContract]
public interface IMyService
{
[OperationContract]
int MyMethod(int x, int y);
}
public class MyService : IMyService
{
public int MyMethod(int x, int y)
{
return ((x + y) * 2);
}
}
}
But you will need also a web.config file and a virtual directory configured on your web server:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="false" />
</system.web>
<system.serviceModel>
<services>
<service name="MyService.MyService">
<endpoint address="" binding="wsHttpBinding" contract="MyService.IMyService" />
</service>
</services>
</system.serviceModel>
</configuration>
But basically if your web server has IIS 6.0 and .NET 3.0 installed then you should have no problems running WCF services on it.

Related

WCF Restful Service :-Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata

The error is
On ctrl+F5 I am getting following error.
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
Here Is my interface declaration
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
namespace DealerAuditWCFService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IDealerAuditService" in both code and config file together.
[ServiceContract]
public interface IDealerAuditService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetDealerbyRegId/{regId}", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
Registration GetDealerbyRegId(string regId);
//[OperationContract]
//List<Registration> GetAllDealers();
//[OperationContract]
//void SaveDealerReg(List<Registration> regDetails);
}
}
Here is interface implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data.Entity;
namespace DealerAuditWCFService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "DealerAuditService" in code, svc and config file together.
public class DealerAuditService : IDealerAuditService
{
public Registration GetDealerbyRegId(string regId)
{
using (DealerAuditEntities dealerAudit = new DealerAuditEntities())
{
Registration regDetails = new Registration();
var reg = (from r in dealerAudit.tblRegistrationDetails
where r.regId == regId
select r).First();
regDetails.regId = reg.regId;
regDetails.Location = reg.Location;
regDetails.Region = reg.Region;
regDetails.typeOfAudit = reg.typeOfAudit;
return regDetails;
}
}
}
}
class for data members
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
namespace DealerAuditWCFService
{
[DataContract]
public class Registration
{
[DataMember]
public string regId { get; set; }
[DataMember]
public string channelPartnerName { get; set; }
[DataMember]
public string Location { get; set; }
[DataMember]
public string Region { get; set; }
[DataMember]
public string typeOfAudit { get; set; }
}
}
Here is my web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior" >
<serviceMetadata httpGetEnabled="True"/>
<!--<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>
<services>
<service name="DealerAuditWCFService.DealerAuditService" behaviorConfiguration="metadataBehavior">
<endpoint address="" binding="basicHttpBinding" contract="DealerAuditWCFService.IDealerAuditService" behaviorConfiguration="DealerAuditWCFService.DealerAuditService"/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<connectionStrings>
<add name="DealerAuditEntities" connectionString="metadata=res://*/DealerAuditEntityDataModel.csdl|res://*/DealerAuditEntityDataModel.ssdl|res://*/DealerAuditEntityDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=192.168.8.122;initial catalog=Beat_plan_db;persist security info=True;user id=sa;password=sa#122;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
As i am new to WCF,So trying to invoke a sample method through REST service.I keep on getting the same error.Please help me to solve this issue.
Firstly, you need to decide if you are going to expose a REST or a SOAP endpoint. The decision is complex and not really the topic in question here.
For REST, you need to use the webHttpBinding, for SOAP, either the basicHttpBinding or the wsHttpBinding.
However, to produce metadata (at least of the type supported by the proxy generator via visual studio add service reference functionality), you are limited to a SOAP endpoint.
To consume a REST endpoint you need to model the same DTOs as the service (or just use the same assembly where they are defined), and then use either HttpClient or WebClient (there are advantages to both).

Restful WCF and Basic Authentication via Fidder

I have created a WCF rest web service. However the client has requested the service be locked down with Basic Authentication but allow them to present the authorization token on first response rather than a challenge. Unfortunately I only have IIS 6 on my test machine
I only really need to simulate Basic Authentication so I doing this over anonymous and throwing an error if the Authorisation token is incorrect. However auth token is not available to the WCF
http://localhost/test.svc/get/token/
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Base64Value
If I remove anonymous and add basic in IIS. All's I get is a 401. Which I guess in IIS doing the authentication before the WCF.
Ideally I'd just like anoymous access and be able to access the authorization header.
How can I get the auth header
Your assumption for this beeing an issue of IIS 6 is probably right.
I just created a WCF service "xxx.svc" and hosted it in the IIS (7.5), and when I requested it with fiddler2 with a correct Authorization header, it did not send a HTTP 401.
I will post my code so that you test it on IIS 6. If it still gives you HTTP 401, then this is surely an IIS 6 issue, if not try to compare and contrast your code with mine and see what configurations are different.
web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindConfig">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="MyTestSvc.MyService">
<endpoint address="http://localhost/TestBasicAuth/Service1.svc" behaviorConfiguration="webHttpEndpointBehavior"
binding="webHttpBinding" bindingConfiguration="webHttpBindConfig"
name="webHttpBindingEndpoint" contract="MyTestSvc.IMyService" />
<host>
<baseAddresses>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Service1.svc
<%# ServiceHost Language="C#" Debug="true" Service="MyTestSvc.MyService" CodeBehind="Service1.svc.cs" %>
IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyTestSvc
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IMyService
{
[OperationContract]
[WebGet(UriTemplate=#"/Hello")]
string GetData();
}
}
and finally: Service1.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyTestSvc
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
public class MyService : IMyService
{
public string GetData()
{
WebOperationContext webCtx = WebOperationContext.Current;
IncomingWebRequestContext incomingCtx = webCtx.IncomingRequest;
string hdrVal = incomingCtx.Headers["Authorization"];
return string.Format("Authorization: {0}", hdrVal);
}
}
}
fiddler Results:

Self hosted WCF Service not working when i type url in browser?

I'm new to WCF. I have made a simple self hosted service and added app.config but when I type address in the browser it is not showing me the service page that we get when we create our service http://localhost:8067/WCFService it is not displaying the service as it shows when we run service.
But when I try to add base service in public static void main instead of app.config it works fine m not getting yy?? Can anyone please help me?
Following is the app.config file manually added:
<configuration>
<system.serviceModel>
<services>
<service name="SelfHostedWCFService.WCFService">
<endpoint
address="http://localhost:8067/WCFService"
binding="wsHttpBinding"
contract="SelfHostedWCFService.IWCFService">
</endpoint>
</service>
</services>
</system.serviceModel>
</configuration>
Following is the Program.cs:
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(SelfHostedWCFService.WCFService));
host.Open();
Console.WriteLine("Server is Running...............");
Console.ReadLine();
}
Following is the interface file manually added:
namespace SelfHostedWCFService
{
[ServiceContract]
interface IWCFService
{
[OperationContract]
int Add(int a, int b);
[OperationContract]
int Sub(int a, int b);
[OperationContract]
int Mul(int a, int b);
}
}
Following is the service.cs file manually added:
namespace SelfHostedWCFService
{
class WCFService:IWCFService
{
public int Add(int a, int b) { return (a + b); }
public int Sub(int a, int b) { return (a - b); }
public int Mul(int a, int b) { return (a * b); }
}
}
Is something wrong with my app.config or some other concept??
Everything seems ok at first glance - are you sure the service isn't running??
Without any metadata being published, you cannot test the service using the WCF Test Client, nor can you generate a client-side proxy for it....
So I would recommend adding service metadata publishing to your service, and doing so, I was able to test that code of yours and it works just flawlessly.
To add metadata, change your config to:
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Metadata">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="SelfHostedWCFService.WCFService" behaviorConfiguration="Metadata">
<endpoint
address="http://localhost:8067/WCFService"
binding="wsHttpBinding"
contract="SelfHostedWCFService.IWCFService" />
<endpoint address="http://localhost:8067/WCFService/mex"
binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
Even with this config, you won't see any service page when navigation to the URL - but the service is up and running - just use the WCF Test Client and see for yourself!

Windows service hosting a WCF service closing immediately

I tried hosting a WCF Library service with windows service project, I installed the service, however, when i start the service in services.msc, the service start and closses immediatly. Following the message that gets displayed:
The Servicel service on Local
Computer started and then stopped.
Some services stop automatically if
they are not in use by other services
or programs.
The App.config file for wcf and the windows service project is same and it is as follows:
<?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="WorkMateWCF.Service1">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="WorkMateWCF.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8523/WorkMate1" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The entire project/solution is downloadable here: https://skydrive.live.com/?cid=d358d316fa2c3a37&sc=documents&uc=1&id=D358D316FA2C3A37%21135#
Could you please guide me on how to proceed further. Thank you.
Additional information:
Following is the code from the service1.cs file in windows service project.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using WorkMateWCF;
namespace WorkMateWinService
{
public partial class Service1 : ServiceBase
{
internal static ServiceHost MyServiceHost = null;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
if (MyServiceHost != null)
{
MyServiceHost.Close();
}
MyServiceHost=new ServiceHost(typeof( Service1));
MyServiceHost.Open();
}
protected override void OnStop()
{
if (MyServiceHost != null)
{
MyServiceHost.Close();
MyServiceHost = null;
}
}
}
}
What I find very confusing (and probably the .NET runtime, too) is the fact that your Windows Service is called Service1, while your WCF Service also is called Service1 (without a namespace or anything).
So which of the two Service1 class types will be used here???
MyServiceHost = new ServiceHost(typeof(Service1));
I'm not sure - and I'm afraid it will be the wrong class (the Windows NT Service class).
You should give your stuff more meaningful names and keep those things apart (by name, too) !
Got the issue, when I reviewed my event logs I found this:
"Service cannot be started. System.InvalidOperationException: The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address. Either supply an http base address or set HttpGetUrl to an absolute address.
at System.ServiceModel.Description.ServiceMetadataBehavior.EnsureGetDispatcher(ServiceHostBase host, ServiceMetadataExtension mex, Uri url, String scheme)
at System.ServiceModel.Description.ServiceMetadataBehavior.CreateHttpGetEndpoints(ServiceDescription description, ServiceHostBase host, ServiceMetadataExtension mex)
at System.ServiceModel.Description.ServiceMetadataBehavior.ApplyBehavior(ServiceDescription description, ServiceHostBase host)
at System.ServiceModel.Description.ServiceMetadataBehavior.System.ServiceModel.Description.IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescript..."
Then after thorough reviewing, the issues is that I did HTTPSGETENABLED to false only for one, infact there are two, after making the change for the other one, the app started to work like charm.
I special

BadImageFormatException IIS hosted WCF service Win7 x86, VS2010b2

My system is Windows 7 Ultimate 32 bit. Running Visual Studio 2010 beta 2 targeting .Net 4.
I have a project containing service contracts.
A project containing the services.
And an ASP.NET Web Application that is hosting the services in IIS.
I've written my own Clients using the ChannelFactory().CreateChannel()...
Whenever I run my application that uses the ServiceClient and calls a method on the service, I get this error:
An attempt was made to load a program with an incorrect format.
(Exception from HRESULT: 0x8007000B)
I've tried to add a service reference in VS, so that the service client is auto-generated and that doesn't change anything.
Then I tried to create a new WCF Service Application from the Web category in VS2010, adding a service reference and calling the standard GetData method That works fine, so it is for sure my service or the hosting of the service that goes wrong...
UPDATE
I noticed that this error was only present when using wsHttpBindings. basicHttpBindings works fine.
This is how I instantiate the service:
private IAdminService _AdminService;
public AdminServiceClient()
{
_AdminService = new ChannelFactory<IAdminService>(String.Empty)
.CreateChannel();
}
Client config settings:
<system.serviceModel>
<client>
<endpoint address="http://AdminServices/svcs/AdminService.svc"
binding="wsHttpBinding"
contract="MyApp.Admin.Model.ServiceContracts.IAdminService" />
</client>
</system.serviceModel>
My service looks like this:
public class AdminService : IAdminService
{
public User GetUserByEmail(string email)
{
throw new NotImplementedException();
}
public void CreateUser(string fullname, string email,
string encryptedPassword,
string encryptedPasswordQuestion,
string encryptedPasswordAnswer)
{
throw new NotImplementedException();
}
public IEnumerable<Application> GetApplications()
{
IEnumerable<Application> apps = new List<Application>();
// Call data access layer method to retrieve Applications
return apps;
}
public IEnumerable<ApplicationInstance> GetApplicationInstances(
long? applicationId)
{
throw new NotImplementedException();
}
public Dictionary<string, string> GetApplicationsAndInstances()
{
Dictionary<string, string> appsAndInstances =
new Dictionary<string, string>();
appsAndInstances.Add("Dummy 1", "1");
appsAndInstances.Add("Dummy 2", "2");
return appsAndInstances;
}
}
My AdminService.svc file looks like this:
<%# ServiceHost Service="MyApp.Admin.Services.AdminService" %>
My Service Host config looks like this:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true"
targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="MyApp.Admin.Services.AdminService">
<endpoint address=""
binding="wsHttpBinding"
contract="MyApp.Admin.Model.ServiceContracts.IAdminService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I've also tried to create a new Console App, and add a service reference to http://AdminServices/svcs/AdminService.svc - that doesn't work either.
I've added AdminServices to my hosts file, and I can browse http://AdminServices/svcs/AdminService.svc and see the service information...
The most obvious cause would be that you are loading a 64 bits DLL into a 32 bits process or visa versa. However given that you are running everything on a a 32 bits development box I assume this isn't the case.
The other option is a .NET bug using a generic constraint like this:
public class SpecificClass: BaseClass: where T : class { }
If you remove the where T : class it should work just fine.