Blog Listem

10 Şubat 2015 Salı

C# - TC kimlik sorgulama web servisi client örneğinden COM uyumlu DLL oluşturma ve bunu App.Config dosyası olmadan kullanabilme

Bir makaleden öğrendiğim aşağıdaki direktifle DLL dosyanızın COM uyumlu olmasını sağlarsınız:


[ComVisible(true)] 

Ayrıca projenin özelliklerinde build sekmesinde Register for COM interop checkboxı işaretli olmalı.

Bunun sayesinde de COM nesnesini kullanırken Intellisense kullanabilirsiniz:

[ClassInterface(ClassInterfaceType.AutoDual)] 

 Tüm bunları yaptıktan sonra yine de bu DLL dosyasını direk kullanamazsınız. Kullanmaya kalktığınızda "OLE IDispatch exception code 0 from System.ServiceModel: ServiceModel..." gibi bir hata alırsınız. Ya app.config dosyasını EXEDosyaAdı.EXE.App.Config olarak çağıran programın olduğu klasöre kopyalayacaksınız ya da aşağıdaki kod parçasındaki kırmızı işaretli yerleri ekleyeceksiniz (Bunun için de Paul Mrozowski'den yardım aldım):

Örnekteki TC kimlik servisini C# Class Library türünde oluşturulan projenize eklemek için Service References üzerinde sağ mouse, Add Service Reference-> adres https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx ve GO yapmalısınız.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.ServiceModel;



namespace TCKimlik
{
    [ComVisible(true)] //COM nesnesi olarak görülebilmesini sağlar
    [ClassInterface(ClassInterfaceType.AutoDual)] //COM nesnesi olarak kullanırken intellisense sağlar
    [ProgId("TCKimlik.TCSorgula")] //COM nesne adı
   
    public class TCKimlikClass
    {
        public bool Dogrula(string adi,string soyadi,Int64 tc,Int32 dogumT)
        {
            bool ret = false;

            //------ APP.CONFIG dosyası gerekmemesi için.
            BasicHttpsBinding binding = new BasicHttpsBinding();
            EndpointAddress address = new EndpointAddress("https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx");

            //------ Sorgula --------
                try
            {
                Sorgula.KPSPublicSoapClient servis = new Sorgula.KPSPublicSoapClient(binding, address);

                ret = servis.TCKimlikNoDogrula(tc, adi, soyadi, dogumT);
            }
            catch
            {
            }
            return ret;
        }
    }
}


Artık bu DLL sadece .NET değil, klasik COM DLL destekleyen dillerle de kullanılabilir. Ancak bu DLL dosyasını setup olmadan taşırsanız hedef bilgisayarda regasm ile kaydetmeniz gerekir. Projenin tamamını hazır DLL ile bu ekte paylaştım.

Aşağıdaki örnekte Microsoft Visual Foxpro ile kullanımı var:

o=CREATEOBJECT("tckimlik.tcsorgula")
?o.Dogrula("METİN","EMRE",11111111111,1980)

Güncelleme:
Bazen .DLL dosyasını register ettikten sonra kullanırken "80131509 unknown com status code" hatası alabilirsiniz. Bunun için DLL'yi strong name ile imzalamanız gerekiyor.
Önce Visual Studio içinde zaten var olan SN.EXE ile bir key dosyası oluşturuyoruz:

 sn -k MyKeyFile.snk

Sonra da Visual Studio->İmzalama->Bütünleştirilmiş kodu imzala checkbox'unu seçtikten sonra MyKeyFile.snk dosyasını seçip derleme yapıyoruz.

6 yorum:

  1. Çalışmadı:

    1) Bir hata aldım. Bunu yazacağım.
    2) "Service References üzerinde sağ mouse, Add Service Reference-> adrese https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx ve GO yap" sırasında şu hatayı veriyor:

    Metadata contains a reference that cannot be resolved: 'http://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx?wsdl'.
    The document format is not recognized (the content type is 'text/html').
    Metadata contains a reference that cannot be resolved: 'https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx'.
    Metadata contains a reference that cannot be resolved: 'https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx'.
    If the service is defined in the current solution, try building the solution and adding the service reference again.

    Bu aşamada Namespace olarak, varsayılan olarak, ServiceReference1 getiriliyor. Aduzayı adı olarak, ServiceReference1'i de olduğu gibi mi bırakacağız?

    YanıtlaSil
  2. 1) de şunu yazacaktım: Aldığım hata:

    "A Project with an Output Type of Class Library cannot be started directly.

    In order to debug this project, add an executable project to this solution which references the library project. Set the executable project as the startup project."

    Projeye sağ tıkla, "Set as startup project" yaptım, ama yine çalışmadı. Şu hata var:
    Error 1 Cannot register assembly "D:\Belgelerim\TC Kimlik Kartı - Soyağacı\Yazılım\TCKimlik\TCKimlik\bin\Debug\TCKimlik.dll" - access denied. Please make sure you're running the application as administrator. Access to the registry key 'HKEY_CLASSES_ROOT\TCKimlik.TCSorgula' is denied. TCKimlik

    Uygulamayı Yönetici olarak nasıl çalıştıracağım? Sanki, böyle de bir sorun var gibi.

    YanıtlaSil
  3. Geldiğim Nokta:
    1) "Add Service Reference" hikayesinde; namespace'e tckimlik yazıp adrese de https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx?wsdl yazınca sorun çıkmadı. Servisi ekledi.
    2) Visual Studio'nun .exe'sini sağtıkla "Run as Administrator" yapınca, Yönetici olarak çalıştırma hikayesini de çözdüm.

    Bu sefer de, Solution'ı build edince şu hata çıktı:
    Error 1 The type or namespace name 'Sorgula' could not be found (are you missing a using directive or an assembly reference?) D:\Belgelerim\TC Kimlik Kartı - Soyağacı\Yazılım\TCKimlik\TCKimlik\TCKimlikClass.cs 30 17 TCKimlik

    YanıtlaSil
  4. "Sorgula"nın, Service References kısmında, aduzayına vermiş olduğun ad olduğunu düşünüyorum. Ben de aduzayına Sorgula adını verince, Build Project ve Build Solution yapınca ikisinde de hiçbir hata çıkmadı. Geriye sadece:

    "A Project with an Output Type of Class Library cannot be started directly.
    In order to debug this project, add an executable project to this solution which references the library project. Set the executable project as the startup project."

    hatası kaldı. TCKimlik'i Startup Project yapmama rağmen bu hatayı alıyorum.

    TCKimlik projesinin Output Type'ını "Console Application" yapıp, yeşil Start okuna basınca:
    "Error 1 Program 'd:\Belgelerim\TC Kimlik Kartı - Soyağacı\Yazılım\TCKimlik\TCKimlik\obj\Debug\TCKimlik.exe' does not contain a static 'Main' method suitable for an entry point D:\Belgelerim\TC Kimlik Kartı - Soyağacı\Yazılım\TCKimlik\TCKimlik\CSC TCKimlik"

    hatası alıyorum.
    Yukarıda vermiş olduğun kodu, birebir aynen hiç değiştirmeden yazdım. Kendimden hiçbir şey de eklemedim.

    YanıtlaSil
    Yanıtlar
    1. Merhaba,

      Şimdi baktım da mesajını tam olarak okumadığımı anladım. Bu proje direk çalışmaz. Win32 derleme yapan dillerden çağırılabilien bir COM DLL oluşturur.

      Sil
  5. Merhaba,

    İşin doğrusu fazla basit olduğunu düşündüğümden projeyi paylaşmamıştım. Malesef projeyi bir türlü bulamadım. Sanırım diskim göçtüğünde yedeklerim arasında bu yoktu. Boş bir vaktimde projeyi tekrar oluşturup paylaşmaya çalışacağım.
    Ancak son aldığın hatanın sebebi direk bunu bir exe olarak kullanmaya çalışman. Bu dosyayı .dll yapıp başka bir proje içinden kullanmalısın. Bu örneği yapmamdaki asıl amaç TC kimlik servisini örnekledirmek değildi zira böyle tonla örnek var internette. Asıl amacım direk .NET DLLlerini kullanamayan VFP, Delphi vs.. COM tabanlı DLL kullanabilen dillerden .NET DLL kullanabilme yolunu göstermekti. Bu örnekteki yol sayesinde .NET DLLleri sadece COM tabanlı DLL destekleyen dillerden kolaylıkla kullanılabiliyor.

    YanıtlaSil