Laden...

WCF-Host läuft nicht in einer WPF-Umgebung

Erstellt von Runshak vor 9 Jahren Letzter Beitrag vor 9 Jahren 2.826 Views
R
Runshak Themenstarter:in
71 Beiträge seit 2014
vor 9 Jahren
WCF-Host läuft nicht in einer WPF-Umgebung

Hallo,

ich hab ne Verständnisfrage für folgendes Problem...

Eine einfache Consolenanwendung mit WCF realisiert...zwei Projekte in einer Mappe (Client und Server)

Das Serverprojekt bietet nen Service und das Clientprojekt greift darauf zu...funktioniert...der Client holt sich eine Message vom Service ab...läuft auch übers Netzwerk (2 Rechner)...

Jetzt wollte ich das ganze etwas aufhübschen und hab beiden Projekten ne WPF-Oberfläche verpasst...nun gut...lief nicht...keine Fehlermeldung die irgendwie weitergeholfen hätte...nur irgendwas mit nem Contract würde nicht stimmen...

Hab dann das Serverprojekt als Consolenanwendung gebastelt und das Clientprojekt als WPFanwendung...jetzt läuft es...

Ist es irgendwie möglich den Service über ne WPFanwendung zum laufen zu bringen??? oder läuft das nur mit Console?

16.835 Beiträge seit 2008
vor 9 Jahren

Nein. Sowohl Server wie auch Clients können problemlos in einer WCF-Anwendung laufen.
Insgesamt ist beides von der Umgebungstechnologie völlig unabhängig, egal ob der Host, Windows Forms, WPF, Windows Service, ASP.NET ist.

Ohne genaue Fehlermeldung ( [Hinweis] Wie poste ich richtig? Punkt 5) ist das jedoch sinnfrei sich über die Ursachen zu unterhalten.

R
Runshak Themenstarter:in
71 Beiträge seit 2014
vor 9 Jahren

hm...es wird bei meinem wpf Projekt eine "XamlParseException" geworfen...es ist aber 1:1 der selbe Code wie bei der Consolenanwendung...halt optisch "aufgehübscht"

Fehlermeldung:
Zeilennummer "3" und Zeilenposition "9" von "Durch den Aufruf des Konstruktors für Typ "WPFServerUndClient.MainWindow", der den angegebenen Bindungseinschränkungen entspricht, wurde eine Ausnahme ausgelöst."

in den Details steht dann:

Fehlermeldung:
Der Vertragsname "WPFServerUndClient.IHelloService" wurde nicht in der Liste von Verträgen gefunden, die vom Dienst "HelloService" implementiert wurden.

das tut er aber...sobald ich den Service über die Console laufen lasse verschwindet die Meldung wieder...und ich hab am Code dabei nichts geändert...nur copy/paste gemacht...deswegen bin ich verunsichert bzw verwundert warum es nicht funktioniert

16.835 Beiträge seit 2008
vor 9 Jahren

Dir ist klar, dass Du die Bindungen in der App.Config definieren musst?
Du hast ja schon mal vergessen, dass man Configs braucht.

R
Runshak Themenstarter:in
71 Beiträge seit 2014
vor 9 Jahren

das hab ich dieses mal alles berücksichtigt!

16.835 Beiträge seit 2008
vor 9 Jahren

Zeig Dein Zeug mal, Service und Config.
Hast sicher wieder was vergessen...vermutlich stimmt wieder der Namespace nicht (deswegen halte ich nichts von den Config-Dateien).

R
Runshak Themenstarter:in
71 Beiträge seit 2014
vor 9 Jahren

Service...

