Domanda

Sto sviluppando un ASP.NET MVC web app sotto .NET 3.5, NHibernate e ospitato su Windows Azure.Quando, la webapp è gestito da sviluppo locale tessuto funziona bene.Eppure, quando mi muovo a Windows Azure, ogni inserto eseguita dal web MVC ruolo finisce con l'eccezione elencati qui sotto.

Qualsiasi idea di cosa c'è di sbagliato con il mio NHibernate logica?(potrebbe essere la gestione della sessione, non sono sicuro)

[AssertionFailure:null id Lokad.Tradurre.Entità.Inserimento utente (non lavare la Sessione dopo si verifica un'eccezione)] NHibernate.Evento.Default.DefaultFlushEntityEventListener.CheckId(Object obj, IEntityPersister persister, id di Oggetto, EntityMode entityMode) +292 NHibernate.Evento.Default.DefaultFlushEntityEventListener.GetValues(entità Oggetto, EntityEntry voce, EntityMode entityMode, Boolean mightBeDirty, ISessionImplementor sessione) +93 NHibernate.Evento.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent evento) +158 NHibernate.Evento.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent evento) +469 NHibernate.Evento.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent evento) +339 NHibernate.Evento.Default.DefaultFlushEventListener.OnFlush(FlushEvent evento) +85 NHibernate.L'Impl.SessionImpl.Flush() +275 NHibernate.Transazione.AdoTransaction.Commit() +236 Lokad.Tradurre.Repository.PageRepository.Creare(Pagina) Lokad.Tradurre.I controller.PagesController.Creare(Pagina) lambda_method(ExecutionScope , ControllerBase , Object[] ) +69 Sistema.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +251 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parametri) +31 Sistema.Web.Mvc.<>c__DisplayClassa.b__7() +88 Sistema.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filtro, ActionExecutingContext preContext, Func1 continuation) +534 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filtri, ActionDescriptor actionDescriptor, IDictionary`2 parametri) +312 Sistema.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +856 Sistema.Web.Mvc.Controller.ExecuteCore() +185 Sistema.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +221 Sistema.Web.CallHandlerExecutionStep.Sistema.Web.HttpApplication.IExecutionStep.Execute() +586 Sistema.Web.HttpApplication.ExecuteStep(IExecutionStep passaggio, Boolean& completedSynchronously) +177

Nota che sto usando _session.FlushMode = FlushMode.Commit; e che il User è utilizzato in un custom RoleProvider

public class SimpleRoleProvider : RoleProvider 
{
    readonly UserRepository Users = new UserRepository();

    public override string[] GetRolesForUser(string username)
    {
        try
        {
            var user = Users.Get(username);

            // no role if user is not registered
            if (null == user) return new string[0];

            // default role for registered user
            return user.IsManager ? new[] { "Manager", "User" } : new[] { "User" };
        }
        catch (Exception)
        {
            // role should not fail in case of DB issue.
            return new string[0];
        }
    }
}
È stato utile?

Soluzione 2

Ho finalmente trovato la soluzione al mio problema.Nel caso In cui la gente sarebbe interessato, sto postando la soluzione qui.

public class SimpleRoleProvider : RoleProvider 
{
    // isolated session management for the RoleProvider to avoid
    // issues with automated management of session lifecycle.

    public override string[] GetRolesForUser(string username)
    {
        using (var session = GlobalSetup.SessionFactory.OpenSession())
        {
            var users = new UserRepository(session);
            var user = users.Get(username);

            // no role if user is not registered
            if (null == user) return new string[0];

            // default role for registered user
            return user.IsManager ? new[] {"Manager", "User"} : new[] {"User"};
        }
    }
}

Fondamentalmente ciò che stava accadendo è che il RoleProvider repository non sembrano avere lo stesso ciclo di vita più regolari in-vista / in-controller repository.Come risultato, al momento il RoleProvider è chiamato, il NHibernate sessione è già stato disposto che causa l'eccezione osservato qui sopra.

Ho sostituito il codice seguente uno qui sopra.Questo ha i propri NHibernate gestione della sessione, e finisce per lavorare bene.

Altri suggerimenti

Non si dovrebbe mai prendere eccezioni e ignorare nel corso di una NHibernate transazione.

Cerco di spiegare perché.

Ci potrebbero essere delle eccezioni, per esempio causato da vincoli nel database.(potrebbe anche essere causato da problemi di mappatura, le eccezioni generate dalla proprietà o qualsiasi altra cosa.) NHibernate tenta di sincronizzare lo stato in memoria con il database.Questo viene fatto in fase di commit - e, a volte, prima di query per assicurarsi che le query vengono eseguite su dati reali.Quando la sincronizzazione ha esito negativo, lo stato del database è qualcosa di casuale, alcuni cambiamenti sono persistenti, altri non lo sono.L'unica cosa che si può fare in questo caso è di chiudere la sessione.

Considerare che le decisioni e calcoli nel codice sono basate su valori in memoria.Ma - in caso di un ignorato eccezione, questi valori non sono i valori nel database, non potranno mai essere lì.Quindi la tua logica di decidere e di calcolo su 'fantasy-dati'.

A proposito, non è mai una buona idea per intercettare le eccezioni (non tipizzata) e ignorarli.Si dovrebbe sempre sapere le eccezioni di gestire, e essere sicuri che si può continuare.

Che cosa stai facendo qui è la deglutizione errori di programmazione.Mi creda, il sistema non sarà più stabile.La domanda è solo:avete notato l'errore quando si verifica, o lo si ignora c'e anche persistere il risultato di un errore nel database?Quando si esegue questi ultimi, non devi essere sorpreso quando il database è incoerente e altri errori si verificano quando si tenta di ottenere i dati dal database.E non potrà mai trovare il codice che è la vera causa dell'errore.

Questa eccezione può verificarsi se i nomi di colonna includere parole riservate (es.usare lo stato come un nome di colonna e diventerà impossibile per Salvare)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top