Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Thursday, September 25, 2014

Designing Your Application to be Unit Testable

The easiest way to structure any application so that it is unit testable is to break up the main sections of the work being down into some basic pieces.  These are:

  1. Get your data
  2. Do work with your data
  3. Commit changes to your data
With this basic application structure you can now separate the pulling and processing of the data.  You are in complete control of that data being used by the processing code and can manipulated it as you see fit.  It is the ideal structure for unit testable code.  

public class MyMainWorker
{
    public void RunWorker()
    {
        // Optional begin your transaction here
        DataSet ds = GetData();
        object o = Execute(ds);
        // Begin your transaction
        SaveData(ds);
        // Commit your transaction
    }

    private void SaveData(DataSet ds)
    {
        throw new NotImplementedException();
    }

    private object Execute(DataSet ds)
    {
        throw new NotImplementedException();
    }

    private DataSet GetData()
    {
        throw new NotImplementedException();
    }
}

Wednesday, September 24, 2014

?? Operator is great for defaulting objects

If you need to default an object, an easy way to do this is with the null-coalescing operator.  In this example I need to default MyTempClass if I cannot pull it from another location.

using System;

namespace Tips
{
    public class NullCoalescingOperator
    {
        public void RunTip()
        {
            MyTempClass myTempClass = null;
            MyTempClass myOtherTempClass = new MyTempClass()
            {
                MyProperty = 1
            };
            MyTempClass x = myTempClass ?? myOtherTempClass;
            Console.WriteLine("{0}", x.MyProperty);
        }
    }

    public class MyTempClass
    {
        public int MyProperty { get; set; }
    }
}

Tuesday, September 23, 2014

Building File and Directory Paths

I see directory and file concatenation done with string append all too often. There are built in .Net libraries that help you do this so much easier. When you are working with file and directory paths, use System.IO.Path.Combine().
using System.IO;

namespace Tips
{
    class Program
    {
        static void Main(string[] args)
        {
            Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonPictures),
                "First SubDir",
                "Second Subdir",
                "MyFile.jpg");
        }
    }
}

Wednesday, July 27, 2011

C# Esri Shapefile Reader

I've been trying to populate a Sql Server database with shapefile information from the National Weather Service in an automated fashion, I finally found a tool that helps me do just that.  It's called ESRI Shapefile Reader from CodePlex.

I had first tried Shape2Sql, but it is closed source and for some reason would not import when I had Create Spatial Index checked.  It would run through all the rows in the Shapefile, but no table or rows would be created.  So I pre-created the table, still no rows were created.  That was with the GUI, so when I tried it as a command line tool, again, it would not import the shape file because there is no command line option to disable creating the spatial index.  I don't know where the problem lies, and Shape2Sql appears to be a good tool.  For me, it works great for doing the import by hand, which is fine for data that doesn't change often, but I need automation and if the command line doesn't work, I'm not about to try and manipulate mouse clicks on a GUI from a windows service....

I found various other tools, but they require subscription $, and I am trying to do this with a minimal budget since this is being used for a hobby.

