5

I cannot save my custom ConfigurationSection in my web.config file on startup.

I've followed this tutorial for a generic implementation. My unit tests passed, I'm able to save de ConfigurationSection in my unit tests!

On application start, I want to build a ClaimCollection based on the controller class name and the belonging method names:

Startup.cs

public void Configuration(IAppBuilder app)
{

    Config = new HttpConfiguration();

    BuildUnityContainer();

    BuildClaimCollection(); <----------------

    ConfigureOAuth(app);

    WebApiConfig.Register(Config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(Config);

}

public void BuildClaimCollection()
{

    //config section
    MethodClaimSection methodClaimSection = BaseConfigurationSection<MethodClaimSection>.Open();

    var methods = GetClaimAuthorizedMethods();

    foreach (var method in methods)
    {
        var claimValue = GetClaimValueFromMethodName(method);
        var claim = new MethodClaimElement()
        {
            Type = "Method",
            Value = claimValue
        };

        methodClaimSection.MethodClaims.Add(claim);
    }
    methodClaimSection.Save();
}  

BaseConfigurationSection.cs

public abstract class BaseConfigurationSection<T> : ConfigurationSection
             where T : ConfigurationSection, new()
{
    public void Save()
    {
        System.Configuration.Configuration config = BaseConfigurationSection<T>.GetConfiguration();
        T section = (T)config.Sections[typeof(T).Name];

        foreach (var property in this.GetType().GetProperties())
        {
            if (property.IsDefined(typeof(ConfigurationPropertyAttribute), false))
            {
                section.GetType().InvokeMember(property.Name, BindingFlags.SetProperty, null, section, 
                    new object[] { 
                        .GetType().InvokeMember(property.Name, BindingFlags.GetProperty, null, this, null) 
                        });
            }
        }

        config.Save(ConfigurationSaveMode.Full);
    }
}

When I run the WebApi application I get this error:

Cannot access a disposed object. Object name: 'System.Web.Http.HttpServer'.

Stacktrace:

[ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Web.Http.HttpServer'.] System.Net.Http.DelegatingHandler.CheckDisposed() +332772 System.Net.Http.DelegatingHandler.CheckDisposedOrStarted() +13 System.Net.Http.DelegatingHandler.set_InnerHandler(HttpMessageHandler value) +23 System.Web.Http.HttpServer.Initialize() +108 System.Web.Http.HttpServer.b__b() +31 System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +115 System.Threading.LazyInitializer.EnsureInitialized(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +72 System.Web.Http.HttpServer.EnsureInitialized() +119 System.Web.Http.d__0.MoveNext() +276 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +28 System.Web.Http.Owin.d__0.MoveNext() +1139 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Cors.d__0.MoveNext() +1204 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext() +287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +937 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +937 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext() +287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +3897072 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__2.MoveNext() +272 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +26 Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow() +33 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +150 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +42 System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +415 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

The Configuration class doesn't have a Dispose method...

How to solve this problem?

Maxime Rouiller
  • 13,614
  • 9
  • 57
  • 107
erwineberhard
  • 309
  • 4
  • 17
  • You don't. Giving the account that is running your app pool write access to the website directory is a very, very bad idea. Don't try to write to your web.config file. Read and save this information from a different, safe, location –  Jan 16 '15 at 20:34
  • In addition to what Will said above, Web.config file is under constant watch. Any change in this file causes app pool recycle. So beaware while changing web.config when application is started. – Pankaj Kapare Jan 16 '15 at 21:19
  • Is it a better idea to write to a separate .xml file. Like this [example](http://www.c-sharpcorner.com/uploadfile/mahesh/readwritexmltutmellli2111282005041517am/readwritexmltutmellli21.aspx) ? Will, do you mean with a 'safe location' a separate file? – erwineberhard Jan 17 '15 at 08:25

0 Answers0