Also habe ich derzeit 2 WSDLs als Service-Referenzen in meiner Lösung hinzugefügt. Sie sehen aus wie dies in meiner app.config-Datei (ich das „Bindungen“ Feld entfernt, weil es uninteressant):Adresse/Port von WSDL EndPointAddress zur Laufzeit ändern?
<system.serviceModel>
<client>
<endpoint address="http://localhost:8080/query-service/jse" binding="basicHttpBinding" bindingConfiguration="QueryBinding" contract="QueryService.Query" name="QueryPort" />
<endpoint address="http://localhost:8080/dataimport-service/jse" binding="basicHttpBinding" bindingConfiguration="DataImportBinding" contract="DataService.DataImport" name="DataImportPort" />
</client>
</system.serviceModel>
Wenn ich eine WSDL verwenden, sieht es so etwas wie diese:
using (DataService.DataClient dClient = new DataService.DataClient())
{
DataService.importTask impt = new DataService.importTask();
impt.String_1 = "someData";
DataService.importResponse imptr = dClient.importTask(impt);
}
Wenn ich das DataClient-Objekt instanziiere, stehen mir in der "using" -Anweisung 5 Konstruktoren zur Verfügung. In diesem Szenario verwende ich den Standard-Konstruktor:
new DataService.DataClient()
, die die Einbau-Endpunkt-Adressen-Zeichenfolge verwendet, die ich davon ausgehen, wird von app.config gezogen. Aber ich möchte, dass der Benutzer der Anwendung die Option hat, diesen Wert zu ändern.
1) Was ist der beste/einfachste Weg, diese Zeichenfolge programmatisch zu erhalten?
2) Wenn ich dem Benutzer erlaubt habe, den Wert zu bearbeiten und zu testen, wo sollte ich ihn dann speichern?
Ich würde es vorziehen, dass es an einem Ort (wie app.config oder gleichwertig) gespeichert wird, so dass nicht überprüft werden muss, ob der Wert existiert und ob ich einen alternativen Konstruktor verwenden sollte. (Auf der Suche nach meinem Code fest, weißt du das?)
Irgendwelche Ideen? Vorschläge?
EDIT
Vielleicht auch über diese Alternative Konstrukteuren frage ich sollte.
Zum Beispiel einer von ihnen sieht wie folgt aus:
Welche Werte könnten für „endPointConfigurationName“ get übergeben und „remote“?
EDIT2
meine Fragen hier Antworten, die „endPointConfigurationName“ erscheint das gleiche wie den „name“ in der app.config XML und das „remote“ zu sein, ist das gleiche wie „Endpunkt-Adresse formatiert "in der app.config XML.
Auch! Die Antwort auf meine erste Frage über die EndPointAddresses bekommen ist folgende:
ClientSection clSection =
ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
ChannelEndpointElementCollection endpointCollection =
clSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;
Dictionary<string, string> nameAddressDictionary =
new Dictionary<string, string>();
foreach (ChannelEndpointElement endpointElement in endpointCollection)
{
nameAddressDictionary.Add(endpointElement.Name,
endpointElement.Address.ToString());
}
EDIT3
Ok, ich glaube, ich habe die 2. Hälfte herausgefunden (und damit vollständige Lösung) zu meinem Problem . Ich fand dies auf einer anderen Website und ich modifizierte es meine Bedürfnisse zu erfüllen:
Configuration configuration;
ServiceModelSectionGroup serviceModelSectionGroup;
ClientSection clientSection;
configuration =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
serviceModelSectionGroup =
ServiceModelSectionGroup.GetSectionGroup(configuration);
clientSection = serviceModelSectionGroup.Client;
foreach (ChannelEndpointElement endPt in clientSection.Endpoints)
{
MessageBox.Show(endPt.Name + " = " + endPt.Address);
}
configuration.Save();
Mit diesem Code haben wir Zugang zu dem clientSection.Endpoints und können alle Elementeigenschaften zugreifen und diese ändern, wie „Adresse“. Und dann, wenn wir fertig sind sie zu ändern, können wir Konfiguration.Sichern() und alle Werte in eine Benutzerdatei geschrieben werden.
Jetzt ist hier der Haken.Im Debug-Modus scheint "configuration.save()" Ihre Werte nicht von der Ausführung bis zur Ausführung zu halten, aber wenn die Anwendung normal ausgeführt wird (außerhalb des Debug-Modus), bleiben die Werte erhalten. (Was gut ist.) Das ist also der einzige Vorbehalt.
Edit4
Es gibt einen weiteren Nachteil. Die Änderungen an den WSDLs werden zur Laufzeit nicht wirksam. Die Anwendung muss neu gestartet werden, um die Benutzer-Konfigurationsdatei Werte in den Speicher neu lesen (offenbar.)
Die einzige andere Sache, die ich interessiert sein könnte in sich einen Weg zu finden (sobald die Werte geändert wurden) um die Werte auf ihre Standardwerte zurückzusetzen. Sicher, Sie können wahrscheinlich die Benutzerdatei löschen, aber das löscht alle benutzerdefinierten Einstellungen.
Irgendwelche Ideen?
EDIT5
Ich denke, Dependency Injection könnte perfekt hier sein, aber müssen es erforschen mehr ...
EDIT 6
Ich habe keine Kommentar Privilegien, sondern Sie müssen
ConfigurationManager.RefreshSection("client");
laufen, um den Cache aktualisiert zu haben, damit Änderungen sofort geschehen.
Ich werde diesen Artikel wieder lesen (meine Augen begannen etwa auf halber Höhe des Artikels zu glasieren ...) Aber ich würde widersprechen: Es ist * ziemlich * schwierig. Besonders wenn man bedenkt, dass ich kaum weiß, was diese WSDLs machen sollen. Und ich habe vielleicht bis zu 22 WSDLs, die ich irgendwann integrieren muss. "Add Service Reference" war wunderbare Magie. Limitierend, sicher, aber wunderbar darin, dass es mein Projekt schnell ging. (Ich gebe dir trotzdem eine +1, da es ein guter Fund ist. Danke!) – Pretzel
Ja, ich merke, dass ich mich wie ein fauler Programmierer anhört. Sind wir nicht alle bis zu einem gewissen Grad? :-) Ich schwöre, ich werde noch ein paar Aufnahmen machen, aber es scheint, als würde ich versuchen, einen Abschluss in Bauingenieurwesen und Architektur zu machen, nur um eine Hütte in meinem Garten zu bauen. Du weißt? – Pretzel
@Pretzel - Gute Trauer, 22 Referenzen! In diesem Fall gibt es eine schnelle und schmutzige Lösung, die ich in der Vergangenheit verwendet habe. Versuchen Sie Teilklassen zu nutzen. Die Idee wäre, eine partielle Klasse für die automatisch generierten zu haben, damit Sie Ihren Code bei einem Service-Referenz-Update nicht verlieren. Wie auch immer, Sie sind an einer Kreuzung. Lernen Sie den von Microsoft generierten Code und sezieren Sie ihn oder schreiben Sie ihn selbst. – Matt