Web Service'de XML parametre nasıl gönderilir?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Web Service'de XML parametre nasıl gönderilir?

Mesaj gönderen fduman »

Bir XML Web Service sunucuna, istemci taraftan bir XML'i parametre geçmem gerekiyor. Ancak parametreden geçtiğim XML Delphi'nin SOAP bileşeni tarafından karşıya, < karakterleri < ve > karakterleri de > olarak gönderiliyor. Hal böyle olunca karşıdaki Web service sunucu bunu kabul etmiyor. (@sadettinpolat sanki böyle birşeyden bahsetmiştin. Evet XML içinde bu karakterleri bu şekilde replace etmesi mantıklı, ancak her zaman değil gördüğün gibi. :) )

HTTPRIO bileşeninin BeforeExecute'unda bunları Replace ederim diye düşünmüştüm. Ancak Replace'e rağmen değişmeden gönderildiğini gördüm. Bunun üzerine VCL kodlarına daldım ve DoBeforeExecute'da Borland programcısının, "değer değişmişse biz gene de bunu uygulamayalım??" gibi bir açıklama yazdığını farkettim. Hakikaten benim değiştirdiğim, < 'leri < olarak replace ettiğim SOAPRequest parametresini işleme sokmuyordu. Niye böyle birşey yapmışlar anlam veremedim. Nette yaptığım araştırmada bunu düzeltecek yamalar verilmiş.

Ancak benim sormak istediğim, böyle bir Replace veya yamaya gerek kalmadan XML'i olduğu gibi (karakterleri değişmeden) parametrede iletmek mümkün müdür? Parametre WideString olarak tanımlı. Array of char yaptığımda MIME kodlamasına sokuyor ve gene işime yaramıyor.

Delphi SOAP bileşenlerine "bu XML'i işlemeden gönder" nasıl derim ki?
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

hali hazırda boyle bir secenek yok galiba. Yamaya gerek kalmayacak sekilde en agrisiz yontem THTTPRIO sınıfından yeni bir sınıf tureterek OnBeforeExecute olayını ezmek gorunuyor.

groups.google
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Haklısın. Yamada da aynı yöntemi uygulamışlar. Kaynak kodu bozmaya gerek yok. Sağolasın. :)
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

SOAP ve benzeri protokollerle uğraşanlar için, arada bilginin nasıl gidip geldiğini bilmek çoğu zaman hayat kurtarıcı oluyor.

http://www.4s4c.com/tcptrace/pt.aspx adresindeki yazılım bir proxy gibi çalışıyor. İzlemek istediğiniz protocol için (mesela SOAP) HTTPRIO bileşeninin Proxy bölümüne "localhost:8080" yazdığınızda, gidip gelen bilgiyi bu program gösterebiliyor. Proxy desteği olan Indy bileşenlerinde de kullanabilirsiniz.
En son fduman tarafından 08 Eyl 2005 08:09 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

coderlord yazdı:arada bilginin nasıl gidip geldiğini bilmek çoğu zaman hayat kurtarıcı oluyor.
sorun cozuldu mu yani?
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Haklısın yazmadım. :)

Sorun şöyle çözüldü. HTTPRIO bileşenini türettim. Türettiğim bileşende DoBeforeExecute method unu override ettim ve bileşene bir event daha ekledim. DoBeforeExecute'tan yeni eventi çağırdım. Böylece gönderilen Stream üzerinde istediğim değişikliği yapabildim. < ve > leri replace ettim. Yarın bileşeni yollarım. Sonra bir baktım nette biri daha aynı benim gibi yapmış. Gene boşa uğraştık yani. :)
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

delphi 2006 ile xml formatinda parametre isteyen bir web servisine rio bilesenin ilgili ozelligini ezerek < ve > karakterlerini tekrar normal işaretlerle değiştirip gonderiyorum ama yinede hata almaktan kurtulamadim.

orjinal hali bu

Kod: Tümünü seç

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Body>
    <RequestSalesConditions xmlns="http://tempuri.org/">
      <CustomerCode>1000000</CustomerCode>
      <UserName>xxxx</UserName>
      <Password>yyyy</Password>
      <warehouseCode>99</warehouseCode>
      <reqSalesConditions><?xml version="1.0" encoding="utf-8"?>
