Fixed some med trust issues with UmbracoExamine. Created new framework for distributed cache providers with unit tests. Still uses the

old ICacheRefresher but now we can plugin 2 new providers - one for resolving a list of servers and the other to notify the servers of changes.
By default we have the configuration based providers which uses the umbracoSettings.
This commit is contained in:
Shannon Deminick
2013-02-12 03:46:27 +06:00
parent f741861014
commit 4e6bdd1fc7
24 changed files with 1120 additions and 467 deletions

View File

@@ -166,9 +166,15 @@ namespace Umbraco.Core
/// </summary>
protected virtual void InitializeResolvers()
{
//by default we'll use the standard configuration based sync
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
new ConfigServerRegistrar()); //by default we'll use the standard configuration based sync
new ConfigServerRegistrar());
//by default (outside of the web) we'll use the default server messenger without
//supplying a username/password, this will automatically disable distributed calls
// .. we'll override this in the WebBootManager
ServerMessengerResolver.Current = new ServerMessengerResolver(
new DefaultServerMessenger());
RepositoryResolver.Current = new RepositoryResolver(
new RepositoryFactory());

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.Sync
{
/// <summary>
/// A registrar that uses the legacy xml configuration in umbracoSettings to get a list of defined server nodes
/// </summary>
internal class ConfigServerRegistrar : IServerRegistrar
{
private readonly XmlNode _xmlServers;
public ConfigServerRegistrar()
: this(UmbracoSettings.DistributionServers)
{
}
internal ConfigServerRegistrar(XmlNode xmlServers)
{
_xmlServers = xmlServers;
}
private List<IServerRegistration> _addresses;
public IEnumerable<IServerRegistration> Registrations
{
get
{
if (_addresses == null)
{
_addresses = new List<IServerRegistration>();
var nodes = _xmlServers.SelectNodes("./server");
foreach (XmlNode n in nodes)
{
_addresses.Add(new ConfigServerRegistration(n));
}
}
return _addresses;
}
}
}
}

View File

@@ -0,0 +1,29 @@
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Core.Sync
{
/// <summary>
/// A server registration based on the legacy umbraco xml configuration in umbracoSettings
/// </summary>
internal class ConfigServerRegistration : IServerRegistration
{
public ConfigServerRegistration(XmlNode n)
{
var webServicesUrl = IOHelper.ResolveUrl(SystemDirectories.WebServices);
var protocol = GlobalSettings.UseSSL ? "https" : "http";
if (n.Attributes.GetNamedItem("forceProtocol") != null && !string.IsNullOrEmpty(n.Attributes.GetNamedItem("forceProtocol").Value))
protocol = n.Attributes.GetNamedItem("forceProtocol").Value;
var domain = XmlHelper.GetNodeValue(n);
if (n.Attributes.GetNamedItem("forcePortnumber") != null && !string.IsNullOrEmpty(n.Attributes.GetNamedItem("forcePortnumber").Value))
domain += string.Format(":{0}", n.Attributes.GetNamedItem("forcePortnumber").Value);
ServerAddress = string.Format("{0}://{1}{2}/cacheRefresher.asmx", protocol, domain, webServicesUrl);
}
public string ServerAddress { get; private set; }
}
}

View File

