WCF ، Channelfactory ، "لا يمكن العثور على عنصر نقطة النهاية ..."
-
21-09-2019 - |
سؤال
أحاول الاتصال بخدمة WCF من داخل خدمة أخرى ، جزئيًا باستخدام مثال وجدته هنا على Stackoverflow الذي ينفذ Channelfactory.
لقد قمت بإنشاء مشروع تطبيق وحدة تحكم منفصل ضمن حولي للاختبار (VS 2008 ، راجع للشغل) ،
namespace MyService.Test
{
class Program
{
static void Main(string[] args)
{
MySolution.MyTestClient proxy = new MyTestClient();
proxy = new MyTestClient();
proxy.Endpoint.Address = new EndpointAddress("http://localhost:8723/MySolution/");
// Instantiate a request object and assign values to its member variables.
MySolution.RemoteServiceMethod() theObject = new RemoteServiceMethod();
theObject.SomeProperty = "123";
theObject.SomeOtherProperty = "alpha";
Console.WriteLine("Calling the remote service method now...");
try
{
proxy.SubmitRemoteServiceRequest(proxy.theObject);
}
catch (FaultException<MySolution.RequestException> e)
{
// exception code hereMySolution
}
}
}
}
هذا من الخدمة المحلية app.config إظهار نقطة النهاية:
<system.serviceModel>
<client>
<endpoint address="http://MyService/MyService.asmx"
binding="basicHttpBinding" bindingConfiguration="ServiceSoap"
contract="ServiceReference.ServiceSoap"
name="ServiceSoap" />
</client>
...
</system.serviceModel>
هذا من مشروع الاختبار الخاص app.config:
<client>
<endpoint address="http://localhost:8723/MyService"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceContract"
contract="ServiceContract.IServiceContract" name="BasicHttpBinding_IServiceContract" />
</client>
هذه هي الطريقة التي كشفتها في خدمتي المحلية ، والتي بدورها تمرر كائن طلب إلى الخدمة عن بُعد:
public ServiceContract.Response.ZZZ_Response SubmitRemoteServiceRequest(ServiceContract.Request.ZZZ_Request sc_TheirServiceRequest)
{
var factory = new ChannelFactory<ServiceReference.ServiceSoap>("ServiceSoap");
var wcfClient = factory.CreateChannel();
bool closedSuccessfully = false;
// Instantiate a response object which I will return to the consumer.
ServiceContract.Response.ZZZ_Response zzz_Response = new ServiceContract.Response.ZZZ_Response();
// Instantiate request and response objects, respectively, which I use internal to my service to call remote service.
ServiceReference.MyServiceRequest scMyServiceRequest = new ServiceReference.MyServiceRequest();
ServiceReference.MyServiceResponse scMyServiceResponse = new ServiceReference.MyServiceResponse();
try
{
// Now you can make calls on the wcfClient object
scMyServiceResponse = wcfClient.MyServiceMethod(scMyServiceRequest );
((ICommunicationObject)wcfClient).Close();
closedSuccessfully = true;
}
finally
{
if (!closedSuccessfully)
{
((ICommunicationObject)wcfClient).Abort();
}
}
return zzz_Response;
}
الخطأ الذي أتلقاه هو:
لا يمكن العثور على عنصر نقطة النهاية مع الاسمServicesOap"و عقد"servicereference.ServicesOapفي قسم تكوين عميل ServiceModel. قد يكون هذا لأنه لم يتم العثور على ملف تكوين للتطبيق الخاص بك ، أو لأنه لا يمكن العثور على عنصر نقطة نهاية هذا الاسم في عنصر العميل.
أنا في حيرة من أمري ، حيث أفتقد بالضبط عنصر نقطة النهاية ، في App.Config للخدمة المحلية (التي تحتوي على مرجع الخدمة الذي يشير إلى الخدمة عن بُعد) ، أو App.Config لتطبيق الاختبار ، أو في أي مكان آخر؟ !
تحديث: لقد وجدت حلًا من نوع ما بعد القراءة هذه المقالة MSDN, ، أو أعتقد مجرد طريقة مختلفة لتشكيل القنوات:
var factory = new ChannelFactory<ServiceReference.ServiceSoap>(new BasicHttpBinding(), "http://urlToRemoteService/RemoteService.asmx");
بدلاً من محاولة الاستيلاء على معلومات غير موجودة أو غير صحيحة في app.config ، أقوم بدلاً من ذلك بتوصيل القيم المتمثلة في الربط (basichttpbinding) ، والعنوان إلى الخدمة عن بُعد. يبدو أن هذا يجعلني تجاوز الخطأ "لم يستطع العثور على عنصر نقطة النهاية" ، لكنني لست متأكدًا مما إذا كان هذا هو الحل الأفضل.
المحلول
حسنًا ، في رمز تطبيق الاختبار الخاص بك ، تطلب عنصر نقطة النهاية باسم "ServicesOap":
var factory = new ChannelFactory<ServiceReference.ServiceSoap>("ServiceSoap");
ولكن في التكوين الخاص بك ، لا توجد نقطة نهاية من هذا القبيل:
<client>
<endpoint address="http://localhost:8723/DelinquencyService"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceContract"
contract="ServiceContract.IServiceContract" name="BasicHttpBinding_IServiceContract" />
</client>
يحتوي التكوين على عنصر نقطة النهاية باسم "basichttpbinding_iserviceContract" (المحدد بواسطة name=
ميزة على الخاص بك <endpoint>
العقدة).
لذلك إما يمكنك تغيير السطر في تطبيق الاختبار الخاص بك لطلب عنصر نقطة النهاية هذا:
var factory = new ChannelFactory<ServiceReference.ServiceSoap>("BasicHttpBinding_IServiceContract");
أو تقوم بتغيير app.config حتى يستخدم تطبيق الاختبار ServicesOap كاسم:
<client>
<endpoint name="ServiceSoap"
address="http://localhost:8723/DelinquencyService"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IServiceContract"
contract="ServiceContract.IServiceContract" />
</client>
يجب على أي من الاثنين حل مشكلتك.
في تطبيق العميل "العادي" الخاص بك ، يعمل هذا لأنه عند إنشاء وكيل العميل ، لا تحدد اسم عنصر نقطة النهاية على الإطلاق - سيستخدم WCF فقط العنصر الوحيد الموجود. إذا كان يجب أن يكون لديك أكثر من عنصر نقطة نهاية واحدة (على سبيل المثال باستخدام بروتوكولات مختلفة) ، فإن هذه المكالمة دون تحديد عنصر نقطة النهاية التي يجب استخدام ، جدا.