Anyways, I needed to load this data into SqlServer Express.  Using Shape2Sql, it took about 14 minutes for my particular datafile.  I hate waiting and I need to automate this thing, so I decided to use ESRI Shapefile Reader to import a National Weather Service Precipitation file (which can be found at http://water.weather.gov/precip/download.php) and only grab the columns I'm interested in.  Doing this, and threading the import, it now only takes 45 seconds to import the data.  Best of all, I met my goal of doing this in an automated fashion.  Here's my code snippet that shows you how I did this, if you have any questions, just post it.



        public static void CreateWorkForThreads()
        {
            DataSet ds = CreateNewDataSet();
            DataTable dtNWS = ds.Tables[0];

            // Parse the shapefile into a DataTable, grabbing the columns we are interested in
            using (Shapefile shapefile = new Shapefile(Path.Combine(weatherFileDir, "nws_precip_1day_observed_" + dateToLoad.ToString("yyyyMMdd") + ".shp")))
            {
                foreach (Shape shape in shapefile)
                {
                    string[] metadataNames = shape.GetMetadataNames();
                    decimal lat = 0m;
                    decimal lon = 0m;
                    decimal globvalue = 0m;

                    if (metadataNames != null)
                    {
                        foreach (string metadataName in metadataNames)
                        {
                            if (metadataName == "lat")
                                lat = decimal.Parse(shape.GetMetadata(metadataName));
                            else if (metadataName == "lon")
                                lon = decimal.Parse(shape.GetMetadata(metadataName));
                            else if (metadataName == "globvalue")
                                globvalue = decimal.Parse(shape.GetMetadata(metadataName));
                        }
                    }

                    DataRow drNWS = dtNWS.NewRow();
                    drNWS["lat"] = lat;
                    drNWS["lon"] = lon;
                    drNWS["globalvalue"] = globvalue;
                    drNWS["precipDate"] = dateToLoad;
                    drNWS["XAxis"] = Math.Cos(ConvertDegreesToRadians((double)lat)) * Math.Cos(ConvertDegreesToRadians((double)lon));
                    drNWS["YAxis"] = Math.Cos(ConvertDegreesToRadians((double)lat)) * Math.Sin(ConvertDegreesToRadians((double)lon));;
                    drNWS["ZAxis"] = Math.Sin(ConvertDegreesToRadians((double)lat));
                    dtNWS.Rows.Add(drNWS);
                }
            }

            List; listOfDataSetsForThreads = new List();
            DataSet dsCur = CreateNewDataSet();

            // Create a list of datasets, each containing the rows the thread will import
            foreach (DataRow dr in dtNWS.Rows)
            {
                if (dsCur.Tables[0].Rows.Count % 3000 == 0)
                {
                    listOfDataSetsForThreads.Add(dsCur);
                    dsCur = CreateNewDataSet();
                }

                dsCur.Tables[0].ImportRow(dr);
            }

            if (dsCur.Tables[0].Rows.Count > 0)
                listOfDataSetsForThreads.Add(dsCur);

            // Spawn off the threads to import our datasets in parallel
            foreach (DataSet dsThreadWork in listOfDataSetsForThreads)
            {
                WaitCallback wcb = new WaitCallback(ImportDataSet);
                ThreadPool.QueueUserWorkItem(wcb, dsThreadWork);
            }
        }

        public static void ImportDataSet(object o)
        {
            DataSet ds = (DataSet)o;
            using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["myDb"]))
            {
                con.Open();

                try
                {
                    SqlDataAdapter da = new SqlDataAdapter("select top 1 * from nws_precip_history", con);
                    SqlCommandBuilder bldr = new SqlCommandBuilder(da);

                    da.InsertCommand = bldr.GetInsertCommand();
                    da.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
                    da.UpdateBatchSize = 500;
                    da.Update(ds, "nws_precip_history");
                }
                finally
                {
                    if (con.State == ConnectionState.Open)
                        con.Close();
                }
            }

        }

        public static DataSet CreateNewDataSet()
        {
            DataSet dsTemp = new DataSet();
            DataTable dtNWSTemp = new DataTable("nws_precip_history");
            dtNWSTemp.Columns.Add("lat", typeof(decimal));
            dtNWSTemp.Columns.Add("lon", typeof(decimal));
            dtNWSTemp.Columns.Add("globalvalue", typeof(decimal));
            dtNWSTemp.Columns.Add("precipDate", typeof(DateTime));
            dtNWSTemp.Columns.Add("XAxis", typeof(float));
            dtNWSTemp.Columns.Add("YAxis", typeof(float));
            dtNWSTemp.Columns.Add("ZAxis", typeof(float));
            dsTemp.Tables.Add(dtNWSTemp);

            return dsTemp;
        }

        public static double ConvertDegreesToRadians(double degrees)
        {
            double radians = (Math.PI / 180) * degrees;
            return (radians);
        }


Wednesday, March 30, 2011

Index (zero based) must be greater than or equal to zero and less than the size of the argument list

Problem:
System.FormatException was unhandled by user code
  Message=Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
  Source=mscorlib
  StackTrace:
       at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args)
       at System.String.Format(IFormatProvider provider, String format, Object[] args)
       at System.String.Format(String format, Object arg0)
       at MultiThreadedDbSeeder.Program.<Main>b__0(Int32 i) in C:\xxxx\Program.cs:line 22
       at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.b__c()
  InnerException:

Offending Line:
SqlCommand cmd = new SqlCommand(string.Format(@"insert into table_1 (vch_value) values('{1}')", "the value of i is " + i));