<reqsalesconditions>
	<reqsalesconditionitem>
		<companyproductid>
       8783
     </companyproductid>
		<quantity>
       1
     </quantity>
	</reqsalesconditionitem>
</reqsalesconditions>
</reqSalesConditions>
    </RequestSalesConditions>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

DoBeforeExecute olayinda bu sekilde degistirip gonderiyorum ama sonuc yine hatali oluyor...

Kod: Tümünü seç

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Body>
    <RequestSalesConditions xmlns="http://tempuri.org/">
      <CustomerCode>1000000</CustomerCode>
      <UserName>xxxx</UserName>
      <Password>yyyyy</Password>
      <warehouseCode>99</warehouseCode>
      <reqSalesConditions><?xml version="1.0" encoding="utf-8"?>
<reqsalesconditions>
	<reqsalesconditionitem>
		<companyproductid>
       8783
     </companyproductid>
		<quantity>
       1
     </quantity>
	</reqsalesconditionitem>
</reqsalesconditions>
</reqSalesConditions>
    </RequestSalesConditions>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

hata mesaji da su sekilde

Server was unable to read request. --> There is an error in XML document (9, 8). --> The XML declaration is unexpected. Line 9, position 29.

yukarida bahsettigin bilesenin adresi duruyor mu?
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
doganzorlu
Kıdemli Üye
Mesajlar: 395
Kayıt: 22 Tem 2004 09:15
Konum: İzmir
İletişim:

Mesaj gönderen doganzorlu »

Selam,

<?xml version="1.0" encoding="utf-8"?>

şeklinde araya giren o tag nereden geliyor ki ? Buna kızıyor. Normalde xml attribute bilgileri ilk tag olarak verilir (ki zaten en üstte verilmiş).

Arada bunu üreten başka birşey var ve bu muhtemelen sizin yazdığınız bölümde tetkilediğiniz birşeyden dolayı geliyor buraya.
Doğan Zorlu, İzmir

------------------------
"Bu Kitap'ı sana yalnız şunun için indirdik: Hakkında ayrılığa düştükleri şeyi onlara iyice açıklayasın ve Kitap, iman eden bir topluluk için kılavuz ve rahmet olsun." (NAHL 64)
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

doganzorlu yazdı: <?xml version="1.0" encoding="utf-8"?>

şeklinde araya giren o tag nereden geliyor ki ? Buna kızıyor. Normalde xml attribute bilgileri ilk tag olarak verilir (ki zaten en üstte verilmiş).
o satiri ben elimle yaziyorum.

ilgili web servisinin ilgili parametrelerinden bi tanesi xml formatinda veri istiyor. bende asagidaki sekilde xml i hazirlayip parametre olarak geciyorum.

Kod: Tümünü seç

<?xml version="1.0" encoding="utf-8"?>
<reqSalesConditions>
  <reqSalesConditionItem>
     <companyProductId>
       8783
     </companyProductId>
     <quantity>
       1
     </quantity>
  </reqSalesConditionItem>
</reqSalesConditions>
eger <?xml version="1.0" encoding="utf-8"?> satirini kaldirirsam

Server was unable to read request. --> The data at the root level is invalid. hata mesaji geriye donuyor.
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

sadettinpolat yazdı: Server was unable to read request. --> There is an error in XML document (9, 8). --> The XML declaration is unexpected. Line 9, position 29.

yukarida bahsettigin bilesenin adresi duruyor mu?
Sorunun karakter çevrimi olduğundan emin misin? Yarın sana yaptığım örneği gönderirim.

Bu arada bir de C# tan göndermeye çalışsana. ;) MS Web servisleri için MS yazılımları kullan sözümü hatırladın mı? :D
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

fduman yazdı: Sorunun karakter çevrimi olduğundan emin misin? Yarın sana yaptığım örneği gönderirim.

Bu arada bir de C# tan göndermeye çalışsana. ;)


c# ile ayni parametrelerle bi problem olmadan kullanabiliyorum.
fduman yazdı: MS Web servisleri için MS yazılımları kullan sözümü hatırladın mı? :D
daha ilk bastan hatirladim ama biraz inat ettim delphi ile yapacam diye :)
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

XML'i gönderdiğim RIO bileşenini içererek oluşturduğum sınıf. Bu sınıf sayesinde, parametre olarak geçtiğim XML dosyasındaki özel işaretler dönüştürülmüyor. İstersen uyarlayabilirsin. Önemli method BeforeExecuteStream. Bütün iş burada yapılıyor. Ancak RIO 'ya geçtiğim:

