Membership.Updateuser не обновляет базу данных - PullRequest
1 голос
/ 27 апреля 2010

В настоящее время я работаю над системой членства для моего веб-приложения, которая основана на проверке подлинности с помощью форм из фреймворка.

Я создал несколько пользователей с помощью интегрированного инструмента, и логин отлично работает. Но теперь я хочу предоставить администратору возможность создавать, изменять, удалять пользователей.

Итак, вот что я получил прямо сейчас:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim muc As MembershipUserCollection = Membership.GetAllUsers()

    ComboBox1.DataSource = muc
    ComboBox1.DataValueField = "UserName"
    ComboBox1.DataTextField = "UserName"
    ComboBox1.DataBind()
End Sub

Protected Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox1.SelectedIndexChanged

    Dim userName As String = ComboBox1.SelectedValue

    Dim mu As MembershipUser = Membership.GetUser(userName)

    Dim userRoles As String() = Roles.GetRolesForUser(userName)

    tbComments.Text = mu.Comment
    tbEmail.Text = mu.Email
    lblUserName.Text = mu.UserName
End Sub

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
    Dim userName As String = ComboBox1.SelectedValue
    Dim mu As MembershipUser = Membership.GetUser(userName)

    If Not mu Is Nothing Then
        Try
            mu.Comment = tbComments.Text
            Membership.UpdateUser(mu)

            mu.Email = tbEmail.Text
            Membership.UpdateUser(mu)

            mu.IsApproved = True
            Membership.UpdateUser(mu)

            mu = Nothing
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
        End Try
    End If

    DetailPanel.Visible = False
End Sub

Проблема в том, что запись не обновляется в базе данных. Я сделал несколько звонков на Membership.UpdateUser после прочтения этой записи в блоге , но это ничего не изменило.

Странная вещь, которую я заметил при отладке, это то, что когда я вхожу в метод Button1_Click, Membership.GetUser(userName) возвращает мне значения из моей предыдущей попытки! Я не очень понимаю, чего мне не хватает.

У кого-нибудь есть подсказка?

Заранее спасибо!

1 Ответ

4 голосов
/ 27 апреля 2010

Первый:

Цитируемая вами запись в блоге просто неверна .

Вот метод, который вы вызываете, сообщите мне, если вы видите указание на то, что его нужно вызывать несколько раз для обновления нескольких свойств:

public override void UpdateUser(MembershipUser user)
{
    if (user == null)
    {
        throw new ArgumentNullException("user");
    }
    SecUtility.CheckParameter(ref user.UserName, true, true, true, 0x100, "UserName");
    string email = user.Email;
    SecUtility.CheckParameter(ref email, this.RequiresUniqueEmail, this.RequiresUniqueEmail, false, 0x100, "Email");
    user.Email = email;
    try
    {
        SqlConnectionHolder connection = null;
        try
        {
            connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
            this.CheckSchemaVersion(connection.Connection);
            SqlCommand command = new SqlCommand("dbo.aspnet_Membership_UpdateUser", connection.Connection);
            command.CommandTimeout = this.CommandTimeout;
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName));
            command.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, user.UserName));
            command.Parameters.Add(this.CreateInputParam("@Email", SqlDbType.NVarChar, user.Email));
            command.Parameters.Add(this.CreateInputParam("@Comment", SqlDbType.NText, user.Comment));
            command.Parameters.Add(this.CreateInputParam("@IsApproved", SqlDbType.Bit, user.IsApproved ? 1 : 0));
            command.Parameters.Add(this.CreateInputParam("@LastLoginDate", SqlDbType.DateTime, user.LastLoginDate.ToUniversalTime()));
            command.Parameters.Add(this.CreateInputParam("@LastActivityDate", SqlDbType.DateTime, user.LastActivityDate.ToUniversalTime()));
            command.Parameters.Add(this.CreateInputParam("@UniqueEmail", SqlDbType.Int, this.RequiresUniqueEmail ? 1 : 0));
            command.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, DateTime.UtcNow));
            SqlParameter parameter = new SqlParameter("@ReturnValue", SqlDbType.Int);
            parameter.Direction = ParameterDirection.ReturnValue;
            command.Parameters.Add(parameter);
            command.ExecuteNonQuery();
            int status = (parameter.Value != null) ? ((int) parameter.Value) : -1;
            if (status != 0)
            {
                throw new ProviderException(this.GetExceptionText(status));
            }
        }
        finally
        {
            if (connection != null)
            {
                connection.Close();
                connection = null;
            }
        }
    }
    catch
    {
        throw;
    }
}

Второе:

Вы переплетаете свой список каждый постбэк. Это нужно сделать только один раз, и список сохраняется в viewstate.

Вот рабочая реализация:

UpdateUser.aspx

<%@ Page Language="vb" %>

<script runat="server">

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        ' be sure that DropDownList1.AutoPostBack = true

        If Not IsPostBack Then
            BindUserList()
        End If
    End Sub


    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox1.SelectedIndexChanged
        DisplayDetails(ComboBox1.SelectedValue)
    End Sub


    Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        Dim approved As Boolean = True
        Dim username As String = ComboBox1.SelectedValue
        Dim comments As String = tbComments.Text
        Dim email As String = tbEmail.Text

        UpdateUser(username, approved, comments, email)
    End Sub

    Private Sub BindUserList()
        '' you only need to databind once, the datasource is stored in viewstate
        Dim muc As MembershipUserCollection = Membership.GetAllUsers()

        ComboBox1.DataSource = muc
        ComboBox1.DataValueField = "UserName"
        ComboBox1.DataTextField = "UserName"
        ComboBox1.DataBind()
        '' initialize the selection
        ComboBox1_SelectedIndexChanged(ComboBox1, EventArgs.Empty)
    End Sub


    Private Sub DisplayDetails(ByVal userName As String)
        Dim mu As MembershipUser = Membership.GetUser(userName)

        Dim userRoles As String() = Roles.GetRolesForUser(userName)

        tbComments.Text = mu.Comment
        tbEmail.Text = mu.Email
        lblUserName.Text = mu.UserName
    End Sub

    Private Sub UpdateUser(ByVal userName As String, ByVal approved As Boolean, ByVal comments As String, ByVal email As String)
        Dim mu As MembershipUser = Membership.GetUser(userName)
        If Not mu Is Nothing Then
            Try

                mu.Comment = comments
                mu.Email = email
                mu.IsApproved = approved

                Membership.UpdateUser(mu)

                ErrLabel.Text = ""
            Catch ex As Exception
                ErrLabel.Text = ex.Message
            End Try
        End If
    End Sub
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="ComboBox1" runat="server" AutoPostBack="True">
        </asp:DropDownList>
    </div>
    <p>
        UserName:<asp:Label ID="lblUserName" runat="server" Text=""></asp:Label><br />
        Email:<asp:TextBox ID="tbEmail" runat="server"></asp:TextBox><br />
        Comments:<asp:TextBox ID="tbComments" runat="server"></asp:TextBox><br />
    </p>
    <asp:Button ID="Button1" runat="server" Text="Update" Height="26px" Width="61px" /><br />
    <asp:Label ID="ErrLabel" runat="server" Text=""></asp:Label>
    </form>
</body>
</html>
...