2012-10-18 28 views
9

Azure web sitelerine ev sahipliği yaptığım temel bir ASP.NET MVC 4 sitem var. Kimlik doğrulama, form kimlik doğrulamasıdır ve varsayılan şablondan özelleştirilmemiştir. Yayınladığım her zaman, sitemi tekrar ziyaret ettiğimde, bir hata mesajı vermeden önce çok uzun bir zaman aşımına (belki birkaç dakika) takılır. Tarayıcımdaki site için çerezleri silerek ve yeniden yükleyerek kurtarabilirim. MVC 4 uygulamasını azure'a yayınladıktan sonra kimlik doğrulama sorunları

Başlangıçta sorun sadece kimlik gerekli sayfalara erişmek için çalışıyordu, ama sonra bu katma benim _Layout.cshtml paylaştı:

@if (User.IsInRole("Admin")) 
{ 
    <li>@Html.ActionLink("Admin", "Index", "Admin")</li> 
} 
şimdi hiç hiçbir sayfaları bir yeni yayımladıktan sonra erişilebilir demektir

ve böylece Sorunu düzeltmek için kullandığım başka bir yol olan çıkış bağlantısını bile tıklayamıyorum.

Yanlış yapılandırılmış bir şey var mı? Bir geçici çözümüm olsa da, kendimi kullanabilirim. Bu, bir güncelleme yayınladıktan sonra sitenin kullanıcıları için iyi bir deneyim olmayacaktır.

DÜZENLEME: ELMAH günlüklerden, form kimlik doğrulaması ben IsInRole çağırdığınızda SQL Express veritabanı oluşturmak için çalışıyor gibi görünüyor. Formlarımın kimlik doğrulaması her şey SQL Azure veritabanımı kullanacak şekilde ayarlandığı için bunu neden yaptığını göremiyorum.

System.Web.HttpException (0x80004005): Unable to connect to SQL Server database. ---> System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified) 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 
    at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover) 
    at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, SqlConnection owningObject, Boolean withFailover) 
    at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout) 
    at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance) 
    at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance) 
    at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) 
    at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup) 
    at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) 
    at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) 
    at System.Data.SqlClient.SqlConnection.Open() 
    at System.Web.Management.SqlServices.GetSqlConnection(String server, String user, String password, Boolean trusted, String connectionString) 
ClientConnectionId:00000000-0000-0000-0000-000000000000 
    at System.Web.Management.SqlServices.GetSqlConnection(String server, String user, String password, Boolean trusted, String connectionString) 
    at System.Web.Management.SqlServices.SetupApplicationServices(String server, String user, String password, Boolean trusted, String connectionString, String database, String dbFileName, SqlFeatures features, Boolean install) 
    at System.Web.Management.SqlServices.Install(String database, String dbFileName, String connectionString) 
    at System.Web.DataAccess.SqlConnectionHelper.CreateMdfFile(String fullFileName, String dataDir, String connectionString) 
    at System.Web.DataAccess.SqlConnectionHelper.EnsureSqlExpressDBFile(String connectionString) 
    at System.Web.DataAccess.SqlConnectionHelper.GetConnection(String connectionString, Boolean revertImpersonation) 
    at System.Web.Security.SqlRoleProvider.GetRolesForUser(String username) 
    at WebMatrix.WebData.SimpleRoleProvider.GetRolesForUser(String username) 
    at System.Web.Security.RolePrincipal.IsInRole(String role) 
+0

Mark Bu soruyu kendiminkine benzer bir şekilde alıntıyorum ... http://stackoverflow.com/questions/24149044/two-chrome-sessions-on-the-same-machine-one-will-connect -siz-bizim-azure-web sitesi ve eğer aşağıdaki cevabın işe yarıyorsa, gerçekten senin yolunu zorlamak gerekir ... – hawbsl

cevap

9

çeşitli blog yayınlarında farklı önerilerin onlarca denedikten sonra ben bir çözüm bulduk. Ev denetleyicime InitialiseSimpleMembership özniteliğini eklemek sorunu çözüyor.

[InitializeSimpleMembership] 
public class HomeController : Controller 

Bu değişikliği yaptıktan sonra, birkaç başarılı yayınınızda sorun yaşamadım. Ben neden User.IsInRole herhangi çağrılar yapılmadan önce InitializeSimpleMembershipAttribute kurucudaki aşağıdaki kod satırı çalıştırmak için ihtiyaç duyduğu şüpheli:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); 

ben Application_Start içinde InitializeSimpleMembership çalıştırmak olacaktır yapılacak en iyi şey sanırım.

+2

Bu işe yararsa, belki de sağlayıcıları web.config dosyasında açık bir şekilde bağlamanız gerekir. Http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/ – RickAndMSFT

+0

teşekkürler @RickAndMSFT, Bir noktada Web.Config dosyasındaki üyeliği ve rol sağlayıcılarını düzenlemeyi araştırdım, ancak sözdiziminin ne olması gerektiğine dair bilgi gelmek çok zordu. –

