Volání webových služeb   zodpovězená otázka

VB.NET

Dobrý den.

Opět jsem v koncích. Neumím to popsat jednoduše, takže se omlouvám za "elaborát"

Všude si čtu, jak primitivní je využívat webové služby a jak se k nim připojit, ale mně to prostě nejde. Ve Visual Studiu si připojím novou Web Referenci na dodavatele (dejme tomu pojmenujeme Abacus) do porjektu s jménem ObjednavkyZbozi, všechno proběhne jak má, před přidáním reference do projektu vidím v části okna prohlížeče opravdu defaultní stránku s popisem služeb:

**************START KOPIE*************

I6 Web Service

Allow connect to information system CyberSoft-I6 via Web Service

The following operations are supported. For a formal definition, please review the Service Description.

* GetResult

Return result specified by resultType argument - for details about resultType see page: ResultTypeInfo.ashx.

* GetResultByCode

Return result specified by resultType argument - for details about resultType see page: ResultTypeInfo.ashx. Result is filtered by code - string identifier of row.

* GetResultByFromTo

Return result specified by resultType argument - for details about resultType see page: ResultTypeInfo.ashx. Result is filtered by date - from/to.

* HelloWorld

Example method.

**************KONEC KOPIE****************

Jedna ze služeb, jak je zřejmé, by měla vracet "HelloWorld.

Dim abws As New ObjednavkyZbozi.Abacus.I6WebService

podle mně vytvoří objekt schopný přistupovat k té webové službě, nebo ne?

Dim VracenaHodnota As String = abws.HelloWorld

by snad mělo vrátit výsledek té služby, nebo ne?

Je pravda, že mi funguje následující, co jsem někde opsal a upravil na konkrétní typ služby a výsledku, ale chtěl jsem tak nějak proniknout víc k jednoduchosti pomocí těch WebReferences, když už ve Visual Studiu jsou, že :-):

Private Function ZjistiStavSkladuVI6(ByVal Kod As String, ByVal PristupUdaje As String, ByVal BaseServerSluzby As String) As Double
        Dim strUrl As String
        Dim Mnozstvi As String
        Dim xmlOdpoved As New Xml.XmlDocument
        Mnozstvi = "0"
        strUrl = "http://" & PristupUdaje & "@" & BaseServerSluzby & "/i6ws/default.asmx/GetResultByCode?resultType=StoItemQtyFree&code=" & Kod
        With CreateObject("MSXML2.XMLHTTP")
            .Open("GET", strUrl, False)
            .Send()
            If .Status <> 200 Then Err.Raise(vbObjectError + 1, "GetResponseXml", "Bad response status: [" & .Status & "] " & .StatusText & vbCrLf & .ResponseText)
            .ResponseXml.Save(strFile)
            Mnozstvi = .ResponseXml.SelectSingleNode("/Result/StoItem/@QtyFree").Value()

        End With
        ZjistiStavSkladuVI6 = Val(Mnozstvi)
    End Function

