diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index cc17ed5a4e..0e8f4c245b 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -280,6 +280,8 @@
+
+
diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs
index 604b12b38f..8da3b889a1 100644
--- a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs
+++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs
@@ -43,9 +43,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
ServiceItem myItem;
Uri discoveryUri;
- ServiceDescriptionCollection serviceDescriptionCollection = new ServiceDescriptionCollection();
CredentialCache credentialCache = new CredentialCache();
WebServiceDiscoveryClientProtocol discoveryClientProtocol;
+ ServiceReferenceDiscoveryClient serviceReferenceDiscoveryClient;
delegate DiscoveryDocument DiscoverAnyAsync(string url);
delegate void DiscoveredWebServicesHandler(DiscoveryClientProtocol protocol);
@@ -121,13 +121,32 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
AsyncCallback callback = new AsyncCallback(DiscoveryCompleted);
discoveryClientProtocol.Credentials = credential;
IAsyncResult result = asyncDelegate.BeginInvoke(uri.AbsoluteUri, callback, new AsyncDiscoveryState(discoveryClientProtocol, uri, credential));
+
+ serviceReferenceDiscoveryClient.DiscoveryComplete += ServiceReferenceDiscoveryComplete;
+ serviceReferenceDiscoveryClient.Discover(uri);
+ }
+
+ void ServiceReferenceDiscoveryComplete(object sender, ServiceReferenceDiscoveryEventArgs e)
+ {
+ if (Object.ReferenceEquals(serviceReferenceDiscoveryClient, sender)) {
+ if (e.HasError) {
+ OnWebServiceDiscoveryError(e.Error);
+ } else {
+ DiscoveredWebServices(e.Services);
+ }
+ }
+ }
+
+ void OnWebServiceDiscoveryError(Exception ex)
+ {
+ ServiceDescriptionMessage = ex.Message;
+ ICSharpCode.Core.LoggingService.Debug("DiscoveryCompleted: " + ex.ToString());
}
///
/// Called after an asynchronous web services search has
/// completed.
///
- ///
void DiscoveryCompleted(IAsyncResult result)
{
AsyncDiscoveryState state = (AsyncDiscoveryState)result.AsyncState;
@@ -144,20 +163,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
try {
DiscoverAnyAsync asyncDelegate = (DiscoverAnyAsync)((AsyncResult)result).AsyncDelegate;
DiscoveryDocument handlerdoc = asyncDelegate.EndInvoke(result);
- if (!state.Credential.IsDefaultAuthenticationType) {
- AddCredential(state.Uri, state.Credential);
- }
handler(protocol);
} catch (Exception ex) {
- if (protocol.IsAuthenticationRequired) {
- HttpAuthenticationHeader authHeader = protocol.GetAuthenticationHeader();
- AuthenticationHandler authHandler = new AuthenticationHandler(AuthenticateUser);
-// trouble Invoke(authHandler, new object[] {state.Uri, authHeader.AuthenticationType});
- } else {
- ServiceDescriptionMessage = ex.Message;
- ICSharpCode.Core.LoggingService.Error("DiscoveryCompleted", ex);
-// trouble Invoke(handler, new object[] {null});
- }
+ OnWebServiceDiscoveryError(ex);
}
}
}
@@ -180,47 +188,30 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
discoveryClientProtocol.Dispose();
}
discoveryClientProtocol = new WebServiceDiscoveryClientProtocol();
+ serviceReferenceDiscoveryClient = new ServiceReferenceDiscoveryClient();
}
}
- void AuthenticateUser(Uri uri, string authenticationType)
- {
- DiscoveryNetworkCredential credential = (DiscoveryNetworkCredential)credentialCache.GetCredential(uri, authenticationType);
- if (credential != null) {
- StartDiscovery(uri, credential);
- } else {
- using (UserCredentialsDialog credentialsForm = new UserCredentialsDialog(uri.ToString(), authenticationType)) {
-// if (DialogResult.OK == credentialsForm.ShowDialog(WorkbenchSingleton.MainWin32Window)) {
-// StartDiscovery(uri, credentialsForm.Credential);
-// }
- }
- }
- }
-
- void AddCredential(Uri uri, DiscoveryNetworkCredential credential)
+ void DiscoveredWebServices(DiscoveryClientProtocol protocol)
{
- NetworkCredential matchedCredential = credentialCache.GetCredential(uri, credential.AuthenticationType);
- if (matchedCredential != null) {
- credentialCache.Remove(uri, credential.AuthenticationType);
+ if (protocol != null) {
+ ServiceDescriptionCollection services = ServiceReferenceHelper.GetServiceDescriptions(protocol);
+ DiscoveredWebServices(services);
}
- credentialCache.Add(uri, credential.AuthenticationType, credential);
}
- void DiscoveredWebServices(DiscoveryClientProtocol protocol)
+ void DiscoveredWebServices(ServiceDescriptionCollection services)
{
- if (protocol != null) {
- serviceDescriptionCollection = ServiceReferenceHelper.GetServiceDescriptions(protocol);
- ServiceDescriptionMessage = String.Format(
- "{0} service(s) found at address {1}",
- serviceDescriptionCollection.Count,
- discoveryUri);
- if (serviceDescriptionCollection.Count > 0) {
- AddUrlToHistory(discoveryUri);
- }
- DefaultNameSpace = GetDefaultNamespace();
- FillItems(serviceDescriptionCollection);
- string referenceName = ServiceReferenceHelper.GetReferenceName(discoveryUri);
+ ServiceDescriptionMessage = String.Format(
+ "{0} service(s) found at address {1}",
+ services.Count,
+ discoveryUri);
+ if (services.Count > 0) {
+ AddUrlToHistory(discoveryUri);
}
+ DefaultNameSpace = GetDefaultNamespace();
+ FillItems(services);
+ string referenceName = ServiceReferenceHelper.GetReferenceName(discoveryUri);
}
void AddUrlToHistory(Uri discoveryUri)
@@ -312,14 +303,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
void UpdateListView()
{
- ServiceDescription desc = null;
TwoValues.Clear();
- if(ServiceItem.Tag is ServiceDescription) {
- desc = (ServiceDescription)ServiceItem.Tag;
+ if (ServiceItem.Tag is ServiceDescription) {
+ ServiceDescription desc = (ServiceDescription)ServiceItem.Tag;
var tv = new ImageAndDescription(PresentationResourceService.GetBitmapSource("Icons.16x16.Interface"),
desc.RetrievalUrl);
TwoValues.Add(tv);
- } else if(ServiceItem.Tag is PortType) {
+ } else if (ServiceItem.Tag is PortType) {
PortType portType = (PortType)ServiceItem.Tag;
foreach (Operation op in portType.Operations) {
TwoValues.Add(new ImageAndDescription(PresentationResourceService.GetBitmapSource("Icons.16x16.Method"),
@@ -330,7 +320,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
void FillItems(ServiceDescriptionCollection descriptions)
{
- foreach(ServiceDescription element in descriptions) {
+ foreach (ServiceDescription element in descriptions) {
Add(element);
}
}
@@ -342,7 +332,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
var rootNode = new ServiceItem(null, name);
rootNode.Tag = description;
- foreach(Service service in description.Services) {
+ foreach (Service service in description.Services) {
var serviceNode = new ServiceItem(null, service.Name);
serviceNode.Tag = service;
items.Add(serviceNode);
diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryClient.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryClient.cs
new file mode 100644
index 0000000000..fb7620e2b6
--- /dev/null
+++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryClient.cs
@@ -0,0 +1,90 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ServiceModel.Description;
+
+namespace ICSharpCode.SharpDevelop.Gui
+{
+ public class ServiceReferenceDiscoveryClient
+ {
+ const int DiscoveryClientsUsed = 2;
+
+ Uri discoveryUrl;
+ BackgroundWorker mexDiscoveryBackgroundWorker = new BackgroundWorker();
+ BackgroundWorker mexRelativePathDiscoveryBackgroundWorker = new BackgroundWorker();
+ List errors = new List();
+
+ public ServiceReferenceDiscoveryClient()
+ {
+ }
+
+ public event EventHandler DiscoveryComplete;
+
+ protected virtual void OnDiscoveryComplete(ServiceReferenceDiscoveryEventArgs e)
+ {
+ if (DiscoveryComplete != null) {
+ DiscoveryComplete(this, e);
+ }
+ }
+
+ public void Discover(Uri url)
+ {
+ this.discoveryUrl = url;
+ DiscoverMexMetadata();
+ }
+
+ void DiscoverMexMetadata()
+ {
+ DiscoverMexMetadata(mexDiscoveryBackgroundWorker, discoveryUrl);
+ DiscoverMexMetadata(mexRelativePathDiscoveryBackgroundWorker, GetRelativeUrl("mex"));
+ }
+
+ Uri GetRelativeUrl(string relativeUrl)
+ {
+ return new Uri(GetDiscoveryUrlWithTrailingSlash(), relativeUrl);
+ }
+
+ Uri GetDiscoveryUrlWithTrailingSlash()
+ {
+ if (discoveryUrl.AbsoluteUri.EndsWith("/")) {
+ return discoveryUrl;
+ }
+ return new Uri(discoveryUrl.AbsoluteUri + "/");
+ }
+
+ void DiscoverMexMetadata(BackgroundWorker worker, Uri url)
+ {
+ worker.DoWork += DiscoverMexMetadata;
+ worker.RunWorkerCompleted += DiscoveryCompleted;
+ worker.RunWorkerAsync(url);
+ }
+
+ void DiscoverMexMetadata(object sender, DoWorkEventArgs e)
+ {
+ Uri url = (Uri)e.Argument;
+ var client = new MetadataExchangeClient(url, MetadataExchangeClientMode.MetadataExchange);
+ MetadataSet metadata = client.GetMetadata();
+ e.Result = new ServiceReferenceDiscoveryEventArgs(metadata);
+ }
+
+ void DiscoveryCompleted(object sender, RunWorkerCompletedEventArgs e)
+ {
+ if (e.Error != null) {
+ OnDiscoveryError(e.Error);
+ } else {
+ OnDiscoveryComplete((ServiceReferenceDiscoveryEventArgs)e.Result);
+ }
+ }
+
+ void OnDiscoveryError(Exception ex)
+ {
+ errors.Add(ex);
+ if (errors.Count == DiscoveryClientsUsed) {
+ OnDiscoveryComplete(new ServiceReferenceDiscoveryEventArgs(errors));
+ }
+ }
+ }
+}
diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryEventArgs.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryEventArgs.cs
new file mode 100644
index 0000000000..07bfde247f
--- /dev/null
+++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryEventArgs.cs
@@ -0,0 +1,57 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.ServiceModel.Description;
+using System.Text;
+using System.Web.Services.Description;
+using WebServices = System.Web.Services.Description;
+
+namespace ICSharpCode.SharpDevelop.Gui
+{
+ public class ServiceReferenceDiscoveryEventArgs : EventArgs
+ {
+ ServiceDescriptionCollection services = new ServiceDescriptionCollection();
+
+ public ServiceReferenceDiscoveryEventArgs(IEnumerable errors)
+ {
+ GenerateAggregateError(errors);
+ }
+
+ void GenerateAggregateError(IEnumerable errors)
+ {
+ var message = new StringBuilder();
+ foreach (Exception ex in errors) {
+ message.AppendLine(ex.Message);
+ message.AppendLine();
+ }
+ Error = new AggregateException(message.ToString(), errors);
+ }
+
+ public ServiceReferenceDiscoveryEventArgs(MetadataSet metadata)
+ {
+ GetServices(metadata);
+ }
+
+ void GetServices(MetadataSet metadata)
+ {
+ foreach (MetadataSection section in metadata.MetadataSections) {
+ var service = section.Metadata as WebServices.ServiceDescription;
+ if (service != null) {
+ Services.Add(service);
+ }
+ }
+ }
+
+ public ServiceDescriptionCollection Services {
+ get { return services; }
+ }
+
+ public Exception Error { get; private set; }
+
+ public bool HasError {
+ get { return Error != null; }
+ }
+ }
+}