locked
WCF DataService throws ConnectionString initialization exception on insert RRS feed

  • Question

  • My WCF Data Service works great when I fetch data from it. When I try to insert new data, I get the following exception:

    The ConnectionString property has not been initialized

    The only thing I modified is to use my partial class that tells to use the connection string name:

     MyExtEntities(string connectionString) : base(connectionString) 
    { ... }

    And I overrode the CreateDataSource, so always have the proper context:

    protected override MyExtEntities CreateDataSource()
    {
        MyExtEntities entities = null;
        try
        {
            entities = new MyExtEntities ("name=MyExtEntities");
            ...
            return entities;

    And you can believe, the config file contains that key:

    add name="MyExtEntities " connectionString="metadata=res://*...

    The stack shows that the core system is running, nothing from my methods:

    System.Data.EntityClient.EntityConnection.Open() 
     at: System.Data.Objects.ObjectContext.EnsureConnection() 
     at: System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
    
    at: System.Data.Entity.Internal.InternalContext.SaveChanges() 
    at: System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
    at: System.Data.Entity.DbContext.SaveChanges() 
    at: lambda_method(Closure , Object ) 
    at: System.Data.Services.Providers.DbContextHelper.<>c_DisplayClass4.b_0() 
    at: System.Data.Services.Providers.ObjectContextServiceProvider.SaveContextChanges() 
    at: System.Data.Services.Providers.ObjectContextServiceProvider.SaveChanges() 
    at: System.Data.Services.Providers.EntityFrameworkDataServiceProvider.SaveChanges() 
    at: System.Data.Services.DataService1.HandleNonBatchRequest(RequestDescription description 
    at: System.Data.Services.DataService1.HandleRequest()

    I already added this to OnStartProcessingRequest:

    protected override void OnStartProcessingRequest(ProcessRequestArgs args)
    {
        if (this.CurrentDataSource == null)
            this.CreateDataSource();
        base.OnStartProcessingRequest(args);
    }
    I debugged the partial class of my Context, and whenever the CreateDataSource was hit, ConnectionString was never null or empty. What context is used on insert if the only one I overrode is always initialized?
    It's really strange that the fetching works and it uses the same connection... What should I check?





    Andris

    Friday, July 19, 2013 9:59 AM

Answers

  • Well, to fix the unexplainable, here is a way.
    For an unknown reason, when the CreateDataSource method creates a new DbContext instance, it doesn't always have a Connection String. To prevent this from happenning, I created a DbContext instance along with the DataService class to ensure that I have a proper instance:

    public class InformationDataService : DataService<InformationEntities>
      {
        private InformationEntities context = new InformationEntities("name=InformationEntities");

    After that I modified the overriden CreateDataSource to always return the initially created (and hopefully properly working) DbContext:

    protected override InformationEntities CreateDataSource()
        {
          if (context == null)
                    return new InformationEntities("name=InformationEntities");
          return context;
        }

    After these modifications, the error is gone.


    Andr&amp;#225;s

    • Marked as answer by nologin Wednesday, July 24, 2013 1:48 PM
    Wednesday, July 24, 2013 1:48 PM

All replies

  • I debugged the OnStartProcessingRequest and set a break point with the condition:

    args.OperationContext.RequestMethod=="POST"

    I also set this.CreateDataSource(); so it creates the DataSource even if the request method is POST. The CreateDataSource was hit and after a few seconds later I got my exception stating that the ConnectionString is null.

    It is clear that a different context is used to host the insert and update methods. Can you tell me where I can set the INSERT context?


    Andr&amp;#225;s

    Sunday, July 21, 2013 7:35 PM
  • For INSERTING I found a WORKAROUND:

    public override int SaveChanges()
        {
          if (string.IsNullOrEmpty(this.Database.Connection.ConnectionString))
            this.Database.Connection.ConnectionString = savedConnectionString;
          return base.SaveChanges();
        }

    The connection string is null on INSERT. I thought I was done but I tried update. It never hits the SaveChanges, and the exception is the same.

    I checked the URI that was sent to my service: http://*/myservice/myservice.svc/Informations(guid'3091f861-0367-4a0a-9b9d-46002e5c2fc5') It uses GET and tries to get the record to overwrite. It also throws the same exception (connection string is null).

    What is the DEFAULT CONTEXT that is used? EF clearly not using my connection string that was used by the Service Operations that fetch me the data.

    In the OnStartProcessingRequest method the CreateDataSource was called first, then base.OnStartProcessingRequest and then comes the exception. What should I set?


    Andr&amp;#225;s

    Tuesday, July 23, 2013 1:22 PM
  • Well, to fix the unexplainable, here is a way.
    For an unknown reason, when the CreateDataSource method creates a new DbContext instance, it doesn't always have a Connection String. To prevent this from happenning, I created a DbContext instance along with the DataService class to ensure that I have a proper instance:

    public class InformationDataService : DataService<InformationEntities>
      {
        private InformationEntities context = new InformationEntities("name=InformationEntities");

    After that I modified the overriden CreateDataSource to always return the initially created (and hopefully properly working) DbContext:

    protected override InformationEntities CreateDataSource()
        {
          if (context == null)
                    return new InformationEntities("name=InformationEntities");
          return context;
        }

    After these modifications, the error is gone.


    Andr&amp;#225;s

    • Marked as answer by nologin Wednesday, July 24, 2013 1:48 PM
    Wednesday, July 24, 2013 1:48 PM