Kod: Tümünü seç

HTTPWebNode.UseUTF8InHeader:= True;
Converter.Options:= Result.Converter.Options + [soUTF8InHeader, soUTF8EncodeXML];
parametreleri de önemliydi diye hatırlıyorum. Kusura bakma aklımda kalmamış burası.

Kolay gelsin.

Kod: Tümünü seç

unit RIOTool;

interface

uses Classes, SoapHTTPClient;

type
  TSharepointService = (spsLists, spsDws, spsMeetings);

  // Sharepoint web servisi için RIO oluşturur.
  TSharepointRIOService = class(TObject)
  private
    FRIO: THTTPRIO;
    procedure BeforeExecuteStream(const MethodName: string; Request: TStream);
    function CreateRIO(const WSDLLocation: string;
      SharepointService: TSharepointService): THTTPRIO;
  public
    constructor Create(const WSDLLocation: string;
      SharepointService: TSharepointService);
    property RIO: THTTPRIO read FRIO;
    destructor Destroy; override;
  end;

implementation

uses SysUtils, CL_HTTPRIO, OpConvert;

{ TRIOService }

constructor TSharepointRIOService.Create(const WSDLLocation: string;
  SharepointService: TSharepointService);
begin
  FRIO:= CreateRIO(WSDLLocation, SharepointService);
end;

destructor TSharepointRIOService.Destroy;
begin
  FRIO:= nil;
  inherited Destroy;
end;

// Inline XML verisinin değişmemesini sağlıyoruz.
procedure TSharepointRIOService.BeforeExecuteStream(const MethodName: string;
  Request: TStream);
var
  StrStream: TStringStream;
  St: string;
begin
  StrStream:= TStringStream.Create('');
  try
    Request.Position:= 0;
    StrStream.CopyFrom(Request, Request.Size);
    St:= StringReplace(StrStream.DataString, '<', '<', [rfReplaceAll]);
    St:= StringReplace(St, '>', '>', [rfReplaceAll]);
  finally
    StrStream.Free;
  end;

  Request.Size:= 0;

  StrStream:= TStringStream.Create(St);
  try
    StrStream.Position:= 0;
    Request.Position:= 0;
    Request.CopyFrom(StrStream, StrStream.Size);
  finally
    StrStream.Free;
  end;
end;

function TSharepointRIOService.CreateRIO(const WSDLLocation: string;
  SharepointService: TSharepointService): THTTPRIO;
begin
  Result:= TCL_HTTPRIO.Create(nil);
  with Result do
  begin
    HTTPWebNode.UseUTF8InHeader:= True;
    Converter.Options:= Result.Converter.Options + [soUTF8InHeader, soUTF8EncodeXML];
{$IFDEF SOAPDEBUG}
    // Proxy trace ile debug ederken.
    HTTPWebNode.Proxy:= 'localhost:8080';
    HTTPWebNode.UserName:= 'xxxxx';
    HTTPWebNode.Password:= 'xxxxx';
{$ENDIF}
    // RIO URL yi ayarla
    WSDLLocation:= WSDLLocation;
    case SharepointService of
      spsLists:   begin
                    Service:= 'Lists';
                    Port:= 'ListsSoap';
                  end;
      spsDws:     begin
                    Service:= 'Dws';
                    Port:= 'DwsSoap';
                  end;
      spsMeetings:begin
                    Service:= 'Meetings';
                    Port:= 'MeetingsSoap';
                  end;
    end;
    TCL_HTTPRIO(Result).OnBeforeExecuteStream:= BeforeExecuteStream;
  end;
end;

end.
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

< > taglarinda bi problem yok ama gonderdigi paketin sonunda bazi taglari fazladan koyuyor bu melet. proxytrace ile bakinca net bir sekilde gorunuyor.

CL_HTTPRIO.pas dosyasinda ne var bu arada ?
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

İşyerinde kaldı şansına küs. :) HTTPRIO bileşeninin biraz değiştirilmişiydi sanırım. Çok fazla bir numarası yoktu. ;)
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

c# ile yaptigim ornegin gonderdigi veriyi soap tolkit ile aldim ve ayni xml yapisini gectim yine nafile. simdilik vazgectim bende :evil:
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
Cevapla