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:
Related
I succeeded to create WCF web service in CodeGear Delphi for .NET 2007/2009.
I use this tutorial:
https://community.embarcadero.com/blogs/entry/building-net-35-wcf-restful-web-services-with-delphi-2007-38508
In this article they created console application and tested web service in it.
But i need to publish this WCF web service on IIS - how can I do that?
UPDATE:
I tried to make dll (not console app) and my work looks like this:
1) unit uServiceIntf.pas
unit uServiceIntf;
interface
uses
System.ServiceModel,
System.ServiceModel.Web;
type
[ServiceContract(Namespace = 'http://localhost:3000/')]
IService = interface
[OperationContract]
[WebGet(UriTemplate='Add?a={x}&b={y}')]
function Add(x, y: integer): integer;
end;
implementation
end.
2) unit uServiceImpl.pas
unit uServiceImpl;
interface
uses
uServiceIntf;
type
TService = class(TObject, IService)
public
function Add(x, y: integer): integer;
end;
implementation
{ TService }
function TService.Add(x, y: integer): integer;
begin
Result := x + y;
end;
end.
3) DelphiRESTBasicSample_Service_dll.dpr
library DelphiRESTBasicSample_Service_dll;
uses
SysUtils,
Classes,
System.Reflection,
System.Runtime.InteropServices,
uServiceImpl in 'uServiceImpl.pas',
uServiceIntf in 'uServiceIntf.pas';
[assembly: AssemblyTitle('')]
[assembly: AssemblyDescription('')]
[assembly: AssemblyConfiguration('')]
[assembly: AssemblyCompany('')]
[assembly: AssemblyProduct('')]
[assembly: AssemblyCopyright('')]
[assembly: AssemblyTrademark('')]
[assembly: AssemblyCulture('')]
[assembly: AssemblyVersion('1.0.*')]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile('')]
[assembly: AssemblyKeyName('')]
[assembly: ComVisible(False)]
begin
end.
4) DelphiRESTBasicSample_Service_dll.svc:
<%# ServiceHost Language="C#" Service="DelphiRESTBasicSample_Service_dll.TService" %>
5) web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="returnFaults">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="returnFaults" name="DelphiRESTBasicSample_Service_dll.TService">
<endpoint address="Add" binding="basicHttpBinding" contract="IService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:3000/DelphiRESTBasicSample_Service_dll.svc"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<system.web>
<customErrors mode="Off" />
</system.web>
<system.webServer>
<directoryBrowse enabled="false" />
</system.webServer>
</configuration>
6) Publish on IIS:
I put svc-file and web.config file in folder D:\MySite and dll-file in folder D:\MySite\bin.
I give all rights to folder D:\MySite for user IIS_IUSRS.
I make a site:
7) Result:
I try this in Chrome browser:
a) http://localhost:3000/Add?a=2&b=3
b) http://localhost:3000/DelphiRESTBasicSample_Service_dll.svc/Add?a=2&b=3
Both don't work.
What am i doing wrong?
Read this page: https://www.ojdevelops.com/2017/10/deploying-web-application-to-local-iis.html
It says the steps are as follows:
Besides that, if you want to have a specific URL that's not related to localhost, then add the URL you desire to be local to hosts, mapped to 127.0.0.1. In that case you will also need to set the host headers at IIS, see: https://docs.revenera.com/isxhelp23/helplibrary/IISHostHeader.htm
Maybe you can start by looking at the official documentation, which will guide you through the hosting service step by step.
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).
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
Sorry for asking a question about something I don't know much about, but I've been pulling my hair out trying to get this working.
So, I have a WCF service that is hosted on IIS and seems to be working insomuch that I can "see" it on the network by going to http://servername/MyService.svc in a browser.
That .svc looks like:
<% #ServiceHost Service="Foo.Bar" %>
The relevant code looks like:
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06Services/Notification/03")]
public interface IBar
{
[OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", ReplyAction = "*")]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
void Notify(string eventXml, string tfsIdentityXml);
}
and:
public class Bar : IBar
{
public void Notify(string eventXml, string tfsIdentityXml)
{
// Just some test output to see if it worked
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "tfs.txt");
File.WriteAllText(path, tfsIdentityXml + eventXml);
}
}
That's all been built and the ensuing .dll put into the bin dir in the site root in IIS.
I now want to subscribe via bissubscribe.exe (or a similar method) to TFS check-in events. I tried doing something like:
bissubscribe /eventType CheckinEvent
/address http://servername/MyService.svc
/deliveryType Soap
/server mytfsserver
But nothing; it doesn't even look like there was log activity. So keeping in mind I know nothing about WCF, what am I doing wrong? I imagine the address param is one thing; am I not supposed to point it to the .svc?
I have created a blog post how you can use WCF in combination with the Event Services of TFS: http://www.ewaldhofman.nl/post/2010/08/02/How-to-use-WCF-to-subscribe-to-the-TFS-2010-Event-Service-rolling-up-hours.aspx
TFS 2010 and WCF 4.0 configurations are described below...
Method signature:
public void Notify(string eventXml) /* No SubscriptionInfo! */
Web config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="Microsoft.TeamFoundation, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="NotificationServiceBehavior" name="TF.CheckinListener.CheckinListener">
<endpoint address="Notify" binding="wsHttpBinding" bindingConfiguration="noSecurity" contract="TF.CheckinListener.ICheckinListener" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="NotificationServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
</binding>
<wsHttpBinding>
<binding name="noSecurity" maxBufferPoolSize="20000000" maxReceivedMessageSize="200000000">
<readerQuotas maxStringContentLength="200000000" maxArrayLength="200000000" />
<security mode="None" />
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Subscription address for bissubscribe:
http://MachineName/VirtualDirectoryName/Service.svc/Notify
One point that jumps out is the fact you have a method that doesn't return anything except void. Those should be marked as "one-way" method in WCF:
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06Services/Notification/03")]
public interface IBar
{
[OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", ReplyAction = "*", IsOneWay=true)]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
void Notify(string eventXml, string tfsIdentityXml);
}
Add the "IsOneWay=true" to your [OperationContract] attribute.
Other than that, there's nothing obviously wrong in your code, but to really tell, we'd need a lot more config info to really tell. Try the IsOneWay=true first and see if that solves your issue.
How is your service configured? In particular, is it configured to use basicHttpBinding?
Try creating a client to call your service to make sure it can be called.
Then, see if there's an example service from the TFS SDK - see if you can get the example to work.
I was able to complete this connection with the following:
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface ITeamSystemObserver : IObservable
{
[OperationContract( Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", ReplyAction = "*" )]
[XmlSerializerFormat(Style=OperationFormatStyle.Document)]
void Notify(string eventXml, string tfsIdentityXml, SubscriptionInfo SubscriptionInfo);
}
Note you are missing the SubscriptionInfo parameter. Here is my web.config:
<basicHttpBinding>
<binding name="TfsEventServiceBasic">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>
</binding>
</basicHttpBinding>
* Readers Beware: massive code dump, not for the faint of heart... *
Hello,
I'm trying to figure out how to deploy a Silverlight 3 app to IIS7 with a WCF Service. I think i've got most of it figured out however I still get a cross domain error for some reason. I'm leaning toward thinking that the service is not finding the client access policy but I'm not sure how to confirm this. I get a very useless exception (simply says CrossDomainError). Inner Exception is nonexistant. Here are the steps I've taken to deploy the app. If anyone sees anything that doesn't add up can they please advise? I can't think of anything else to poke at right now...
In IIS manager I built a new site. I named it Silverlight, accepted a pool of the same name, and accepted all the rest of the defaults. I disabled the default site. I set the web root to be C:\WebApps
I placed all of the files from the release build of my Visual Studio Silverlight client project into the web root.
I place the following config files from the Silverlight client project in the web root: ServiceReferences.ClientConfig, Silverlight.js.
I placed the /bin directory from the release build of the Silverlight.Web project into the web root
I place the following files from the Silverlight.Web release build in the web root: crossdomain.xml, clientaccesspolicy.xml, Service1.svc, Service1.svc.cs, Web.config.
I renamed the TestPage.html file to index.html.
I realize that many of these are superfluous but I was running out of things to try so I started adding anything that looked like it might contain any useful metadata.
Here is the code to my various config files:
clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
crossdomain.xml:
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
system.serviceModel configuration, excerpted from Web.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SilverlightApplication2.Web.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="customBinding0">
<binaryMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="SilverlightApplication2.Web.Service1Behavior" name="SilverlightApplication2.Web.Service1">
<endpoint address="http://win-xqawq222tag:2721/Service1.svc" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
ServiceReferences.ClientConfig:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_Service1">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://win-xqawq222tag:2721/Service1.svc" binding="customBinding"
bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
name="CustomBinding_Service1" />
</client>
</system.serviceModel>
</configuration>
Service1.svc:
<%# ServiceHost Language="C#" Debug="true" Service="SilverlightApplication2.Web.Service1" CodeBehind="Service1.svc.cs" %>
Now for the implementation followed by the client code:
Service1.svc.cs:
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
namespace SilverlightApplication2.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
[OperationContract]
public DoWorkResult DoWork()
{
// Add your operation implementation here
int i = new Random().Next();
string s = "test string";
DoWorkResult r = new DoWorkResult() { String = s, Integer = i };
return r;
}
// Add more operations here and mark them with [OperationContract]
}
[DataContract]
public class DoWorkResult
{
[DataMember]
public string String { get; set; }
[DataMember]
public int Integer { get; set; }
}
}
MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
ServiceReference1.Service1Client proxy = new SilverlightApplication2.ServiceReference1.Service1Client();
proxy.DoWorkCompleted += new EventHandler<SilverlightApplication2.ServiceReference1.DoWorkCompletedEventArgs>(proxy_DoWorkCompleted);
proxy.OpenAsync();
proxy.DoWorkAsync();
proxy.CloseAsync();
}
void proxy_DoWorkCompleted(object sender, SilverlightApplication2.ServiceReference1.DoWorkCompletedEventArgs e)
{
if (e.Error == null)
{
String.Text = "Test String is: " + e.Result.String;
Integer.Text = "Random Int is: " + e.Result.Integer;
}
else
{
String.Text = e.Error.Message + e.Error.InnerException.Message + e.Error.StackTrace;
Integer.Text = e.Error.Message + e.Error.InnerException.Message + e.Error.StackTrace;
}
}
}
}
All of this works fine in VS 2008 on XP Pro. On IIS7 on Server2008 I am able to hit the default page, index.html, at http://localhost or at http://[myComputerName].
I am also able to hit the service at http://localhost/Service1.svc. I am not able to hit the service using http://[compNameHere]/Service1.svc. It complains with this error:
No protocol binding matches the given
address
'http://win-xqawq222tag:2721/Service1.svc'.
Protocol bindings are configured at
the Site level in IIS or WAS
configuration. Description: An
unhandled exception occurred during
the execution of the current web
request. Please review the stack trace
for more information about the error
and where it originated in the code.
Exception Details:
System.InvalidOperationException: No
protocol binding matches the given
address
'http://win-xqawq222tag:2721/Service1.svc'.
Protocol bindings are configured at
the Site level in IIS or WAS
configuration.
Source Error:
An unhandled exception was generated
during the execution of the current
web request. Information regarding the
origin and location of the exception
can be identified using the exception
stack trace below.
Stack Trace:
[InvalidOperationException: No
protocol binding matches the given
address
'http://win-xqawq222tag:2721/Service1.svc'.
Protocol bindings are configured at
the Site level in IIS or WAS
configuration.]
System.ServiceModel.Channels.TransportChannelListener.OnOpening()
+11513378 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan
timeout) +229
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan
timeout) +72
[InvalidOperationException: The
ChannelDispatcher at
'http://win-xqawq222tag:2721/Service1.svc'
with contract(s) '"Service1"' is
unable to open its IChannelListener.]
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan
timeout) +118
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan
timeout) +261
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan
timeout) +107
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan
timeout) +261
System.ServiceModel.HostingManager.ActivateService(String
normalizedVirtualPath) +121
System.ServiceModel.HostingManager.EnsureServiceAvailable(String
normalizedVirtualPath) +479
[ServiceActivationException: The
service '/Service1.svc' cannot be
activated due to an exception during
compilation. The exception message
is: The ChannelDispatcher at
'http://win-xqawq222tag:2721/Service1.svc'
with contract(s) '"Service1"' is
unable to open its IChannelListener..]
System.ServiceModel.AsyncResult.End(IAsyncResult
result) +11531006
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult
result) +194
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication
context, Boolean flowContext) +176
System.ServiceModel.Activation.HttpHandler.ProcessRequest(HttpContext
context) +23
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+181 System.Web.HttpApplication.ExecuteStep(IExecutionStep
step, Boolean& completedSynchronously)
+75
No protocol binding matches the given
address
'http://win-xqawq222tag:2721/Service1.svc'.
Protocol bindings are configured at
the Site level in IIS or WAS
configuration.
Further, I am able to hit the policy file at http://localhost/clientaccesspolicy.xml and http://[computerNameHere]/clientaccesspolicy.xml.
Is there something else I need to look at?
I freely admit I haven't exactely tried to reproduce you specific error, but I noticed something I too stubled over.
Colin Cole blogged that there was a subtle change in cap.xml format in regard to using SSL.
I didn't use SSL, but only when I changed
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
to
<allow-from http-request-headers="*">
<domain uri="http://*" />
<domain uri="https://*" /> <!-- if needed -->
</allow-from>
accessing the service worked.
I had to make the following change to the ServiceReferences.ClientConfig file and then publish again:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_Service1">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost/Service1.svc" binding="customBinding"
bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
name="CustomBinding_Service1" />
<!--<endpoint address="http://localhost:2721/Service1.svc" binding="customBinding"
bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
name="CustomBinding_Service1" />-->
</client>
</system.serviceModel>
</configuration>