بررسی مشکل معروف استفاده از بیش از یک آدرس پایه برای یک اسکیما در WCF
  در این مقاله به معرفی یکی از مشکلات شایعی که معمولا هنگام استفاده از سرویس WCF در محیط وب به وجود می آید، می پردازیم
   WCF
   ۴۷۶۳
   این مقاله حاوی فایل ضمیمه نمی باشد
   مرتضی صحراگرد
   ۱۳۸۹/۴/۳۰
ارسال لینک صفحه برای دوستان ارسال لینک صفحه برای دوستان  اضافه کردن به علاقه مندیها اضافه کردن به علاقه مندیها   نسخه قابل چاپ نسخه قابل چاپ

 

یکی از نکات مهم و البته نا آشنای تکنولوژی WCF این است که از فقط از یک آدرس پایه (base address) می توان برای یک اسکیما (یا یک پرتکل مانند http یا net.tcp و غیره) استفاده نمود.

برای درک بهتر مسئله بهتر است که از یک مثال استفاده کنیم.

محتوای فایل کانفیگ یک سرویس به طور کلی مشابه زیر می باشد (البته به شرطی که پیکربندی از طریق کد انجام نشده باشد).

<system.serviceModel>
 
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
 
    <services>
        <service behaviorConfiguration="MyServiceBehavior" name="MyService">
            <endpoint address="" binding="wsHttpBinding" contract="IMyService"></endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
 
</system.serviceModel>

احتمالا هنگام کار با این سرویس در رایانه شخصی خود با مشکل خاصی مواجه نخواهید شد. ولی اگر این سرویس را بر روی سرور سایت خود آپلود کنید، ممکن است با خطای زیر مواجه شوید.

This collection already contains an address with scheme http. There can be at most one address per
scheme in this collection.
Parameter name: item
 

همانطور که از متن خطا نیز مشخص می باشد و در ابتدای مقاله هم ذکر گردیده، دلیل این مشکل استفاده از بیش از یک آدرس پایه برای یک اسکیما (در اینجا http) می باشد. با توجه به اینکه این سرویس در وب سایت با استفاده از دو آدرس پایه زیر قابلیت دسترسی را دارد، خطای مورد نظر به وجود آمده است.

  1. http://MySite.com
  2. http://www.MySite.com

برای حل این مشکل هم می توان از طریق برنامه نویسی و در کد اقدام نمود (که مورد بحث این مقاله نمی باشد) و هم از طریق فایل کانفیگ.

ابتدا باید تصمیم بگیریم که قصد داریم سرویس را از طریق کدام یک از آدرس ها در دسترس قرار دهیم. سپس آدرس را به شکل یک آدرس پایه در داخل تگ فایل کانفیگ به شکل زیر قرار می دهیم.

<system.serviceModel>
 
    <serviceHostingEnvironment>
        <baseAddressPrefixFilters>
            <add prefix="http://MySite.com:80"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
 
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
 
    <services>
        <service behaviorConfiguration="MyServiceBehavior" name="MyService">
            <endpoint address="" binding="wsHttpBinding" contract="IMyService"></endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
 
</system.serviceModel>

در قطعه کد بالا ما آدرس پایه مورد نظر خود را داخل تگ baseAddressPrefixFilters قرار داده ایم و مشخص نموده ایم که سرویس فقط از طریق آدرس پایه http://MySite.com (البته در صورت استفاده از پرتکل http)در دسترس می باشد و اگر سعی کنید از طریق آدرس پایه http://www.MySite.com به سرویس دسترسی پیدا کنید، با خطا مواجه خواهید شد.