2009-05-07 25 views
6

ASP.NET MVC'de özel bir profil sağlayıcısı uygulama konusunda çok çalıştım. Çok sayıda öğretici okudum ama sorunumun nerede olduğunu bulamıyorum. Implementing Profile Provider in ASP.NET MVC'a oldukça benziyor.ASP.NET MVC'de Özel Profil Sağlayıcısı Uygulaması

Ama kendi Profili Sağlayıcı oluşturmak istiyorum, bu yüzden ProfileProvider devralır aşağıdaki sınıfını yazdı:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult CreateProfile(string Username, string Password, string FirstName, string LastName) 
{ 
    MembershipCreateStatus IsCreated = MembershipCreateStatus.ProviderError; 
    MembershipUser user = null; 

    user = Membership.CreateUser(Username, Password, "[email protected]", "Q", "A", true, out IsCreated); 

    if (IsCreated == MembershipCreateStatus.Success && user != null) 
    { 
     ProfileCommon profile = (ProfileCommon)ProfileBase.Create(user.UserName); 

     profile.FirstName = FirstName; 
     profile.LastName = LastName; 
     profile.Save(); 
    } 

    return RedirectToAction("Index", "Home"); 
} 

: my Kontrolör benim CreateProfile eylem

İşte
public class UserProfileProvider : ProfileProvider 
{ 
    #region Variables 
    public override string ApplicationName { get; set; } 
    public string ConnectionString { get; set; } 
    public string UpdateProcedure { get; set; } 
    public string GetProcedure { get; set; } 
    #endregion 

    #region Methods 
    public UserProfileProvider() 
    { } 

    internal static string GetConnectionString(string specifiedConnectionString) 
    { 
     if (String.IsNullOrEmpty(specifiedConnectionString)) 
      return null; 

     // Check <connectionStrings> config section for this connection string 
     ConnectionStringSettings connObj = ConfigurationManager.ConnectionStrings[specifiedConnectionString]; 
     if (connObj != null) 
      return connObj.ConnectionString; 

     return null; 
    } 
    #endregion 

    #region ProfileProvider Methods Implementation 
    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) 
    { 
     if (config == null) 
      throw new ArgumentNullException("config"); 

     if (String.IsNullOrEmpty(name)) 
      name = "UserProfileProvider"; 

     if (String.IsNullOrEmpty(config["description"])) 
     { 
      config.Remove("description"); 
      config.Add("description", "My user custom profile provider"); 
     } 

     base.Initialize(name, config); 

     if (String.IsNullOrEmpty(config["connectionStringName"])) 
      throw new ProviderException("connectionStringName not specified"); 

     ConnectionString = GetConnectionString(config["connectionStringName"]); 

     if (String.IsNullOrEmpty(ConnectionString)) 
      throw new ProviderException("connectionStringName not specified"); 


     if ((config["applicationName"] == null) || String.IsNullOrEmpty(config["applicationName"])) 
      ApplicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath; 
     else 
      ApplicationName = config["applicationName"]; 

     if (ApplicationName.Length > 256) 
      throw new ProviderException("Application name too long"); 

     UpdateProcedure = config["updateUserProcedure"]; 
     if (String.IsNullOrEmpty(UpdateProcedure)) 
      throw new ProviderException("updateUserProcedure not specified"); 

     GetProcedure = config["getUserProcedure"]; 
     if (String.IsNullOrEmpty(GetProcedure)) 
      throw new ProviderException("getUserProcedure not specified"); 
    } 

    public override System.Configuration.SettingsPropertyValueCollection GetPropertyValues(System.Configuration.SettingsContext context, System.Configuration.SettingsPropertyCollection collection) 
    { 
     SettingsPropertyValueCollection values = new SettingsPropertyValueCollection(); 

     SqlConnection myConnection = new SqlConnection(ConnectionString); 
     SqlCommand myCommand = new SqlCommand(GetProcedure, myConnection); 
     myCommand.CommandType = CommandType.StoredProcedure; 

     myCommand.Parameters.AddWithValue("@FirstName", (string)context["FirstName"]); 

     try 
     { 
      myConnection.Open(); 
      SqlDataReader reader = myCommand.ExecuteReader(CommandBehavior.SingleRow); 

      reader.Read(); 

      foreach (SettingsProperty property in collection) 
      { 
       SettingsPropertyValue value = new SettingsPropertyValue(property); 

       if (reader.HasRows) 
       { 
        value.PropertyValue = reader[property.Name]; 
        values.Add(value); 
       } 
      } 

     } 
     finally 
     { 
      myConnection.Close(); 
      myCommand.Dispose(); 
     } 

     return values; 
    } 

    public override void SetPropertyValues(System.Configuration.SettingsContext context, System.Configuration.SettingsPropertyValueCollection collection) 
    { 
     SqlConnection myConnection = new SqlConnection(ConnectionString); 
     SqlCommand myCommand = new SqlCommand(UpdateProcedure, myConnection); 
     myCommand.CommandType = CommandType.StoredProcedure; 

     foreach (SettingsPropertyValue value in collection) 
     { 
      myCommand.Parameters.AddWithValue(value.Name, value.PropertyValue); 
     } 

     myCommand.Parameters.AddWithValue("@FirstName", (string)context["FirstName"]); 

     try 
     { 
      myConnection.Open(); 
      myCommand.ExecuteNonQuery(); 
     } 

     finally 
     { 
      myConnection.Close(); 
      myCommand.Dispose(); 
     } 
    } 

olduğunu Benim yordam usp_GetUserProcedure özel bir şey yok:

ALTER PROCEDURE [dbo].[usp_GetUserProcedure] 
-- Add the parameters for the stored procedure here 
@FirstName varchar(50) 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
SELECT * FROM dbo.Users WHERE FirstName = @FirstName 
END 

A nd benim Web.config dosyası:

<profile enabled="true" 
     automaticSaveEnabled="false" 
     defaultProvider="UserProfileProvider" 
     inherits="Test.Models.ProfileCommon"> 
<providers> 
<clear/> 
<add name="UserProfileProvider" 
     type="Test.Controllers.UserProfileProvider" 
     connectionStringName="ApplicationServices" 
     applicationName="UserProfileProvider" 
     getUserProcedure="usp_GetUserProcedure" 
     updateUserProcedure="usp_UpdateUserProcedure"/> 
</providers> 
</profile> 

Ama her zaman bu durum almak:

Yordam veya işlev 'usp_GetUserProcedure' parametresi bekler '@firstName' sağlanmadı hangi.

Neyi yanlış yaptığım hakkında bir fikrin var mı?

cevap

2

en olası nedeni

myCommand.Parameters.AddWithValue("@FirstName", (string)context["FirstName"]); 

(string)context["FirstName"] boş değer olmasıdır. Bir parametreyi bir dikdörtgene geçirseniz bile, değer gerekli bir parametrede boşsa, bu hatayı görürsünüz. SQL Server (etkin bir şekilde), iletilmeyen bir parametre ile bir null değeriyle bir tane arasında ayrım yapmaz.

Bir SQL hatası görüyorsunuz. Bu MVC ve MVC ile ilgili değil gerçekten sorununuzu neden olmaz. Null'ın geçerli bir context["FirstName"] değeri olup olmadığını belirleyin ve eğer öyleyse, boş değerlerini kabul etmek için işlevinizi değiştirin. Değilse, neden context["FirstName"]'un boş olduğunu öğrenin.

Ayrıca, bu satırın parametre adlarınızı doğru şekilde ("@" öneki ile) ekleyeceğini sanmıyorum.

myCommand.Parameters.AddWithValue (value.Name, value.Mülk değeri); Ayrıca

, bu MVC olduğundan, size form gönderme üzerinde FirstName adında bir kontrole sahip emin olun:

Bu adına göre alanlar okur
public ActionResult CreateProfile(string Username, string Password, string FirstName, string LastName) 

değil, kimliği

0

Evet, çünkü özelliklerim için ProfileBase'den alınmış bir ShareCommon sınıfı kullanıyorum.

public class ProfileCommon : ProfileBase 
{ 
public virtual string Label 
{ 
    get 
    { 
     return ((string)(this.GetPropertyValue("Label"))); 
    } 
    set 
    { 
     this.SetPropertyValue("Label", value); 
    } 
} 

public virtual string FirstName 
{ 
    get 
    { 
     return ((string)(this.GetPropertyValue("FirstName"))); 
    } 
    set 
    { 
     this.SetPropertyValue("FirstName", value); 
    } 
} 

public virtual string LastName 
{ 
    get 
    { 
     return ((string)(this.GetPropertyValue("LastName"))); 
    } 
    set 
    { 
     this.SetPropertyValue("LastName", value); 
    } 
} 

public virtual ProfileCommon GetProfile(string username) 
{ 
    return Create(username) as ProfileCommon; 
} 
} 

Sen Web.Config dosyasında bu sınıfı kullanıyorum görebilirsiniz: Ben Web.config benim özelliklerini yazarsam,

<profile enabled="true" 
    automaticSaveEnabled="false" 
    defaultProvider="UserProfileProvider" 
    inherits="Test.Models.ProfileCommon"> 
[...] 

Ve ASP.Net MVC ile Yapamam artık Profile.PropertyName kullanarak erişebilirsiniz. Belki bir yolu var, ama hiçbir örnek bulamıyorum.

İlgili konular