Actualmente estoy evaluando ABP 3.9 y la creación de inquilinos no funciona.
Falla al ejecutar este código:
CheckErrors(await _roleManager.CreateStaticRoles(tenant.Id));
Esta es la excepción que estoy obteniendo:
Mvc.ExceptionHandling.AbpExceptionFilter - Format of the initialization string does not conform to specification starting at index 0.
System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0.
at System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue)
at System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms, Boolean firstKey)
at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms)
at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
at System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
at System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
at System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.CreateDbConnection()
La misma conexión de Entity Framework funciona con otras clases de ApplicationService
que he agregado. No sé por qué solo para la creación de inquilinos esto falla. Estoy extendiendo la plantilla de muestra, que está disponible gratuitamente en el sitio ASP.NET Boilerplate.
Muchas gracias por la ayuda. Saludos, Zainu
No me di cuenta hasta que el código se implementó en Azure que terminaría con la excepción "System.ApplicationException: No se pudo encontrar la carpeta raíz de contenido".
Por suerte para mí, hubo una discusión sobre lo mismo aquí https://github.com/aspnetboilerplate/aspnetboilerplate-templates/issues/43 y la solución fue la misma
var startupPath = System.IO.Directory.GetCurrentDirectory (); configuración var = AppConfigurations.Get (startupPath); tenant.ConnectionString = SimpleStringCipher.Instance.Encrypt (configuration.GetConnectionString (OneCloudConsts.ConnectionStringName));
En la clase TenantAppService, en el método Crear, se comentó el código que creó la cadena de conexión cifrada a partir de la entrada DTO. Se agregó una forma de leer la cadena de conexión desde la configuración y esto funcionó en mi caso, ya que tengo una única base de datos para todos los inquilinos. Esta base de datos sería muy pequeña y almacenaría solo metadatos sobre los inquilinos, mientras que la mayoría de los datos de la aplicación se almacenarían en Azure.
public override async Task<TenantDto> Create(CreateTenantDto input)
{
CheckCreatePermission();
// Create tenant
var tenant = ObjectMapper.Map<Tenant>(input);
//this code is commented since we have single database for all tenants
//tenant.ConnectionString = input.ConnectionString.IsNullOrEmpty()
// ? null
// : SimpleStringCipher.Instance.Encrypt(input.ConnectionString);
//This would read connection string from configuration and pass it to
//connectionstring property of AbpTenant
var configuration =
AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
tenant.ConnectionString = SimpleStringCipher.Instance.Encrypt(configuration.GetConnectionString(OneCloudConsts.ConnectionStringName));