When deploying WCF security, for a Smart Client Service Factory (SCSF) solution the documentation encourage the developer to deploy an EndPointCatalog. I found this to be a lot of coding when all I wanted to do was simply pass a username and password to the proxy so that it would call the service with the correct credentials.
My workaround is to not create a “EndPoint” section in your client app.config but instead override the GetOnlineProxy Method in the Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory class.
Assuming you have a Service Agent (or similar) Module in your SCSF solution create a new class that inherits the WCFProxyFactory class mentioned above.
using System;
using System.Net;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.Practices.SmartClient.EndpointCatalog;
using Microsoft.Practices.SmartClient.DisconnectedAgent;
namespace MyNamespace
{
public class WCFProxyFactory : Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory
where TChannel : class
{
public override object GetOnlineProxy(Request request, string networkName)
{
Guard.ArgumentNotNull(request, "request");
ClientBase proxy = (ClientBase)Activator.CreateInstance(request.OnlineProxyType);
// Set the credentials
ClientCredentials clientCredentials = proxy.ClientCredentials;
clientCredentials.UserName.UserName = "myusername";
clientCredentials.UserName.Password = "mypassword";
return proxy;
}
}
}
You will need to create a Guard Class which you can simply copy from the source code that comes with SCSF (i.e. Microsoft.Practices.SmartClient.DisconnectedAgent.Guard) and then your solution should successfully compile.
Lastly you need to change the default offlinebehavoir of your Agent which was generated by the Disconnected Service Agent. Look for the GetAgentDefaultBehavior method
public static OfflineBehavior GetAgentDefaultBehavior()
{
OfflineBehavior behavior = new OfflineBehavior();
behavior.MaxRetries = 3;
behavior.Stamps = 1;
behavior.Expiration = DateTime.Now + new TimeSpan(1, 0, 0, 0);
// behavior.ProxyFactoryType = typeof(Microsoft.Practices.SmartClient.DisconnectedAgent.WCFProxyFactory);
behavior.ProxyFactoryType = typeof(MyNamespace.WCFProxyFactory);
return behavior;
}
Compile and start your application and it will now pass the credentials on to your service.
There are instances where on closing a Work Item View, you would also like to dispose of the footprint. Here is how it done.
Change the OnCloseView of the Presenter as follows:
#region Closing the View
/// <summary>
/// Close the view
/// </summary>
public void OnCloseView()
{
base.CloseView();
// If this presenter has created any workspaces
// be sure to remove them first.
// e.g. if (WorkItem.Workspaces.Contains(WorkSpaceName))
// WorkItem.Workspaces.Remove(WorkItem.Workspaces[WorkSpaceName]);
// Remove the View from the SmartParts Collection
this.WorkItem.SmartParts.Remove(View);
// As we are closing and re-creating this view
// several times, we need to Dispose the view.
if (View is IDisposable)
((IDisposable)View).Dispose();
}
#endregion
Open the code behind the that the presenter controls and add the following Code snippet.
#region Closing the View
void ParentForm_FormClosed(object sender, FormClosedEventArgs e)
{
_presenter.OnCloseView();
}
#endregion
Finally on the same page change the OnLoad Method so it reads:
protected override void OnLoad(EventArgs e)
{
_presenter.OnViewReady();
base.OnLoad(e);
// Capture the Form Close Event, because we want to destroy
// the view on Closing the form
this.ParentForm.FormClosed += new FormClosedEventHandler(ParentForm_FormClosed);
}
And that’s it. Each time you close the view it will be destroyed and the memory released.