WCF – “Ajax-enabled WCF Service” ne peut pas avoir plusieurs bindings - “Cette collection contient déjà une adresse avec le schéma http.”
Afin de communiquer avec le serveur depuis le client en JavaScript, il est possible d’utiliser un “Ajax-enabled WCF Service”. Il s’agit d’un service WCF classique qui possède un binding et un behavior personnalisé afin de générer du JSON.
Si votre site web possède plusieurs binding il se peut que vous soyez face à ce problème.
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
ou en français
Cette collection contient déjà une adresse avec le schéma http. Une adresse tout au plus par schéma est possible dans cette collection.
Mais tout d’abord, quand est-ce que notre site web utilisera plusieurs bindings ? C’est le cas lorsque vous configurez un seul site web au niveau de IIS pour plusieurs urls. Par exemple si vous avez un site web accessible via
Ce problème est assez bien connu sur le net, il existe 2 bidouilles.
La première est de rajouter l’url dans le fichier de configuration :
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://www.mydomain.com"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
La seconde est de créer un ServiceHostFactory personnalisé
public class CustomHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return base.CreateServiceHost(serviceType, new Uri[]{ baseAddresses[0]});
}
}
<%@ ServiceHost Language="C#" Debug="true" Service="DataService"
CodeBehind="~/App_Code/DataService.cs" Factory="CustomHostFactory" %>
Malheureusement ces 2 bidouilles permettent de faire fonctionner le service seulement pour un domaine. Cela pose des soucis car à partir d’un appel AJAX il n’est pas possible de faire des requêtes crossdomain.
Afin de remonter le problème à Microsoft, j’ai recherché le bug sur connect : Feedback : Can't host WCF service in a website with multiple identities. Celui-ci est en état “Closed (By design)” ! Microsoft ne nous indique aucune piste afin de résoudre ce souci.
Ne me satisfaisant pas de cette solution, j’ai testé d’autres bidouilles. J’ai réussit à faire fonctionner le service avec plusieurs bindings en créant un ServiceHostFactory personalisé qui consiste à créer manuellement les ServiceEndpoint.
// use this class with caution !
// it's a workaround for this bug
// https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=322896
public class CustomHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
// a valid url is required
ServiceHost host = new ServiceHost(serviceType, new Uri[] { baseAddresses[0] });
// manually create endpoint for each uri - ignore WCF config file
for (int i = 0; i < baseAddresses.Length; i++)
{
WebHttpBinding webHttpBinding = new WebHttpBinding();
ServiceEndpoint endpoint = host.AddServiceEndpoint(serviceType,
webHttpBinding, baseAddresses
);
endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
}
return host;
}
}
Cette solution n’est pas idéale puisqu’elle ne prend pas en compte la configuration WCF stocké dans le fichier de configuration, cependant cela me permet de faire fonctionner mon service WCF sur 2 URLs distinct.
Si vous avez d’autres astuces ou informations à ce problème, je suis preneur.
N’oublier pas de voter pour ce bug si vous rencontrez ce soucis : Feedback : Can't host WCF service in a website with multiple identities