<Window x:Class="WPFServerUndClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Server" Height="255" Width="710">
    <Window.Resources>
        <ImageBrush x:Key="blue"    ImageSource="Properties/ultra.jpg" />
        <ImageBrush x:Key="technik" ImageSource="Properties/tech.jpg" />
    </Window.Resources>

    <Grid Background="{StaticResource blue}">

        <Menu Height="25"
              VerticalAlignment="Top">

            <MenuItem Header="Datei">
                <MenuItem Command="New" 
                          Header="Neu..."
                         />
                <Separator/>
                <MenuItem Click="OnBeenden" Header="Beenden"/>
            </MenuItem>
        </Menu>
        <TextBox Margin="305,76,185,114"
                 Height="35"
                 FontWeight="Medium"
                 FontSize="16"/>
        <TextBox Margin="525,76,30,114"
                 FontWeight="Medium"
                 FontSize="16"/>
        <TextBox Margin="27,126,30,21"
                 Name="TxtBoxServer"/>
        <Label Foreground="Red"
               Margin="305,45,185,138">Server Ip-Adresse
        </Label>
        <Label Foreground="Red"
               Margin="525,45,30,138">Server Portnummer

        </Label>
        <Label Background="{StaticResource technik}" 
               Margin="27,45,443,114"/>



    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFServerUndClient
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            using (ServiceHost sh = new ServiceHost(typeof(HelloService)))
            {
                sh.Open();                                  // Port wird geöffnet
                TxtBoxServer.Text = "Service ist bereit";

            }

        }

        private void OnBeenden(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace WPFServerUndClient
{
    [ServiceContract]
    interface IHelloService
    {
        [OperationContract]
        string DoIt();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WPFServerUndClient
{
    class HelloService
    {
         #region IHelloService Member

        public string DoIt()
        {
            return "Hallo Windows Communication Foundation";
        }
    }

        #endregion
    
}

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviorMeta">
          <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:2121/HelloService/meta"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="ServiceBehaviorMeta" name="WPFServerUndClient.HelloService">
        <endpoint address="http://localhost:2121/HelloService" binding="basicHttpBinding"
          bindingConfiguration="" name="HelloServiceHttpendpoint" contract="WPFServerUndClient.IHelloService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

wobei der Fehler eigentlich im Servicebereich liegen sollte...da beim Debuggen man gar nicht weiter kommt...

Client

<Window x:Class="Client.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Client" Height="255" Width="710">
    <Window.Resources>
        <ImageBrush x:Key="blue"    ImageSource="Properties/ultra.jpg" />
        <ImageBrush x:Key="technik" ImageSource="Properties/tech.jpg" />
    </Window.Resources>

    <Grid Background="{StaticResource blue}">

        <Menu Height="25"
              VerticalAlignment="Top">

            <MenuItem Header="Datei">
                <MenuItem Command="New" 
                          Header="Neu..."
                         />
                <Separator/>
                <MenuItem Click="OnBeenden" Header="Beenden"/>
            </MenuItem>
        </Menu>
        <TextBox Margin="305,76,185,114"
                 Height="35"
                 FontWeight="Medium"
                 FontSize="16"/>
        <TextBox Margin="525,76,30,114"
                 FontWeight="Medium"
                 FontSize="16"/>
        <TextBox    Name="TxtBoxClient"
                    Margin="27,126,185,21"/>
        <Label Foreground="Red"
               Margin="305,45,185,138">Server Ip-Adresse
        </Label>
        <Label Foreground="Red"
               Margin="525,45,30,138">Server Portnummer

        </Label>
        <Label Background="{StaticResource technik}" 
               Margin="27,45,443,114"/>

        <Button Margin="525,126,30,57"
                Background="White"
                Name="btnStarten"
                Click="OnClick"
                > Client starten
            
        </Button>

    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ServiceModel;

namespace Client
{
   
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            //HelloServiceClient hsc = new HelloServiceClient();

            //TxtBoxClient.Text = hsc.DoIt();
            //hsc.Close();
        }
        public void OnClick(object sender, RoutedEventArgs e)
        {
            String epName = "HelloServiceHttpendpoint";
            String rmAddres = "http://localhost:2121/HelloService";

            try 
            {

                HelloServiceClient hsc = new HelloServiceClient(epName, rmAddres);

                epName = hsc.DoIt();
                 hsc.Close();

	        } 
            
            catch (Exception ex) 
            {

                modAllgemein.AddLastErr(ref ex);
        	}
        }
        private void OnBeenden(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

    }
}

// Proxy

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IHelloService")]
public interface IHelloService
{

    [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IHelloService/DoIt", ReplyAction = "http://tempuri.org/IHelloService/DoItResponse")]
    string DoIt();

    [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IHelloService/DoIt", ReplyAction = "http://tempuri.org/IHelloService/DoItResponse")]
    System.Threading.Tasks.Task<string> DoItAsync();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IHelloServiceChannel : IHelloService, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class HelloServiceClient : System.ServiceModel.ClientBase<IHelloService>, IHelloService
{

    public HelloServiceClient()
    {
    }

    public HelloServiceClient(string endpointConfigurationName) :
        base(endpointConfigurationName)
    {
    }

    public HelloServiceClient(string endpointConfigurationName, string remoteAddress) :
        base(endpointConfigurationName, remoteAddress)
    {
    }

    public HelloServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
        base(endpointConfigurationName, remoteAddress)
    {
    }

    public HelloServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
        base(binding, remoteAddress)
    {
    }

    public string DoIt()
    {
        return base.Channel.DoIt();
    }

    public System.Threading.Tasks.Task<string> DoItAsync()
    {
        return base.Channel.DoItAsync();
    }
}

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="HelloServiceHttpendpoint" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint  binding="basicHttpBinding" address="http://localhost:2121/HelloService"
          bindingConfiguration="HelloServiceHttpendpoint" contract="IHelloService"
          name="HelloServiceHttpendpoint" />
    </client>
  </system.serviceModel>
</configuration>


using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Windows;

namespace Client
{

    static class modAllgemein
    {

         public static void AddErr(ref Exception mEx)
        {
        //string strD = null;
        //string strT = null;

           MessageBox.Show(mEx.Source + "\r\n" + mEx.StackTrace);


         }



         public static void AddLastErr(ref Exception mEx)
        {
        //string strD = null;
        //string strT = null;

            MessageBox.Show(mEx.Source + "\r\n" + mEx.StackTrace);


        }

    }
}
16.835 Beiträge seit 2008
vor 9 Jahren

Ich finde es aus meiner Sicht sehr sehr schade, dass man sich Mühe mit Beispielen und sogar Code Snippets macht und die Leute ignorieren alles.
Dass Du es jetzt mit Deiner Umsetzung unbedingt durchboxen musst; das ist ok für Dich.

Ich würde es immer noch anders machen, weil Deine Variante in meinen Augen alles andere als sauber ist.
Wie das aussieht hab ich in WCF-Client bekommt Fehlermeldung und Einfaches WCF-Beispiel ohne komplizierte Config gezeigt.

Ein mal schreibst Du bindingConfiguration="" name="HelloServiceHttpendpoint" contract="**WPFServerUndClient**.IHelloService&quot; /&gt; und ein mal bindingConfiguration="HelloServiceHttpendpoint" contract="IHelloService", also ohne Base-Namespace.

Warum es so wichtig ist die einzelnen Elemente auszulagern hab ich im Blog beschrieben.
Ich denke so wie Du es machst hat es - meiner Meinung nach - keine Zukunft und Du stolperst von Problem A in Problem B.

Irgendwie wirkt das ganze auf mich so (weiß nicht ob es tatsächlich so ist) auch, dass Du nur irgendwie rumstocherst.

   using (ServiceHost sh = new ServiceHost(typeof(HelloService)))
             {
                 sh.Open();                                  // Port wird geöffnet
                 TxtBoxServer.Text = "Service ist bereit";

             }

Du schließt den Service sofort wieder. Das hat ja nichts mit "Bereit" zutun?! 🤔
Und Du öffnest ja keinen Port, sondern den (Service)Host.

das hab ich dieses mal alles berücksichtigt!

-->

namespace WPFServerUndClient
 {
     class HelloService

sehe keine Implementierung von IHelloService...
(Mein Edit hat sich mit Landos Antwort überschnitten)

74 Beiträge seit 2014
vor 9 Jahren

Und außerdem implementiert die Service-Klasse (zumindest im Snippet) das Interface nicht.

R
Runshak Themenstarter:in
71 Beiträge seit 2014
vor 9 Jahren

@ Lando ...du hast recht -.- [edit] Der Fehler taucht trotzdem noch auf...habs wieder vererbt...

@ Abt
Danke für deine Mühe...und auch danke für dein Beispielprogramm...leider verstehe ich noch nicht alles in deinem Bsp. deswegen ist es mir noch nicht möglich es korrekt selbst umzusetzen...aber ich wollte genau in diesem Projekt es Stück für Stück ändern...so dass ich es endlich verstehe...aber das ist eben nur möglich wenn das, was ich bisher selbst gemacht habe auch läuft...

...das mit dem Port öffnen stammt aus einem Tutorial...danke, werde es korrigieren...

du hast in deinem Beispielcode

ChannelFactory<ICalcService> chFactory = new ChannelFactory<ICalcService>( tcpb );

verwendet...ich versteh dabei nur "Bahnhof"...wenn ich das in meinem "Versuchsprojekt" ebenfalls implementiert habe, bekam ich die Meldung, dass irgendeine Sicherheitsebene nicht befugt ist oder so...damit konnte ich nichts anfangen...und die Dokumentation von Microsoft ist in meinen Augen teilweise etwas arg karg und kurz gehalten bzw hat merkwürdigen Beispielcode...ich hab jetzt schon zwei bücher vor mir liegen und sie auch so weit gelesen...aber immer an der entscheidenden Stelle wird das Kapitel beendet...die Beispiele darin sind jedes mal mit dem app.config gemacht und nicht so wie in deinem Beispiel ohne...und ich finde es wirklich nett und ausgesprochen hilfreich, dass du mir extra ein Beispielcode geschrieben hast, aber mir fehlt auf diese Art eben das Verständnis...weil abschreiben kann ich es...klar...aber ich muss es ja auch verstehen um dann selbst was zu programmieren...