Tomuhle i jakžtakž rozumím (jsem amatér a něco jako "ještě ani ne začátečník :-) ), chápu, že mi to vrátí XML soubor:

<Result>

<StoItem Code="CPA X2 4800 B AM2 E2" QtyFree="18"/>

</Result>

, tak jsem si tam jen "šáhnul" pro hodnotu atributu QtyFree.

Poradí někdo efektivnější způsob?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Vyparsovávat XML je naprostý nesmysl, navíc ještě pomocí MSXML2.XMLHTTP.

Dim VracenaHodnota As String = abws.HelloWorld

by opravdu mělo vrátit výsledek. Nenapsal jste ale bohužel, co to vlastně udělá? Nevrátí nic, nebo vyhodí chybu? Nenapsal jste ani kód té metody Hello world, třeba nic nevrací. Zkuste ji zavolat z prohlížeče (do prohlížeče napište adresu té webové služby a doufejte, že to mají povolené, pokud ne, tak bohužel to nezkusíte).

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Dobrý den.

Díky za reakci, byl jsem celý den pryč, takže až nyní.

http://www.abacus.cz/i6ws/Default.asmx/H... vrací XML:

<string>Hello World</string>

I ostatní webové služby, které mají popsané na webu vracejí ty relevantní XMLka, to se nebojím, že by to měli oni špatně, třeba dotaz na množství zboží skladem vrátí:

<Result>

<StoItem Code="CPA X2 4800 B AM2 E2" QtyFree="7"/>

</Result>

Máte pravdu, že jsem zapoměl napsat, že po spuštění toho kódu:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim abws As New ObjednavkyZbozi.Abacus.I6WebService
        Dim vratise As String
        vratise = abws.HelloWorld
        MessageBox.Show(vratise)
    End Sub

mi to vyhodí chybovou zprávu:

WebException was unhandled

The request failed with HTTP status 401: Unauthorized

ale to mi nedává smysl, protože při zavádění webové reference do projektu se mně to na jméno i heslo zeptá, tak předpokládám, že si někde ve vygenerovaném kódu VB ty přihlašovací údaje uloží a je schopen při tom volání webové služby je správně předat.

Omlouvám se, chápu, že bych měl asi napřed nastudovat VB od začátku a ne se hned pokoušet o něco podobného, ale já potřebuji víceméně právě toto co nejrychleji a nemá smysl pro mně se zabývat dalšími aspekty .NET technologií, když nechci nic jiného, než pomocí webových služeb zjišťovat u distributorů dostupnost a cenu zboží a na základě toho nějak automatizovat systém objednávání zboží. Kdyby se toho někdo chtěl zhostit, , bylo by to asi pro mně nejjednodušší, bohužel nikoho takového ve svém okolí nemám a tak není koho požádat.

Zde přikládám detail chyby:

System.Net.WebException was unhandled
  Message="The request failed with HTTP status 401: Unauthorized."
  Source="System.Web.Services"
  StackTrace:
       at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
       at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
       at ObjednavkyZbozi.Abacus.I6WebService.HelloWorld() in C:\Documents and Settings\Petr\Dokumenty\Visual Studio 2005\Projects\ObjednavkyZbozi\ObjednavkyZbozi\Web References\Abacus\Reference.vb:line 95
       at ObjednavkyZbozi.Form1.Button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\Petr\Dokumenty\Visual Studio 2005\Projects\ObjednavkyZbozi\ObjednavkyZbozi\Form1.vb:line 135
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at ObjednavkyZbozi.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

no a tím už se vůbec neprokoušu. :-(

Pro jiné počítám tak na 30 hodin práce, pro mně "zábava po večerech na půl roku" :-)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pozor, jméno a heslo, které zadáte při přidávání webové služby do projektu, se neukládá a nepoužívá v aplikaci. Tuto aplikaci totiž dáváte širému světu, který ke službě třeba přístup mít nemá. Přihlášení tedy musíte provést při volání požadavku.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Poučné a možná i dostačující pro zkušenější. Díky.

Jdu zjišťovat, kterak to myslíte. Přihlášení musím provést při volání požadavku. Požadavek vyvolá ta aplikace (proto to také dělám, že, aby byl ten přístup ke službě automatizovaný) a aplikace si jméno a heslo nepamatuje... Trošku jsem se ztratil v tom, kdy teda je ten správný okamžik pro přihlášení a jak ho provést bez mé vlastní interakce... Ale to nějak pořeším. Snad.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak jsem se skoro nikam neposunul, jen jsem změnil chbové hlášení :-(

Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim abws As Objednavky.AbacusWS.I6WebServiceSoap = New Objednavky.AbacusWS.I6WebServiceSoapClient
        Dim vratise As String
        vratise = abws.GetResultByCode("StoItemQtyFree", "MYO").SelectSingleNode("/Result/Item/@QtyFree").Value
        MessageBox.Show(vratise)
    End Sub

Vyhodí chybu:

MessageSecurityException was unhandled

Požadavek protokolu HTTP je neoprávněný se schématem ověření klienta Anonymous. Zájlaví ověření přijaté ze serveru je Basic Realm=I6 Web Service on www.abacus.cz

Takže to už je opravdu někde mimo moje chápání. Na to, že potřebuju jen zjišťovat pomocí této webové služby stav skladu u výrobku jsem už tomu věnoval na můj vkus moc času :-(

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den.

Vím, že jdu sice s křížkem po funuse, resp. odpovím sám sobě po cca roce a půl, ale třeba se to někomu ze začátečníků hodí. Problém nahoře popisovaný byl způsoben opravdu pokusem o neautorizovaný přístup ke službě. Odpovědí na to je obecná třída webových služeb:

Public Class NetworkCredential
          Inherits System.Object
     Member of System.Net
Summary:
Provides credentials for password-based authentication schemes such as basic, digest, NTLM, and Kerberos authentication.

Takže funkční kód je takový, že se napřed musím nechat ověřit:


Dim ws As WS.WSluzba = New WS.WSluzba()
                
ws.Url = "http:\\www.bazovaadresasluzby.cz"
ws.Credentials = New Net.NetworkCredential("Login", "Heslo")

No a pak už mi to vesele vrací všechny ty soubory resp. XML nody, co jsem chtěl a popisoval. Samožřejmě za předpokladu, že ta webová služba/funkce je definovaná takto:

Public Function GetResultByCode(ByVal resultType As String, ByVal code As String) As System.Xml.XmlNode
            Dim results() As Object = Me.Invoke("GetResultByCode", New Object() {resultType, code})
            Return CType(results(0),System.Xml.XmlNode)
        End Function

Teď jsem však narazil na něco nového a jiného. Webová služba/funkce nevrací XNode, ale objekt typu Dataset:

Public Function Kategorie(ByVal strUzivatelskeJmeno As String, ByVal strUzivatelskeHeslo As String) As System.Data.DataSet
            Dim results() As Object = Me.Invoke("Kategorie", New Object() {strUzivatelskeJmeno, strUzivatelskeHeslo})
            Return CType(results(0),System.Data.DataSet)
        End Function

Tahle funkce je dělaná trochu jinak, tzn. že k ověřování dochází při volání. Ale to teď není důležité. Jde mi o to, jak do nějakého objektu z ní načíst ta data. Zkusil jsem:

Dim rdr As DataTableReader = ws.Kategorie("Login","Heslo").CreateDataReader()
Dim odpoved As DataSet = ws.Kategorie("Login","Heslo")
odpoved.Load(rdr,LoadOption.Upsert,?????????????? )

A tam právě nevím co zadat, protože nerozumím tomu, co po mě chce tahle přetížená metoda. Chce to nějaké parametrické pole popisující ten dataset a to jsem úplně mimo.

Neumím se na to vlastně ani pořádně zeptat, takže doufám, že jste to z toho zmatku pochopili.

Poradí někdo zkušený?

Děkuji.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

problem je v tom ,ze tema je oznacena ako vyriesena preto si toto uz sotva biekto precita skuste zalozit temu este raz ;)

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback