Autor Beitrag
FrEEzE2046
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 109

Windows 98, 2000, XP Pro, Vista Ultimate 32 & 64 Bit, Windows 7 Beta 64 Bit
C/C++, C# (VS 2008 TeamSystem) - Delphi (Delphi 5) - Java (Eclipse)
BeitragVerfasst: Di 25.05.10 21:06 
Hallo,

ich erkläre am besten mal meine Anforderung:

Ich habe einen WCF-Service auf den ich von einer Silverlight Application aus zugreife. Innerhalb der Domäne des Services existiert ein Image-Folder. Dies ist alles was statisch existiert.
In diesem Verzeichnis können weitere Folder abgelegt werden. Diese repräsentieren einzelne Alben. Der Name des Folder entspricht dann auch dem Titel des Albums.

Die eigentliche Übertragung der Bilder stellt die größte Frage dar. Aus meiner Sicht würde ich einfach die Raw-Daten der Dateien übers Netzwerk übertragen. Da jedoch in WCF der ganze Netzwerkverkehr stark abstrahiert wurde, gibt es sicherlich eine viel elegantere Möglichkeit. Am einfachsten wäre wohl die Übertragung eines BitmapImage[]. Dazu würde sich mir aber auch die Frage stellen, wie ich das mache, da meines Wissens nach nur Klassen übertragen werden können, die das DataContractAttribute-Attribut haben.
Am liebsten wäre mir eine Art Random-Access-Iterator auf meine Images zurückgeliefert zu bekommen. Das sollte so funktionieren, dass man dem Konstruktor einen PrefetchLevel mitgeben kann.
Angenommen ich möchte 16 Bilder prefetchen, dann sollte der erste Zugriff auf Image[0] mir die Bilder 0-15 übertragen, sodass erst bei Zugriff auf Image[16] erneut die Netzwerkleitung in Anspruch genommen werden müsste.


Die Umsetzung stelle ich mir ungefähr so vor (PseudoCode)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
WcfServiceClient client = new WcfServiceClient();

MyAlbumEnum album    = client.EnumerateAlbums();      // alle Alben im Ordner Image
MyImageIterator iter = client.EnumerateImages(album.AlbumA, 16);

[...]


Hat da jemand eine Lösung parat, die in diese Richtung geht?
Vielen Dank im Voraus.
FrEEzE2046 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 109

Windows 98, 2000, XP Pro, Vista Ultimate 32 & 64 Bit, Windows 7 Beta 64 Bit
C/C++, C# (VS 2008 TeamSystem) - Delphi (Delphi 5) - Java (Eclipse)
BeitragVerfasst: Mo 31.05.10 17:24 
Ich bin einem Beispiel auf MSDN gefolgt und wollte erst mal die grundlegende Übertragung implementierten. Der Service sieht folgendermaßen aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ImageService
{
    private IEnumerable<FileInfo> _Files;

    public ImageService()
    {
        this._Files = new DirectoryInfo(@"F:\Images").EnumerateFiles();
    }

    [OperationContract, WebGet, FaultContract(typeof(ArgumentOutOfRangeException))]
    public Stream GetImage(uint num)
    {
        if (this._Files.Count() > num)
        {
            MemoryStream ms = new MemoryStream();
            Bitmap bmp = new Bitmap(this._Files.ElementAt((int)num).OpenRead());
            bmp.Save(ms, ImageFormat.Jpeg);
            ms.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
            return ms;
        }
        else
            throw new FaultException<ArgumentOutOfRangeException>(new ArgumentOutOfRangeException());
    }
}


Der Aufruf so:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{         
    this.stateText.Text = "begin loading image";
    var client = new ImageServiceClient();

    var obsGetImage = Observable.FromEvent<GetImageCompletedEventArgs>
    (
        h => client.GetImageCompleted += h,
        h => client.GetImageCompleted -= h
    )
    .Take(1);

    obsGetImage.Subscribe
    (
        args =>
        {
            BitmapImage bmp = new BitmapImage();

            try
            {
                bmp.SetSource(new MemoryStream(args.EventArgs.Result));
                this.img.Source = bmp;
            }
            catch (Exception ex)
            {
                do
                {
                    MessageBox.Show(ex.Message);
                }
                while( (ex = ex.InnerException) != null );
            }

            this.stateText.Text = "finished loading image";
        }
    );

    client.GetImageAsync(0);
}


Ich bekomme immer folgende Exceptions:

ausblenden Quelltext
1:
2:
ex = Während des Vorgangs ist eine Ausnahme aufgetreten, sodass das Ergebnis ungültig ist. Weitere Ausnahmedetails finden Sie in InnerException.
ex.InnerException = Der Inhaltstyp "image/jpeg" der Antwortnachricht stimmt nicht mit dem Inhaltstyp der Bindung (application/soap+msbin1) überein. Wenn sie einen benutzerdefinierten Encoder verwenden, sollten Sie sicherstellen, dass die IsContentTypeSupported-Methode korrekt implementiert ist. Dier ersten 1024 Bytes der Antwort waren ...


Warum der Fehler auftritt ist mir klar, aber wie kann ich den "Inhaltstyp der Bindung" definieren?