Ketika WCF service di-host di IIS website yang mana terdapat multiple identities yang dapat merespon dari URL dan port yang berlainan, WCF service tersebut ketika dipanggil akan menghasilkan error sebagai berikut:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
Parameter name: item
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.ArgumentException: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
Parameter name: item
Saya tahu bahwa ini adalah behavior yang memang didesain oleh Microsoft dan ada solusi untuk masalah ini. Akan tetapi setelah googling di beberapa forum, MSDN dan beberapa blog, saya tidak mendapatkan solusi yang tepat. Saya hanya mendapatkan solusi untuk mengambil URL pertama dari daftar alamat alias yang ada. Ini bukan solusi yang tepat bagi saya karena semua WCF service harus dapat diakses dari semua alamat alias. Terima kasih kepada Zeddy yang telah membatu dalam memecahkan masalah ini. Masalah ini dapat diatasi dengan membuat custom ServiceHostFactory yang menghapus semua baseAddresses lalu override Behaviors dan ServiceEndPoint sebagaimana saya uraikan dalam langkah-langkah di bawah. Saya gunakan contoh WCF service dengan name MyService yang diimplementasikan dari IMyService.
Buat Custom ServiceHostFactory
Buat class baru untuk custom ServiceHostFactory berikut.
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Linq;
using System.ServiceModel.Description;
public class MultipleIISBindingSupportServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var host = base.CreateServiceHost(serviceType, new Uri[] {/*empty*/ });
// Setup MEX dynamically
var behavior = new ServiceMetadataBehavior
{
HttpGetEnabled = true,
HttpGetUrl = baseAddresses.Where(addr => addr.Scheme == "http").First()
};
host.Description.Behaviors.Add(behavior);
// Setup Endpoint dynamically
foreach (var uri in baseAddresses)
{
// Service endpoint support http scheme only, exclude https scheme
if (uri.Scheme == "http")
{
host.AddServiceEndpoint(typeof (IMyService),
new BasicHttpBinding(BasicHttpSecurityMode.None),
uri
);
}
}
return host;
}
}
Ubah Markup WCF Service
Untuk mengubah markup WCF Service, klik kanan pada file MyService.svc lalu klik "View Markup".
<%@ ServiceHost Language="C#" Debug="true"
Service="MyService"
CodeBehind="MyService.svc.cs"
Factory="MultipleIISBindingSupportServiceHostFactory" %>
Ubah Web.config File
Buka file web.config, pada element <system.serviceModel>, ganti element <system.serviceModel> dan semua child elements dengan configurasi berikut.
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true"/>
</diagnostics>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Setelah semua langkah dilakukan, seharusnya masalah multiple identities dapat teratasi.
Semoga tips in bermanfaat. Versi Bahasa Inggris tulisan ini dapat dilihat di sini.