Solution:
Don’t forget that string.Format uses a zero based index.
Fixed Code:
SqlCommand cmd = new SqlCommand(string.Format(@"insert into table_1 (vch_value) values('{0}')", "the value of i is " + i));

Saturday, March 26, 2011

Quartz.ObjectAlreadyExistsException: Unable to store Job with name: '' and group: 'DEFAULT', because one already exists with this identification.

Problem:
Exception Caught: Quartz.ObjectAlreadyExistsException: Unable to store Job with name: 'updateMyStuff' and group: 'DEFAULT', because one already exists with this identification.


Code:
                 // construct job info for every 10 seconds
                JobDetail = jobDetail = new JobDetail("updateMyStuff", null, typeof(UpdateMyOneMethod));
                trig = new CronTrigger();
                trig.CronExpression = new CronExpression("0/10 * * * * ?");
                trig.Name = " updateStuff ";
                sched.ScheduleJob(jobDetail, trig);

                // job for every day 12:00 am
                jobDetail = new JobDetail("updateMyStuff", null, typeof(UpdateMyOtherMethod));
                trig = new CronTrigger();
                trig.CronExpression = new CronExpression("0 0 0 * * ?");
                trig.Name = "updateStuff";
                sched.ScheduleJob(jobDetail, trig);



Solution:
I was clearly very tired and not paying attention and made a miserable copy/paste error.  Make sure the JobDetail has a unique name and same with the trigger!  Fixed Code, changes bolded:

                 // construct job info for every 10 seconds
                JobDetail = jobDetail = new JobDetail("updateMyStuff", null, typeof(UpdateMyOneMethod));
                trig = new CronTrigger();
                trig.CronExpression = new CronExpression("0/10 * * * * ?");
                trig.Name = " updateStuff ";
                sched.ScheduleJob(jobDetail, trig);

                // job for every day 12:00 am
                jobDetail = new JobDetail("updateMyOtherStuff", null, typeof(UpdateMyOtherMethod));
                trig = new CronTrigger();
                trig.CronExpression = new CronExpression("0 0 0 * * ?");
                trig.Name = "updateOtherStuff";
                sched.ScheduleJob(jobDetail, trig);



Saturday, March 19, 2011

The type or namespace name 'xxxx' does not exist in the namespace 'yyyy' (are you missing an assembly reference?)

Problem:
Error    1          The type or namespace name 'xxxx' does not exist in the namespace 'yyyy' (are you missing an assembly reference?)
Screenshot:

My environment: Visual Studio 2010, .Net 4.0.   Two projects involved, 1 is a dll, other is a console app.

You know your reference is correct, but you still get that reference error.  Your using clause fails, too.
Screenshot:
 

Solution:
In this case, my console app had the Target Framework in the project properties set to .NET Framework 4 Client Profile, the dll project had it set to .NET Framework 4.  I changed the console app to use .NET Framework 4, and everything built fine.

Console App Project properties before:

Console App Project properties after:


Saturday, March 5, 2011

The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.

Problem:

Server Error in '/' Application.


The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentException: The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.

Source Error: 
 
Line 32:         /// Initializes a new xxxxEntities object using the connection string found in the 'xxxxEntities' section of the application configuration file.
Line 33:         /// 
Line 34:         public xxxxEntities() : base("name=xxxxEntities", "xxxxEntities")
Line 35:         {
Line 36:             this.ContextOptions.LazyLoadingEnabled = true;

Source File: C:\Users\xxxx\Documents\Visual Studio 2010\Projects\xxxx.Designer.cs    Line: 34 

Stack Trace: 
 
[ArgumentException: The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.]
   System.Data.EntityClient.EntityConnection.ChangeConnectionString(String newConnectionString) +8080056
   System.Data.EntityClient.EntityConnection..ctor(String connectionString) +81
   System.Data.Objects.ObjectContext.CreateEntityConnection(String connectionString) +42
   System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName) +16
   xxxx..ctor() in C:\Users\xxxxx.cs:34
   xxxx(Int32 id) in C:\Users\xxx.cs:25
   xxxx() in C:\Users\xxxx\Documents\Visual Studio 2010\Projects\xxxxDal.cs:36
   xxxx() in C:\Users\xxxx\Documents\Visual Studio 2010\Projects\xxxx.cs:13
   xxxx(Object sender, EventArgs e) in C:\Users\xxxxaspx.cs:145
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563



Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1


Solution:
Add the entity connection string to the web.config file in the appropriate project.

Failed to start monitoring changes to 'path' because access is denied.

Problem:
Brought up a web page and was presented with this error:

Server Error in '/' Application.


Failed to start monitoring changes to 'C:\Users\xxxx\AppData\Local\Temp\Temporary ASP.NET Files\root\b6230deb\7677a327\hash\hash.web' because access is denied.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Failed to start monitoring changes to 'C:\Users\xxxx\AppData\Local\Temp\Temporary ASP.NET Files\root\b6230deb\7677a327\hash\hash.web' because access is denied.

Source Error: 
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 
 
[HttpException (0x80070005): Failed to start monitoring changes to 'C:\Users\xxxx\AppData\Local\Temp\Temporary ASP.NET Files\root\b6230deb\7677a327\hash\hash.web' because access is denied.]
   System.Web.DirectoryMonitor.AddFileMonitor(String file) +8805891
   System.Web.DirectoryMonitor.StartMonitoringFileWithAssert(String file, FileChangeEventHandler callback, String alias) +94
   System.Web.FileChangesMonitor.StartMonitoringFile(String alias, FileChangeEventHandler callback) +340
   System.Web.Compilation.BuildManager.CheckTopLevelFilesUpToDate2(StandardDiskBuildResultCache diskCache) +790
   System.Web.Compilation.BuildManager.CheckTopLevelFilesUpToDate(StandardDiskBuildResultCache diskCache) +55
   System.Web.Compilation.BuildManager.RegularAppRuntimeModeInitialize() +174
   System.Web.Compilation.BuildManager.Initialize() +261
   System.Web.Compilation.BuildManager.InitializeBuildManager() +246
   System.Web.HttpRuntime.HostingInit(HostingEnvironmentFlags hostingFlags, PolicyLevel policyLevel, Exception appDomainCreationException) +350
 