@@ -0,0 +1,281 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using umbraco.interfaces;
namespace Umbraco.Core.Sync
{
/// <summary>
/// The default server messenger that uses web services to keep servers in sync
/// </summary>
internal class DefaultServerMessenger : IServerMessenger
{
private readonly string _login;
private readonly string _password;
private readonly bool _useDistributedCalls;
/// <summary>
/// Without a username/password all distribuion will be disabled
/// </summary>
internal DefaultServerMessenger()
{
_useDistributedCalls = false;
}
/// <summary>
/// Distribution will be enabled based on the umbraco config setting.
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
internal DefaultServerMessenger(string login, string password)
{
_useDistributedCalls = UmbracoSettings.UseDistributedCalls;
_login = login;
_password = password;
}
public void PerformRefresh<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher,Func<T, int> getNumericId, params T[] instances)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
throw new NotImplementedException();
}
public void PerformRefresh<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
throw new NotImplementedException();
}
public void PerformRemove<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
throw new NotImplementedException();
}
public void PerformRemove(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params int[] numericIds)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
numericIds.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RemoveById, x));
}
public void PerformRefresh(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params int[] numericIds)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
numericIds.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RefreshById, x));
}
public void PerformRefresh(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params Guid[] guidIds)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
guidIds.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RefreshById, x));
}
public void PerformRefreshAll(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher)
{
InvokeDispatchMethod(servers, refresher, MessageType.RefreshAll, null);
}
private void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, object id)
{
if (refresher == null) throw new ArgumentNullException("refresher");
//if we are not, then just invoke the call on the cache refresher
switch (dispatchType)
{
case MessageType.RefreshAll:
refresher.RefreshAll();
break;
case MessageType.RefreshById:
if (id is int)
{
refresher.Refresh((int)id);
}
else if (id is Guid)
{
refresher.Refresh((Guid) id);
}
else
{
throw new InvalidOperationException("The id must be either an int or a Guid");
}
break;
case MessageType.RemoveById:
refresher.Remove((int)id);
break;
}
}
private void InvokeDispatchMethod(
IEnumerable<IServerRegistration> servers,
ICacheRefresher refresher,
MessageType dispatchType,
object id)
{
if (servers == null) throw new ArgumentNullException("servers");
if (refresher == null) throw new ArgumentNullException("refresher");
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
// can definitely not distribute.
if (!_useDistributedCalls || !servers.Any())
{
//if we are not, then just invoke the call on the cache refresher
InvokeMethodOnRefresherInstance(refresher, dispatchType, id);
return;
}
//We are using distributed calls, so lets make them...
try
{
using (var cacheRefresher = new ServerSyncWebServiceClient())
{
var asyncResultsList = new List<IAsyncResult>();
LogStartDispatch();
var nodes = servers;
// Go through each configured node submitting a request asynchronously
foreach (var n in nodes)
{
//set the server address
cacheRefresher.Url = n.ServerAddress;
// Add the returned WaitHandle to the list for later checking
switch (dispatchType)
{
case MessageType.RefreshAll:
asyncResultsList.Add(
cacheRefresher.BeginRefreshAll(
refresher.UniqueIdentifier, _login, _password, null, null));
break;
case MessageType.RefreshById:
IAsyncResult result;
if (id is int)
{
result = cacheRefresher.BeginRefreshById(refresher.UniqueIdentifier, (int) id, _login, _password, null, null);
}
else
{
result = cacheRefresher.BeginRefreshByGuid(refresher.UniqueIdentifier, (Guid)id, _login, _password, null, null);
}
asyncResultsList.Add(result);
break;
case MessageType.RemoveById:
asyncResultsList.Add(
cacheRefresher.BeginRemoveById(
refresher.UniqueIdentifier, (int)id, _login, _password, null, null));
break;
}
}
List<WaitHandle> waitHandlesList;
var asyncResults = GetAsyncResults(asyncResultsList, out waitHandlesList);
var errorCount = 0;
// Once for each WaitHandle that we have, wait for a response and log it
// We're previously submitted all these requests effectively in parallel and will now retrieve responses on a FIFO basis
foreach (var t in asyncResults)
{
var handleIndex = WaitHandle.WaitAny(waitHandlesList.ToArray(), TimeSpan.FromSeconds(15));
try
{
// Find out if the call succeeded
switch (dispatchType)
{
case MessageType.RefreshAll:
cacheRefresher.EndRefreshAll(t);
break;
case MessageType.RefreshById:
if (id is int)
{
cacheRefresher.EndRefreshById(t);
}
else
{
cacheRefresher.EndRefreshByGuid(t);
}
break;
case MessageType.RemoveById:
cacheRefresher.EndRemoveById(t);
break;
}
}
catch (WebException ex)
{
LogDispatchNodeError(ex);
errorCount++;
}
catch (Exception ex)
{
LogDispatchNodeError(ex);
errorCount++;
}
}
LogDispatchBatchResult(errorCount);
}
}
catch (Exception ee)
{
LogDispatchBatchError(ee);
}
}
private IEnumerable<IAsyncResult> GetAsyncResults(List<IAsyncResult> asyncResultsList, out List<WaitHandle> waitHandlesList)
{
var asyncResults = asyncResultsList.ToArray();
waitHandlesList = new List<WaitHandle>();
foreach (var asyncResult in asyncResults)
{
waitHandlesList.Add(asyncResult.AsyncWaitHandle);
}
return asyncResults;
}
private void LogDispatchBatchError(Exception ee)
{
LogHelper.Error<DefaultServerMessenger>("Error refreshing distributed list", ee);
}
private void LogDispatchBatchResult(int errorCount)
{
LogHelper.Debug<DefaultServerMessenger>(string.Format("Distributed server push completed with {0} nodes reporting an error", errorCount == 0 ? "no" : errorCount.ToString(CultureInfo.InvariantCulture)));
}
private void LogDispatchNodeError(Exception ex)
{
LogHelper.Error<DefaultServerMessenger>("Error refreshing a node in the distributed list", ex);
}
private void LogDispatchNodeError(WebException ex)
{
string url = (ex.Response != null) ? ex.Response.ResponseUri.ToString() : "invalid url (responseUri null)";
LogHelper.Error<DefaultServerMessenger>("Error refreshing a node in the distributed list, URI attempted: " + url, ex);
}
private void LogStartDispatch()
{
LogHelper.Info<DefaultServerMessenger>("Submitting calls to distributed servers");
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using umbraco.interfaces;
namespace Umbraco.Core.Sync
{
/// <summary>
/// Defines a server messenger for server sync and distrubuted cache
/// </summary>
internal interface IServerMessenger
{
/// <summary>
/// Performs a sync against all instance objects
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="servers">The servers to sync against</param>
/// <param name="refresher"></param>
/// <param name="getNumericId">A delegate to return the Id for each instance to be used to sync to other servers</param>
/// <param name="instances"></param>
void PerformRefresh<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances);
/// <summary>
/// Performs a sync against all instance objects
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="servers">The servers to sync against</param>
/// <param name="refresher"></param>
/// <param name="getGuidId">A delegate to return the Id for each instance to be used to sync to other servers</param>
/// <param name="instances"></param>
void PerformRefresh<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances);
/// <summary>
/// Removes the cache for the specified items
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="servers"></param>
/// <param name="refresher"></param>
/// <param name="getNumericId">A delegate to return the Id for each instance to be used to sync to other servers</param>
/// <param name="instances"></param>
void PerformRemove<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances);
/// <summary>
/// Removes the cache for the specified items
/// </summary>
/// <param name="servers"></param>
/// <param name="refresher"></param>
/// <param name="numericIds"></param>
void PerformRemove(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params int[] numericIds);
/// <summary>
/// Performs a sync against all Ids
/// </summary>
/// <param name="servers">The servers to sync against</param>
/// <param name="refresher"></param>
/// <param name="numericIds"></param>
void PerformRefresh(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params int[] numericIds);
/// <summary>
/// Performs a sync against all Ids
/// </summary>
/// <param name="servers">The servers to sync against</param>
/// <param name="refresher"></param>
/// <param name="guidIds"></param>
void PerformRefresh(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params Guid[] guidIds);
/// <summary>
/// Performs entire cache refresh for a specified refresher
/// </summary>
/// <param name="servers"></param>
/// <param name="refresher"></param>
void PerformRefreshAll(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher);
}
}

