Intenté mucho implementar un proveedor de perfil personalizado en ASP.NET MVC. He leído muchos tutoriales, pero no puedo encontrar mi problema. Es bastante similar al Implementing Profile Provider in ASP.NET MVC.Implementación de proveedor de perfil personalizado en ASP.NET MVC
Pero me gustaría crear mi propio proveedor de perfil, así que escribí la siguiente clase que hereda de 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();
}
}
Aquí está mi acción CreateProfile en mi controlador:
[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");
}
Mi procedimiento usp_GetUserProcedure no es nada especial:
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 mi archivo 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>
Pero siempre consigo esta excepción:
procedimiento o función 'usp_GetUserProcedure' espera el parámetro '@Nombre', que no fue suministrado.
¿Alguna idea sobre lo que podría estar haciendo mal?