Laden...

Daten mit Zusatzinformationen versehen

Erstellt von itstata vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.308 Views
I
itstata Themenstarter:in
302 Beiträge seit 2008
vor 14 Jahren
Daten mit Zusatzinformationen versehen

Hallo,
ich würde gerne mal wissen wie ein geeigneter Weg ist Daten von einem Webservice mit zusätzlichen Informationen zu versehen. Hintergrund ist folgendes...
Bei einigen Methoden seitens des Webservice kann es sein, dass die Datengrundlage nicht vollständig ist und daher nicht die komplette Berechnung durchgeführt werden kann. Einie Ausnahme auszulösen ist aber zu viel da ja einige Daten berechnet werden könnten. Sonst hätte ich einfach die Ausnahme weitergereicht. Dem Nutzer am Client soll dann einfach angezeigt werden, dass einige Daten fehlen und daher nicht alles berechnet werden konnte. Ich hab einfach eine generische Klasse erstellt die zusätzlich Informationen bereitstellen kann... siehe Beispiel:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            String helloWorld = "Hallo Welt";
            ExtendedData<String> w = new ExtendedData<String>(helloWorld);


            if (w.FehlendeDaten)
                Console.WriteLine("Es hat etwas gefehlt, ich zeig dir die Daten aber trotzdem an");

            Console.WriteLine(w.Content);

        }
    }
    /// <summary>
    /// Daten die noch eine Information enthalten ob alle Basisdaten vorlagen.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class ExtendedData<T>
    {
        T content;
        bool fehlendeDaten = false;

        public ExtendedData(T content)
        {
            this.content = content;
        }

        public bool FehlendeDaten
        {
            get
            {
                // simuliere Fehler
                fehlendeDaten = true;

                return fehlendeDaten;
            }
            set { fehlendeDaten = value; }
        }

        public T Content
        {
            get { return content; }
        }
    }
}

hat jemand schon einmal etwas in der art implementiert?
man könnte natürlich auch argumentieren, dass der client über eine separate methode die vollständigkeit der daten prüfen muss und der webservice selbst "dumm" ist.

was haltet ihr von dieser Lösung?

S
8.746 Beiträge seit 2005
vor 14 Jahren

Mit generischen Typen kannst du in Webservices nicht arbeiten.

I
itstata Themenstarter:in
302 Beiträge seit 2008
vor 14 Jahren

bist du dir sicher List<xy> ist doch auch generisch und das unterstütz der ws auf jeden fall...

S
8.746 Beiträge seit 2005
vor 14 Jahren

List<T> ist ein Sonderfall, weil der auf ein nicht-generisches Array abgebildet wird. Ansonsten fliegt dir beim Starten des Dienstes folgendes um die Ohren:

Der Typ "ConsoleApplication2.GenType`1[T]" kann nicht als Schematyp exportiert werden, da er ein offener generischer Typ ist. Ein generischer Typ kann nur exportiert werden, wenn alle zugehörigen generischen Parametertypen tatsächliche Typen sind.

XML Schema kennen keine generischen Typen, deswegen muss man auf generische Typen in Webservices verzichten.

Was man bauen kann ist ein generischer Service, d.h. das Service-Interface selbst ist generisch. Beim Starten des Dienstes muss aber dann ein konkreter Typ angegeben werden. Nach außen ist der Dienst dann eben mit diesem einen Typen sichtbar - also nicht mehr generisch. Generische Typen als Parameter oder Return-Werte gehen nicht.

Ggf. kannst du aber auch Vererbung ausweichen. Abstrakte Typen gehen. Aber mangels Mehrfachvererbung ist das natürlich kritisch. Auf Interfaces kannst du auch nicht ausweichen.

I
itstata Themenstarter:in
302 Beiträge seit 2008
vor 14 Jahren

also ich hab das gerade probiert und nach meiner Meinung funktioniert dies ohne weiteres. es ist ja letztendlich doch alles typisiert.

Service:


 public class Service1 : IService1
    {
        public ExtendetData<String> GetHello()
        {
            return new ExtendetData<string>("hallo");
        }
        public ExtendetData<Auto> GetCustomClass()
        {
            return new ExtendetData<Auto>(new Auto("Golf", "Volkswagen"));
        }

    }
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        ExtendetData<String> GetHello();

        [OperationContract]
        ExtendetData<Auto> GetCustomClass();
    }

    [DataContract]
    public class Auto
    {
        private String _name;
        private String _hersteller;

        [DataMember]
        public String Name
        {
            get { return _name; }
            set { _name = value; }
        }

        [DataMember]
        public String Hersteller
        {
            get { return _hersteller; }
            set { _hersteller = value; }
        }

        public Auto(String name, String hersteller)
        {
            this._hersteller = hersteller;
            this._name = name;
        }
    }


    [DataContract]
    [Serializable]
    public class ExtendetData<T>
    {
        T content;
        bool fehlendeDaten = false;

        public ExtendetData(T content)
        {
            this.content = content;
        }

        [DataMember]
        public bool FehlendeDaten
        {
            get
            {
                // simuliere Fehler
                fehlendeDaten = true;

                return fehlendeDaten;
            }
            set { fehlendeDaten = value; }
        }

        [DataMember]
        public T Content
        {
            get { return content; }
            set { content = value; ; }
        }
    }

und der Client:

static void Main(string[] args)
        {
            using (ServiceReference1.Service1Client client = new ConsoleApplication1.ServiceReference1.Service1Client())
            {
                ServiceReference1.ExtendetDataOfstring result = client.GetHello();
                if (result.FehlendeDaten)
                    Console.WriteLine("da fehlt was, aber ich zeig dir die daten an die ich berechnen konnte...");

                Console.WriteLine(result.Content);


                ServiceReference1.ExtendetDataOfAutoAJw_PARbn extendedAuto = client.GetCustomClass();

                if (extendedAuto.FehlendeDaten)
                    Console.WriteLine("da fehlt was, aber ich zeig dir die daten an die ich berechnen konnte...");

                Console.WriteLine("Name:" + (extendedAuto.Content.Name));
                Console.ReadKey();

            }
        }

S
8.746 Beiträge seit 2005
vor 14 Jahren

Solange du im Service nur konkrete Klassen verwendest geht das. Im Client wirds nur sehr unschön, denn aus ExtendetData<String> wird wohl ExtendetData11 werden, aus ExtendetData&lt;String&gt; wird ExtendetData12. Da wäre mir ExtendetDataString und ExtendetDataAuto schon lieber....

I
itstata Themenstarter:in
302 Beiträge seit 2008
vor 14 Jahren

ja, das ist wohl so.... momentan hab ich leider keine alternative.