View File

@@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace Umbraco.Core.Sync
{
/// <summary>
/// An interface to expose a list of server registrations for server syncing
/// </summary>
internal interface IServerRegistrar
{
IEnumerable<IServerRegistration> Registrations { get; }
}
}

View File

@@ -0,0 +1,10 @@
namespace Umbraco.Core.Sync
{
/// <summary>
/// An interface exposing a server address to use for server syncing
/// </summary>
internal interface IServerRegistration
{
string ServerAddress { get; }
}
}

View File

@@ -0,0 +1,12 @@
namespace Umbraco.Core.Sync
{
/// <summary>
/// The message type to be used for syncing across servers
/// </summary>
internal enum MessageType
{
RefreshAll,
RefreshById,
RemoveById
}
}

View File

@@ -0,0 +1,29 @@
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Sync
{
/// <summary>
/// A resolver to return the currently registered IServerMessenger object
/// </summary>
internal class ServerMessengerResolver : SingleObjectResolverBase<ServerMessengerResolver, IServerMessenger>
{
internal ServerMessengerResolver(IServerMessenger factory)
: base(factory)
{
}
/// <summary>
/// Can be used at runtime to set a custom IServerMessenger at app startup
/// </summary>
/// <param name="serverMessenger"></param>
public void SetServerMessenger(IServerMessenger serverMessenger)
{
Value = serverMessenger;
}
public IServerMessenger Messenger
{
get { return Value; }
}
}
}

