Web Service'de XML parametre nasıl gönderilir?
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
Web Service'de XML parametre nasıl gönderilir?
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?
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?
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
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
groups.google
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.
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.
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
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.
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.
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
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
DoBeforeExecute olayinda bu sekilde degistirip gonderiyorum ama sonuc yine hatali oluyor...
hata mesaji da su sekilde
Server was unable to read request. --> There is an error in XML document (9, . --> The XML declaration is unexpected. Line 9, position 29.
yukarida bahsettigin bilesenin adresi duruyor mu?
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>
Server was unable to read request. --> There is an error in XML document (9, . --> The XML declaration is unexpected. Line 9, position 29.
yukarida bahsettigin bilesenin adresi duruyor mu?
-
- Kıdemli Üye
- Mesajlar: 395
- Kayıt: 22 Tem 2004 09:15
- Konum: İzmir
- İletişim:
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.
<?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)
------------------------
"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)
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
o satiri ben elimle yaziyorum.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ş).
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>
Server was unable to read request. --> The data at the root level is invalid. hata mesaji geriye donuyor.
Sorunun karakter çevrimi olduğundan emin misin? Yarın sana yaptığım örneği gönderirim.sadettinpolat yazdı: Server was unable to read request. --> There is an error in XML document (9, . --> The XML declaration is unexpected. Line 9, position 29.
yukarida bahsettigin bilesenin adresi duruyor mu?
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ı?
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
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.
daha ilk bastan hatirladim ama biraz inat ettim delphi ile yapacam diyefduman yazdı: MS Web servisleri için MS yazılımları kullan sözümü hatırladın mı?
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:
parametreleri de önemliydi diye hatırlıyorum. Kusura bakma aklımda kalmamış burası.
Kolay gelsin.
Kod: Tümünü seç
HTTPWebNode.UseUTF8InHeader:= True;
Converter.Options:= Result.Converter.Options + [soUTF8InHeader, soUTF8EncodeXML];
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.
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim: