2009-11-16 17 views
10

Estoy escribiendo una aplicación web de pequeños foros básicos (para divertirme y afilar la sierra vieja), y estoy teniendo un problema con AppSettings.Actualización de AppSettings a través del Controlador MVC de ASP.NET

Mi plan es tener estas configuraciones en su propio archivo (Settings.config), al que otorgaré modificar permisos a la cuenta de usuario del proceso web, y almacenar todas las configuraciones editables en este archivo (por ejemplo, título del foro, descripción, etc.)

Este es mi código:

 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(FormCollection collection) 
{ 
    try 
    { 
     var config = WebConfigurationManager.OpenWebConfiguration("~/Web.config"); 

     config.AppSettings.Settings["SiteTitle"].Value = collection["SiteTitle"]; 
     config.AppSettings.Settings["SiteDescription"].Value = collection["SiteDescription"]; 

     config.Save(ConfigurationSaveMode.Minimal, false); 
     ConfigurationManager.RefreshSection("appSettings"); 

     return RedirectToAction("Index"); 
    } 
    catch (Exception ex) 
    { 
     ModelState.AddModelError("_FORM", ex.Message); 
     return View("Index"); 
    } 
} 

... pero el funcionamiento se devuelve el siguiente error:

A configuration file cannot be created for the requested Configuration object.

He intentado conceder el permiso completo a todos los usuarios en el archivo de configuración , sin ningún efecto (actualmente solo me estoy ejecutando bajo Cassini, por lo que el usuario del proceso soy yo quien tiene la propiedad del archivo en cualquier caso).

¿Alguna idea?

Respuesta

18

Cambiar la primera línea a la siguiente:

var config = WebConfigurationManager.OpenWebConfiguration("~"); 

confuso ya que puede ser, OpenWebConfiguration espera que la ruta de acceso virtual donde reside el Web.config, excluyendo el nombre del archivo. Supongo que la lógica es que solo habrá un Web.config en un directorio determinado, por lo que incluir el nombre no es necesario.

El MSDN documentation última instancia, nos pistas en aquí - si nos fijamos en los ejemplos todos ellos utilizan rutas relativas explícitas, y cuando se aloja en IIS le permiten especificar los archivos de configuración desde otros lugares, por ejemplo:

OpenWebConfiguration("/siteName", "Default Web Site", null, "myServer"); 

Adición:

¿Por qué funciona OpenWebConfiguration("~/Web.config") en absoluto? No estoy seguro de que pueda explicarlo definitivamente, pero intente esto con patadas: cámbielo a ("~/Foo.bar"). ¡El mismo resultado! Puede leer - su mismo archivo Web.config - ¡pero no puede escribir! (Ahora intente agregar el directorio foo.bar a su sitio, luego ponga un Web.config dentro de él ...)

Dado que OpenWebConfiguration espera un directorio (y aparentemente permite que no existan, siempre que encuentre un Web .config dentro del padre), creo que es por eso que especificar erróneamente ~/Web.config como una "ruta" nos permite cargar la configuración raíz, pero no guardarla.

+0

Eso es realmente un comportamiento muy interesante del que no he oído hablar. Muchas gracias por explicarlo ya que también estaba un poco despistado en esto. – Venemo

+0

Gracias, eso es muy interesante - ¡Voy a probar esto esta noche! –

+1

Funcionó como un encanto, ¡gracias! –

0

Si está ejecutando esto desde otro proyecto, entonces usará la configuración de esa carpeta que no tendrá un archivo de configuración, por lo tanto, el error que no se puede crear.

Es posible que desee utilizar server.mappath o algo por el estilo para llegar a las carpetas de archivo de configuración web.

+0

¿Podría aclarar qué quiere decir con "ejecutar esto desde otro proyecto"? –

+0

Si tiene su sitio web y tiene su capa comercial, y el código se está ejecutando en el proyecto de la capa empresarial, entonces sospecho que el archivo de configuración que está buscando estará en el proyecto de la capa empresarial. necesita obtener la ruta al archivo de configuración web – griegs

+0

Ah, ya veo ... en realidad no, aunque normalmente configuro cosas así, en este caso estoy siendo flojo y tengo la capa de negocios en la carpeta "Modelos" de mi aplicación MVC. –

1

Prueba esto:

var configFile = HttpContext.Current.Server.MapPath("~/Web.config"); 
var config = WebConfigurationManager.OpenWebConfiguration(configFile); 

Sin embargo, creo que es una mala idea para almacenar este tipo de información en el web.config, sobre todo si se tiene la intención de cambiar de forma dinámica.

Incluso si planea usar un archivo de configuración separado, preferiría almacenar esto de otra manera, y no me molestaría en obtener mi propia configuración a través de las clases de System.Configuration. En su mayoría están destinados a leer App.Config de las aplicaciones ASP.NET 'Web.Config y Windows App', y hacer que funcionen con otra cosa es realmente inútil.

recomiendo lo siguiente:

añadir un archivo XML independiente a su proyecto. (preferiblemente en la carpeta App_Data, donde no se puede acceder desde la web, y donde su aplicación ya tiene permisos de lectura y escritura.)

Puede almacenar este tipo de configuraciones en ese XML, y leer y escríbelo usando System.Xml o LINQ to XML.

+0

Sí, sé que puede que no sea la mejor manera de hacerlo: realmente solo quería ver si funcionaba, y probar algo diferente (y era demasiado vago para configurar una tabla de configuraciones en mi base de datos, si estoy honesto;)) –

+1

@Venemo - Su sugerencia tiene mucho sentido. Es mucho más práctico usar un archivo XML donde podamos leer y escribir libremente sin las restricciones impuestas por web.config. También me gustó la sugerencia de colocarlo en AppData, donde ya se otorgan los derechos de lectura y escritura. Sin mencionar que puede ser compartido por un sinnúmero de aplicaciones. No es que vaya a llegar tan lejos :) –

+0

@BenJunior - gracias :) ¡Me alegro de poder ayudar! – Venemo

Cuestiones relacionadas