View File

@@ -0,0 +1,31 @@
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Sync
{
/// <summary>
/// The resolver to return the currently registered IServerRegistrar object
/// </summary>
internal class ServerRegistrarResolver : SingleObjectResolverBase<ServerRegistrarResolver, IServerRegistrar>
{
internal ServerRegistrarResolver(IServerRegistrar factory)
: base(factory)
{
}
/// <summary>
/// Can be used at runtime to set a custom IServerRegistrar at app startup
/// </summary>
/// <param name="serverRegistrar"></param>
public void SetServerRegistrar(IServerRegistrar serverRegistrar)
{
Value = serverRegistrar;
}
public IServerRegistrar Registrar
{
get { return Value; }
}
}
}

View File

@@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Umbraco.Core.Configuration;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Sync
{
internal class ConfigServerRegistrar : IServerRegistrar
{
private List<IServerRegistration> _addresses;
public IEnumerable<IServerRegistration> Registrations
{
get
{
if (_addresses == null)
{
_addresses = new List<IServerRegistration>();
var nodes = UmbracoSettings.DistributionServers.SelectNodes("./server");
foreach (XmlNode n in nodes)
{
_addresses.Add(new ConfigServerRegistration(n));
}
}
return _addresses;
}
}
}
internal interface IServerRegistration
{
string ServerAddress { get; }
}
internal class ConfigServerRegistration : IServerRegistration
{
public ConfigServerRegistration(XmlNode n)
{
var protocol = GlobalSettings.UseSSL ? "https" : "http";
if (n.Attributes.GetNamedItem("forceProtocol") != null && !string.IsNullOrEmpty(n.Attributes.GetNamedItem("forceProtocol").Value))
protocol = n.Attributes.GetNamedItem("forceProtocol").Value;
var domain = XmlHelper.GetNodeValue(n);
if (n.Attributes.GetNamedItem("forcePortnumber") != null && !string.IsNullOrEmpty(n.Attributes.GetNamedItem("forcePortnumber").Value))
domain += string.Format(":{0}", n.Attributes.GetNamedItem("forcePortnumber").Value);
ServerAddress = string.Format("{0}://{1}{2}", protocol, domain);
}
public string ServerAddress { get; private set; }
}
internal interface IServerRegistrar
{
IEnumerable<IServerRegistration> Registrations { get; }
}
internal class ServerRegistrarResolver : SingleObjectResolverBase<ServerRegistrarResolver, IServerRegistrar>
{
internal ServerRegistrarResolver(IServerRegistrar factory)
: base(factory)
{
}
public IServerRegistrar Registrar
{
get { return Value; }
}
}
}

View File

