Avatar billede jackass- Nybegynder
23. marts 2012 - 13:33 Der er 20 kommentarer

Returnér database output fra webservice

Hej,

Hvad er den bedste måde at returnere DB data via en webservice via odbc? Og hvordan gør man?

Jeg bruger i øjeblikket følgende i en applikation, men hvordan returnerer man et helt output via en webservice?


OdbcConnection Conn = new System.Data.Odbc.OdbcConnection("DSN=<clip>;UID=<clip>;PWD=<clip>;");
OdbcCommand catCMD = new OdbcCommand("SELECT * FROM Table", Conn);
Conn.Open();
OdbcDataReader myReader = catCMD.ExecuteReader();
               
while (myReader.Read())
{
    // do stuff
}

myReader.Close();
Conn.Close();


Pft.
Avatar billede arne_v Ekspert
23. marts 2012 - 14:04 #1
Laes data ind i et X[] hvor X er en data klasse med properties og returner dette array.
Avatar billede arne_v Ekspert
23. marts 2012 - 14:05 #2
Eksempel (med gammeldags .asmx web service og uden brug af generics):

using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Web.Services;

namespace E
{
    [Serializable]
    public class Rec
    {
        private int f1;
        private string f2;
        public Rec() : this(0, "")
        {
        }
        public Rec(int f1, string f2)
        {
            this.f1 = f1;
            this.f2 = f2;
        }
        public int F1
        {
            get
            {
                return f1;
            }
            set
            {
                f1 = value;
            }
        }
        public string F2
        {
            get
            {
                return f2;
            }
            set
            {
                f2 = value;
            }
        }
    }

    public class DataGateway
    {
        [WebMethod]
        public Rec[] GetAll()
        {
            SqlConnection con = new SqlConnection("server=ARNEPC3;Integrated Security=SSPI;database=Test");
            con.Open();
            SqlCommand cmd = new SqlCommand("SELECT F1,F2 FROM T1", con);
            ArrayList list = new ArrayList();
            SqlDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                list.Add(new Rec((int)rdr[0], (string)rdr[1]));
            }
            rdr.Close();
            con.Close();
            Rec[] res = (Rec[])list.ToArray(typeof(Rec));
            return res;
        }
    }
}
Avatar billede jackass- Nybegynder
28. marts 2012 - 10:50 #3
Tak for eksemplet arne_v ... nu spørger jeg måske dumt, men hvordan behandler jeg det resultat af typen Rec[]?

Kan ikke få det til at spille :-/
Avatar billede arne_v Ekspert
28. marts 2012 - 15:01 #4
Hvad er web service client?


C#? VB.NET? Java? PHP? JavaScript?
Avatar billede jackass- Nybegynder
28. marts 2012 - 15:41 #5
Både klient og webservice er C#
Avatar billede arne_v Ekspert
28. marts 2012 - 16:05 #6
Saa adder du en web service til dit client projekt - den spoerger om URL paa WSDL og saa faar du en stub genereret som du bare kan kalde ligesom lokal kode.
Avatar billede jackass- Nybegynder
29. marts 2012 - 07:42 #7
Jo, men det jeg mener er; webservicen returnerer jo result af typen Rec[] iht. "Rec[] res = (Rec[])list.ToArray(typeof(Rec));".

Hvis jeg kalder den fra min C# klient med:

myservice.Service1 tw = myservice.Service1();
res = (Rec[])tw.GetJobs();

Får jeg denne compile fejl:

Cannot convert type 'App.myservice.Rec[]' to 'App.Rec[]'
Avatar billede jackass- Nybegynder
29. marts 2012 - 12:59 #8
Eller hvordan returnerer og læser jeg det som XML? Det er vel måske det mest optimale for en webservice?
Avatar billede jackass- Nybegynder
29. marts 2012 - 13:56 #9
Jeg har forsøgt med dette:

OdbcConnection Conn = new System.Data.Odbc.OdbcConnection(connectionstring);
OdbcCommand catCMD = new OdbcCommand("SELECT PATH FROM Table1", Conn);
Conn.Open();
OdbcDataReader myReader = catCMD.ExecuteReader();

XmlDocument doc = new XmlDocument();
XmlNode root = doc.CreateElement("all");
doc.AppendChild(root);