[HttpException (0x80004005): Failed to start monitoring changes to 'C:\Users\xxxx\AppData\Local\Temp\Temporary ASP.NET Files\root\b6230deb\7677a327\hash\hash.web' because access is denied.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8950644
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97
   System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +258



Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1


Solution:
First, I had to close Visual Studio 2010, then I deleted c:\Users\xxxx\AppData\ocal\Temp\Temporary ASP.NET Files.
Reopened Visual Studio and ran it again in debug mode, worked fine.

Monday, February 28, 2011

MVC3 - Server Error in '/' Application. The resource cannot be found.



Problem:
MVC3 – You added your HttpPost method in your Controller, and you get:

Server Error in '/' Application.


The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

Requested URL: /Movies/Edit/1

Code:
        [HttpPost]
        public ActionResult Edit(Movie model)
        {
            try
            {
                var movie = db.Movies.Find(model.ID);

                UpdateModel(movie);
                db.SaveChanges();
                return RedirectToAction("Details", new {id=model.ID});
            }
            catch (Exception)
            {

                ModelState.AddModelError("", "Edit Failure, see inner exception");
            }

            return View(model);
        }



Solution:
You forgot to add the Get method to the Controller class:
Code:
        public ActionResult Edit(int id)
        {
            var movie = db.Movies.Find(id);
            if (movie == null)
                RedirectToAction("Index");
           
            return View(movie);
        }


System.InvalidOperationException was unhandled by user code The model backing the 'SomeContext' context has changed since the database was created

Problem:
Received the following exception when adding a field to an Entity class:


System.InvalidOperationException was unhandled by user code
  Message=The model backing the 'MovieDBContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
  Source=EntityFramework
Full Stack Trace at the end.

Code the exception occurred:
        MovieDBContext db = new MovieDBContext();

        public ActionResult Index()
        {
            var movies = from m in db.Movies
                         where m.ReleaseDate > new DateTime(1984, 6, 1)
                         select m;

            return View(movies.ToList());
        }


Solution:
Update the table in Sql Server to have the additional column you added to your entitiy class.



Full Stack Trace:
  StackTrace:
       at System.Data.Entity.Database.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context)
       at System.Data.Entity.Database.DbDatabase.<>c__DisplayClass8.b__5()
       at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
       at System.Data.Entity.Database.DbDatabase.Initialize(Boolean force)
       at System.Data.Entity.Internal.InternalContext.Initialize()
       at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
       at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
       at System.Data.Entity.Internal.Linq.InternalSet`1.get_Provider()
       at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
       at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)
       at MvcMovie.Controllers.MoviesController.Index() in xxxx\visual studio 2010\Projects\MovieApp\MvcMovie\Controllers\MoviesController.cs:line 16
       at lambda_method(Closure , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.b__12()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)





Saturday, February 26, 2011

System.ServiceModel.CommunicationException was unhandled Exception

Problem:
Message=The underlying connection was closed: The connection was closed unexpectedly.

I was making a WCF client/service, I ran it for the first time and got that exception.  So, my WCF service had an OperationContract to return a DataTable like so:


[ServiceContract]
    public interface IUserService
    {
        [OperationContract]
        DataTable GetApprovedUser();
    }

And it was implemented like this:


public DataTable GetApprovedUser()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("UserId", typeof (Int64));
            dt.Columns.Add("IsApproved", typeof (bool));

            DataRow newUser = dt.NewRow();
            newUser["UserId"] = 1000;
            newUser["IsApproved"] = true;
            dt.Rows.Add(newUser);
            newUser = dt.NewRow();
            newUser["UserId"] = 1001;
            newUser["IsApproved"] = true;
            dt.Rows.Add(newUser);
            newUser = dt.NewRow();
            newUser["UserId"] = 1002;
            newUser["IsApproved"] = false;
            dt.Rows.Add(newUser);
            newUser = dt.NewRow();
            newUser["UserId"] = 1003;
            newUser["IsApproved"] = true;
            dt.Rows.Add(newUser);

            return dt;
        }


And my Client:
            ServiceReference1.UserServiceClient proxy = new ServiceReference1.UserServiceClient();
            string User = proxy.Authenticate("theuser", "somecrypt");
            foreach(DataRow userRow in proxy.GetApprovedUser().Tables[0].Rows)
            {
                Console.WriteLine(string.Format("User: {0}, IsApproved: ", userRow["UserId"], userRow["IsApproved"]));
            }



Solution:
Turns out that DataTables are not serializable, so I tried wrapping the DataTable in a DataSet like this:

Interface:
    [ServiceContract]
    public interface IUserService
    {
        [OperationContract]
        void DoWork();

        [OperationContract]
        string Authenticate(string userName, string aCryptKey);

        [OperationContract]
        DataSet GetApprovedUser();
    }



Implementation:


        public DataSet GetApprovedUser()
        {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable();
            ds.Tables.Add(dt);
            dt.Columns.Add("UserId", typeof (Int64));
            dt.Columns.Add("IsApproved", typeof (bool));

            DataRow newUser = dt.NewRow();
            newUser["UserId"] = 1000;
            newUser["IsApproved"] = true;
            dt.Rows.Add(newUser);
            newUser = dt.NewRow();
            newUser["UserId"] = 1001;
            newUser["IsApproved"] = true;
            dt.Rows.Add(newUser);
            newUser = dt.NewRow();
            newUser["UserId"] = 1002;
            newUser["IsApproved"] = false;
            dt.Rows.Add(newUser);
            newUser = dt.NewRow();
            newUser["UserId"] = 1003;
            newUser["IsApproved"] = true;
            dt.Rows.Add(newUser);

            return ds;
        }

And that fixed it.



For those interested, here was the full stack trace:


  Message=The underlying connection was closed: The connection was closed unexpectedly.
  Source=mscorlib
  StackTrace:
    Server stack trace:
       at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
       at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]:
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at WCRTestClient.ServiceReference1.IUserService.GetApprovedUser()
       at WCRTestClient.ServiceReference1.UserServiceClient.GetApprovedUser() in xxxx\visual studio 2010\Projects\Test WCF\WCRTestClient\Service References\ServiceReference1\Reference.cs:line 64
       at WCRTestClient.Program.Main(String[] args) in xxxx\visual studio 2010\Projects\Test WCF\WCRTestClient\Program.cs:line 15
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Net.WebException
       Message=The underlying connection was closed: The connection was closed unexpectedly.
       Source=System
       StackTrace:
            at System.Net.HttpWebRequest.GetResponse()
            at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)