+0

Benzer bir sorunla karşılaştım - hata iletisi, SQL Server ile bağlantı kurulurken ağ ile ilgili veya örneğe özel bir hata oluştu. Sunucu bulunamadı veya erişilebilir değildi. Örnek adının doğru olduğunu ve SQL Server'ın uzak bağlantılara izin verecek şekilde yapılandırıldığını doğrulayın. (sağlayıcı: SQL Network Arabirimleri, hata: 26 - Sunucu/Örnek Belirtilen Hata). – Will

4

İşte Windows Azure üzerinde uygulama dağıtımını yaparken kurulum için bir SQL veritabanı takip edebilecek bir tutorial bu. Internet şablonunu kullanarak yeni bir ASP.NET MVC 4 uygulaması oluşturduğunuzda, varsayılan olarak yerel bir SQL Express veritabanına işaret eden web.config dosyasında doğru bağlantı dizesini ayarlamanız gerekir.

Kişisel SQL Azure bağlantı dizesi şu şekilde görünecektir:

<connectionStrings> 
    <add name="DefaultConnection" connectionString="Data Source=tcp:#server#.database.windows.net,1433;Initial Catalog=#DBName#;User ID=UserName#@#server#;Password=#password#;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/> 
</connectionStrings> 
+2

Teşekkürler, ama benim bağlantı dizgimde sorun yok. Tarayıcımdaki çerezleri sildikten sonra site iyi çalışıyor. Tüm veriler var, tüm kullanıcı girişleri ve roller var. Yanlış giden bir yayınlamanın ardından sadece ilk erişim. –

+0

Peki o zaman sorunun ne olabileceğini düşünmek zorundayım. Bağladığım eğiticiyi izlemeyi deneyin. –

+0

evet, bunu denedim ve bunu yüklememi sağladı: http://nuget.org/packages/Microsoft.AspNet.Providers.LocalDB, ama bu her şeyi kırdı, bu konuya http: // social. msdn.microsoft.com/forums/pl-pl/windowsazuredevelopment/thread/d352bb1b-577c-42b7-8872-5ed59cd65f32 –

1

Bu soruya cevap verilmesine rağmen, deneyimlerimi aynı sorunla çabucak paylaşabileceğimi düşündüm. Benim durumum Mark'ınkinden biraz farklı.

Tüm denetleyicilerimdeki InitializeSimpleMembership özniteliğini aldım (aslında tüm denetleyicilerin devraldığı temel denetleyicimde kullandım), ancak yine de aynı sorunu yaşıyordum. Şimdi, temel denetleyicimde, uygulamalarımıza ilişkin bazı bağlam bilgilerini ayarlamak için Initialize yöntemini de geçersiz kıldım. Bu bağlam kurulumunun bir parçası, geçerli kullanıcının belirli bir rolde olup olmadığını kontrol etmektir, dolayısıyla IsUserInRole yönteminin bu Initialize yönteminden, tüm eylem yöntemlerinin çağrılmasından önce çağrıldığını kontrol etmektir.tek tek ilk olarak başlatılması aslında OnActionExecuting yöntemde yapıldığını fark InitializeSimpleMembership sınıfa bir göz sürerse Şimdi

(yani ActionFilterAttribute den InitializeSimpleMembership devralır): Benim durumumda

public override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
     // Ensure ASP.NET Simple Membership is initialized only once per app start 
     LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); 
} 

, bu üyelik başlatma oluyordu çok geç ... yani, temel denetleyicimin Initialize yönteminde geçersiz kılınması için çağrımı IsUserInRole yapmadan önce başlatılması gereken Basit Üyeliğe ihtiyacım var.

benim için çözüm oldukça basit oldu

: Artık

public class BaseController : Controller 
{ 
    private static SimpleMembershipInitializer _initializer; 
    private static object _initializerLock = new object(); 
    private static bool _isInitialized; 

    private class SimpleMembershipInitializer 
    { 
     public SimpleMembershipInitializer() 
     { 
      try 
      { 
       WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); 
      } 
      catch (Exception ex) 
      { 
       throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex); 
      } 
     } 
    } 

    ... 

    protected override void Initialize(RequestContext requestContext) 
    { 
     base.Initialize(requestContext); 
     LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); 
     SetupControllerContext(); // my function that calls 'IsUserInRole' 
    } 
} 

: Ben InitializeSimpleMembership tamamen bağlıyor ve benim Initialize yönteminden böyle bir şey diyebilirsin ki düz benim temel denetleyicisi içine mantığı koymak kaldırıldı Sanırım bu, muhtemelen bunu tekrar gözden geçirip Mark'ın önerdiği gibi Application_Start() yöntemine koymanız gerektiğini düşünür, ama siz bu fikri anlayabilirsiniz :). Sadece tecrübelerimi kontrol edenlerin kontrolünde Initialize yönteminde benzer bir şey yapması durumunda açıklamak istedim.

İlgili konular