2009-05-07 10 views
6

ASP.NET MVCでカスタムプロファイルプロバイダを実装しようとしました。 多くのチュートリアルを読んだことがありますが、問題がどこにあるのかわかりません。それはImplementing Profile Provider in ASP.NET MVCとかなり似ています。ASP.NET MVCでのカスタムプロファイルプロバイダの実装

しかし、私は私自身のプロファイルプロバイダを作成したいのですが、私はProfileProviderから継承以下のクラスを書いた:ここ

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(); 
     } 
    } 

は私のコントローラで私CreateProfileアクションです:

[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"); 
} 

私の手続きusp_GetUserProcedureは特別なものではありません。

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私のWeb.Configファイル:

<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> 

しかし、私は常にこの例外を取得:

プロシージャまたは関数 'usp_GetUserProcedureは' パラメータを期待 '@FirstName'、供給されませんでした。

私は何が間違っているかもしれないと思っていますか?

答えて

2

最も可能性の高い原因は、

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

(string)context["FirstName"]がNULL値であるということです。 sprocにパラメータを渡しても、必要なパラメータで値がnullの場合、このエラーが表示されます。 SQL Serverでは、渡されなかったパラメータとNULL値で渡されたパラメータは区別されません(事実上)。

SQLエラーが表示されます。これはMVCとは無関係であり、MVCは実際に問題を引き起こすものではありません。ヌルが有効値context["FirstName"]であるかどうかを判断し、ヌル値を受け入れるように関数を変更します。そうでない場合は、context["FirstName"]がnullである理由を確認してください。

また、私はこの行がパラメータ名を正しく( "@"接頭辞付きで)追加するとは思わないと思います。

myCommand.Parameters.AddWithValue(value.Name、value。PropertyValue);これはMVCであるので、

また、に姓フォーム投稿に名前のコントロールを持っていることを確認します

public ActionResult CreateProfile(string Username, string Password, string FirstName, string LastName) 

それは名前ではなくID

に基づいてフィールドを読み込み、
0

ええ、それはProfileBaseを継承するProfileCommonのプロパティ用にクラスを使用しているからです。私はのWeb.Configで私の性質を書いた場合、私はできない、

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

そして、ASP.Net MVCを持つ:Web.configファイルで、私はこのクラスを使用していることがわかります

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; 
} 
} 

Profile.PropertyNameを使用してそれらにアクセスします。多分方法がありますが、私は例を見つけることはできません。

関連する問題