@@ -0,0 +1,154 @@
using System.Web.Services;
using Umbraco.Core.IO;
namespace Umbraco.Core.Sync
{
/// <summary>
/// The client Soap service for making distrubuted cache calls between servers
/// </summary>
[WebServiceBinding(Name = "CacheRefresherSoap", Namespace = "http://umbraco.org/webservices/")]
internal class ServerSyncWebServiceClient : System.Web.Services.Protocols.SoapHttpClientProtocol
{
/// <remarks/>
public ServerSyncWebServiceClient()
{
// only set the url if the httpcontext is present, else it's set by the cache dispatcher methods (when using distributed calls)
if (System.Web.HttpContext.Current != null)
this.Url = "http://" + System.Web.HttpContext.Current.Request.ServerVariables["SERVER_NAME"] + IOHelper.ResolveUrl(SystemDirectories.WebServices) + "/cacheRefresher.asmx";
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RefreshAll", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void RefreshAll(System.Guid uniqueIdentifier, string Login, string Password)
{
this.Invoke("RefreshAll", new object[] {
uniqueIdentifier,
Login,
Password});
}
/// <remarks/>
public System.IAsyncResult BeginRefreshAll(System.Guid uniqueIdentifier, string Login, string Password, System.AsyncCallback callback, object asyncState)
{
return this.BeginInvoke("RefreshAll", new object[] {
uniqueIdentifier,
Login,
Password}, callback, asyncState);
}
/// <remarks/>
public void EndRefreshAll(System.IAsyncResult asyncResult)
{
this.EndInvoke(asyncResult);
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RefreshByGuid", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void RefreshByGuid(System.Guid uniqueIdentifier, System.Guid Id, string Login, string Password)
{
this.Invoke("RefreshByGuid", new object[] {
uniqueIdentifier,
Id,
Login,
Password});
}
/// <remarks/>
public System.IAsyncResult BeginRefreshByGuid(System.Guid uniqueIdentifier, System.Guid Id, string Login, string Password, System.AsyncCallback callback, object asyncState)
{
return this.BeginInvoke("RefreshByGuid", new object[] {
uniqueIdentifier,
Id,
Login,
Password}, callback, asyncState);
}
/// <remarks/>
public void EndRefreshByGuid(System.IAsyncResult asyncResult)
{
this.EndInvoke(asyncResult);
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RefreshById", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void RefreshById(System.Guid uniqueIdentifier, int Id, string Login, string Password)
{
this.Invoke("RefreshById", new object[] {
uniqueIdentifier,
Id,
Login,
Password});
}
/// <remarks/>
public System.IAsyncResult BeginRefreshById(System.Guid uniqueIdentifier, int Id, string Login, string Password, System.AsyncCallback callback, object asyncState)
{
return this.BeginInvoke("RefreshById", new object[] {
uniqueIdentifier,
Id,
Login,
Password}, callback, asyncState);
}
/// <remarks/>
public void EndRefreshById(System.IAsyncResult asyncResult)
{
this.EndInvoke(asyncResult);
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RemoveById", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void RemoveById(System.Guid uniqueIdentifier, int Id, string Login, string Password)
{
this.Invoke("RemoveById", new object[] {
uniqueIdentifier,
Id,
Login,
Password});
}
/// <remarks/>
public System.IAsyncResult BeginRemoveById(System.Guid uniqueIdentifier, int Id, string Login, string Password, System.AsyncCallback callback, object asyncState)
{
return this.BeginInvoke("RemoveById", new object[] {
uniqueIdentifier,
Id,
Login,
Password}, callback, asyncState);
}
/// <remarks/>
public void EndRemoveById(System.IAsyncResult asyncResult)
{
this.EndInvoke(asyncResult);
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/GetRefreshers", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public System.Xml.XmlNode GetRefreshers(string Login, string Password)
{
object[] results = this.Invoke("GetRefreshers", new object[] {
Login,
Password});
return ((System.Xml.XmlNode)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginGetRefreshers(string Login, string Password, System.AsyncCallback callback, object asyncState)
{
return this.BeginInvoke("GetRefreshers", new object[] {
Login,
Password}, callback, asyncState);
}
/// <remarks/>
public System.Xml.XmlNode EndGetRefreshers(System.IAsyncResult asyncResult)
{
object[] results = this.EndInvoke(asyncResult);
return ((System.Xml.XmlNode)(results[0]));
}
}
}

View File

@@ -73,6 +73,7 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.20715.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Services" />
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll</HintPath>
@@ -667,7 +668,18 @@
<Compile Include="Services\MediaService.cs" />
<Compile Include="Services\ServiceContext.cs" />
<Compile Include="Services\UserService.cs" />
<Compile Include="Sync\ServerSync.cs" />
<Compile Include="Sync\DefaultServerMessenger.cs" />
<Compile Include="Sync\ServerSyncWebServiceClient.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Sync\ConfigServerRegistration.cs" />
<Compile Include="Sync\IServerMessenger.cs" />
<Compile Include="Sync\IServerRegistrar.cs" />
<Compile Include="Sync\IServerRegistration.cs" />
<Compile Include="Sync\MessageType.cs" />
<Compile Include="Sync\ServerMessengerResolver.cs" />
<Compile Include="Sync\ServerRegistrarResolver.cs" />
<Compile Include="Sync\ConfigServerRegistrar.cs" />
<Compile Include="TypeExtensions.cs" />
<Compile Include="ReadLock.cs" />
<Compile Include="TypeFinder.cs" />