while (myReader.Read())
{
    XmlNode elm = doc.CreateElement("PATH");
    elm.AppendChild(doc.CreateTextNode(Convert.ToString(myReader[0])));
    root.AppendChild(elm);
}

doc.InsertBefore(doc.CreateXmlDeclaration("1.0", "ISO-8859-1", null), doc.DocumentElement);

myReader.Close();
Conn.Close();

return doc;

.................

Men får denne fejl i IE:

The XML page cannot be displayed
Cannot view XML input using style sheet. Please correct the error and then click the Refresh button, or try again later.


--------------------------------------------------------------------------------

System does not support the specified encoding. Error processing resource 'http://toolboxweb/ToolboxWeb.asmx/GetDeleteJobs'...

<?xml version="1.0" encoding="utf-8"?>
Avatar billede arne_v Ekspert
29. marts 2012 - 15:13 #10
myservice.Service1 tw = myservice.Service1();
res = tw.GetJobs();

boer virke.

Men du skal bruge den Rec som er genereret i stub *ikke* en haandskreven i client.
Avatar billede jackass- Nybegynder
11. april 2012 - 12:45 #11
Vil det ikke give mere mening at få XML til at virke? Det lyder (umiddelbart) mere "gængs"?
Avatar billede arne_v Ekspert
12. april 2012 - 01:37 #12
Mere gaengs??

Der er naeppe nogen der manuelt genererer XML for web services idag.
Avatar billede jackass- Nybegynder
12. april 2012 - 06:45 #13
Ok, det er noteret :-P

Men.. hvis jeg kalder servicen med:

myservice.Service1 tw = myservice.Service1();
res = tw.GetJobs();

Hvordan bruger jeg den Rec der bliver returned? Altså loop'er gennem resultatet fx. Kan ikke helt få det til at virke :-/
Avatar billede arne_v Ekspert
13. april 2012 - 00:58 #14
Du itererer vel gennem det array ligesom du goer med alle mulige andre arrays.

En for eller en foreach loekke.
Avatar billede jackass- Nybegynder
13. april 2012 - 07:52 #15
Når jeg invoker den via browser returnerer den:

<?xml version="1.0" encoding="utf-8" ?>
  <ArrayOfRec xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" xmlns="http://myweb/" />

Når jeg kalder webservicen via en C# applikation, får jeg fejlen "Object reference not set to an instance of an object". Jeg gør det således:

try
{
    myservice.Service1 tw = new myservice.Service1();
    Array res = tw.GetCopyJobs();

    foreach (string element in res)
    {
        richTextBox1.AppendText(element[0] + " :: " + element[1] + "\r\n");
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

Kan du se hvad jeg gør forkert?
Avatar billede arne_v Ekspert
14. april 2012 - 23:44 #16
Jeg tror at server side returnerer null.

Og jeg formoder at du skal bruge:

Rec[] res = tw.GetCopyJobs();
foreach (Rec element in res)
    richTextBox1.AppendText(element.SomeProp + " :: " + element.SomeOtherProp + "\r\n");
Avatar billede jackass- Nybegynder
18. april 2012 - 09:37 #17
Hvis jeg bruger "Rec[] res = tw.GetCopyJobs();" får jeg denne fejl:

Cannot implicitly convert type 'TestApplication.toolboxweb.Rec[]' to 'TestApplication.Rec[]'.

Jeg har "[Serializable]    public class Rec{ .. }" i både webservicen og klienten.
Avatar billede arne_v Ekspert
18. april 2012 - 16:22 #18
Du skal ikke selv skrive Rec i client.

Den bliver genereret for dig.
Avatar billede jackass- Nybegynder
20. april 2012 - 07:34 #19
Hvis jeg blot gør således:

myservice.Service1 tw = new myservice.Service1();
Rec[] res = tw.GetCopyJobs();

..får jeg denne fejl:

The type or namespace name 'Rec' could not be found (are you missing a using directive or an assembly reference?)

Det var derfor jeg selv skrev den ind :-/
Avatar billede arne_v Ekspert
20. april 2012 - 14:15 #20
Har du en:

using TestApplication.toolboxweb;

i toppen?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester