Обновление FormView успешно, но вставка нулей для определенного столбца - PullRequest
0 голосов
/ 30 октября 2018

Странная проблема с обновлением FormView в режиме редактирования. Я раньше использовал форму просмотра, и в настоящее время он работает в другом проекте.

Сейчас работаю над другим проектом - я начал с 5 или 6 столбцов в EditItemTemplate, все они были типами валют, за исключением 1 столбца, который является nvarchar (50). Мое заявление об обновлении успешно, и все столбцы будут Обновление кроме одного. Для столбца («QBooksEnteredBy», nvarchar (50)) в столбец таблицы вставляется значение NULL вместо значения, введенного в текстовое поле. Я удалил все остальные поля из приведенного ниже кода, чтобы сделать код максимально простым.

У меня есть код в событии FormView ItemUpdated, чтобы проверить наличие исключений и распечатать старые и новые значения из словарей. Нет исключений. Я даже заполнил столбец, который я пытаюсь изменить в режиме редактирования, чтобы избежать возможных проблем с нулевым значением, но я все равно получаю тот же результат. Строка / столбец базы данных обновляется со значением NULL независимо от того, что я ввожу в текстовое поле.

Я также попытался указать тип параметра, без изменений в поведении. Результат выполнения того же кода (напечатанного на странице): Запись 1182 успешно обновлена. Старое значение =, новое значение = томас

Я поместил этот код в новый проект Asp.Net WebForms, чтобы попытаться исключить любое вмешательство со стороны мастер-страниц и т. Д. Тот же результат. Я попытался изменить целевой фреймворк на 4.0 и 4.6.1. Framework 4.0 используется моим рабочим проектом.

Буду признателен за любой вклад, который я могу получить!

Страница Aspx:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication2.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
     <form id="form1" runat="server">
         <div class="admin_block">
     <asp:HiddenField runat="server" ID="userNameField" ClientIDMode="Static" />
     <asp:Label runat="server" ID="MessageLabel" />
    <br />
    <br />
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" 
        PageSize="20" OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
        OnPageIndexChanged="GridView1_PageIndexChanged"
        OnDataBound="GridView1_DataBound"
        OnRowDataBound="GridView1_RowDataBound"
        DataSourceID="SqlDataSource1">
        <Columns>
            <asp:ButtonField Text="View..." HeaderText="Details" ButtonType="Link" HeaderStyle-HorizontalAlign="Center" CommandName="Select"  >  
                    <ItemStyle Width="80px" HorizontalAlign="Left" />
                    <HeaderStyle Font-Names="Segoe UI" Font-Size="Medium" Font-Bold="false" />
                </asp:ButtonField>
            <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
            <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
            <asp:BoundField DataField="DonationAmount" HeaderText="DonationAmount" SortExpression="DonationAmount" />
            <asp:BoundField DataField="MultiYear" HeaderText="MultiYear" SortExpression="MultiYear" ReadOnly="True" />
            <asp:BoundField DataField="DonationDate" HeaderText="DonationDate" SortExpression="DonationDate" />
            <asp:BoundField DataField="CommitmentDate" HeaderText="CommitmentDate" SortExpression="CommitmentDate" />
            <asp:BoundField DataField="Approved" HeaderText="Approved" SortExpression="Approved" ReadOnly="True" />
        </Columns>
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyDB %>" 
        SelectCommand="SELECT Donations.ID, don.CompanyName, Donations.DonationAmount, (CASE WHEN Donations.MultiYear = 'True' THEN 'Yes' ELSE 'No' END) AS MultiYear, Donations.DonationDate, Donations.CommitmentDate, (CASE WHEN Donations.Approved = 'True' THEN 'Yes' ELSE 'No' END) As Approved FROM Donations INNER JOIN DonationMethods dm ON dm.ID = Donations.DonationMethodID INNER JOIN Donors don ON don.AspNetUserID = Donations.AspNetUserID INNER JOIN DonorTypes types ON types.ID = Donations.DonorTypeID AND Donations.DonorTypeID = 3"></asp:SqlDataSource>

    <asp:FormView ID="FormView1" runat="server"
        OnItemUpdating="FormView1_ItemUpdating"
        OnItemUpdated="FormView1_ItemUpdated"
        OnDataBound="FormView1_DataBound"
        DataSourceID="SqlDataSourceDetails" DataKeyNames="ID">
        <EditItemTemplate>
            ID:
            <asp:Label Text='<%# Eval("ID") %>' runat="server" ID="IDLabel1" /><br />
            QBooksEnteredBy:
            <asp:TextBox Text='<%# Bind("QBooksEnteredBy") %>' runat="server" ID="QBooksEnteredByTextBox" /><br />

            <asp:LinkButton runat="server" Text="Update" CommandName="Update" ID="UpdateButton" CausesValidation="True" />&nbsp;<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" ID="UpdateCancelButton" CausesValidation="False" />
        </EditItemTemplate>
        <InsertItemTemplate>
            QBooksEnteredBy:
            <asp:TextBox Text='<%# Bind("QBooksEnteredBy") %>' runat="server" ID="QBooksEnteredByTextBox" /><br />
            <asp:LinkButton runat="server" Text="Insert" CommandName="Insert" ID="InsertButton" CausesValidation="True" />&nbsp;<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" ID="InsertCancelButton" CausesValidation="False" />
        </InsertItemTemplate>
        <ItemTemplate>
            ID:
            <asp:Label Text='<%# Eval("ID") %>' runat="server" ID="IDLabel" /><br />
            QBooksEnteredBy:
            <asp:Label Text='<%# Bind("QBooksEnteredBy") %>' runat="server" ID="QBooksEnteredByLabel" /><br />
            created_datetime: 
            created_datetime:
            <asp:Label Text='<%# Bind("created_datetime") %>' runat="server" ID="created_datetimeLabel" /><br />
            update_datetime:
            <asp:Label Text='<%# Bind("update_datetime") %>' runat="server" ID="update_datetimeLabel" /><br />
            <asp:LinkButton runat="server" Text="Edit" CommandName="Edit" ID="EditButton" CausesValidation="False" />
        </ItemTemplate>
    </asp:FormView>
    <br /><br />

    <asp:SqlDataSource ID="SqlDataSourceDetails" runat="server" ConnectionString="<%$ ConnectionStrings:GODonationsDB %>" 
        SelectCommand="SELECT ID, DonationAmount, DonationNet, QBooksEnteredBy, DonorChoiceUndesAmt, ForcedUndesAmt, created_datetime, update_datetime FROM Donations WHERE [ID] = @ID" 
        UpdateCommand="UPDATE [Donations] SET [QBooksEnteredBy] = @qbEnteredBy WHERE [ID] = @id"
        OnUpdating="SqlDataSourceDetails_Updating">
        <SelectParameters>
            <asp:FormParameter FormField="IDLabel" DefaultValue="0" Name="ID" Type="Int32"></asp:FormParameter>
        </SelectParameters>
        <UpdateParameters>
            <asp:Parameter Name="qbEnteredBy" Type="String" />
            <asp:Parameter Name="id" Type="Int32" />
        </UpdateParameters>
    </asp:SqlDataSource>
         </div>
    </form>
</body>
</html>

Код сзади:

    using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        private int _firstId = 0;
        //private DataClass _dataClass = new DataClass();
        //private AdminCenter _master = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {


                userNameField.Value = "myemail@outlook.com";

            }
        }

        protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (null != GridView1.SelectedValue)
            {
                SqlDataSourceDetails.SelectParameters["ID"].DefaultValue = GridView1.SelectedValue.ToString();
            }
            FormView1.DataBind();
        }

        protected void GridView1_PageIndexChanged(object sender, EventArgs e)
        {

        }

        protected void GridView1_DataBound(object sender, EventArgs e)
        {
            if (GridView1.Rows.Count > 0)
            {
                if (GridView1.SelectedIndex < 0)
                {
                    // No rows selected when first displayed, so select the first row and set the DataKey
                    // value in the datasource for the details view.
                    _firstId = Convert.ToInt32(GridView1.Rows[0].Cells[1].Text.ToString());
                    SqlDataSourceDetails.SelectParameters["ID"].DefaultValue = _firstId.ToString();
                    GridView1.SelectedIndex = 0;
                }

                //rowCountLabel.Text = "Contributors: " + _dataClass.GetRowCount(PatientSqlDataSource.SelectCommand);
            }
            else
            {
                //rowCountLabel.Text = string.Empty;
            }
        }

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {

        }

        protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
        {


        }

        protected void FormView1_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
        {
            // Use the Exception property to determine whether an exception
            // occurred during the update operation.
            if (e.Exception == null)
            {
                // Sometimes an error might occur that does not raise an 
                // exception, but prevents the update operation from 
                // completing. Use the AffectedRows property to determine 
                // whether the record was actually updated. 
                if (e.AffectedRows == 1)
                {
                    // Use the Keys property to get the value of the key field.
                    String keyFieldValue = e.Keys["ID"].ToString();

                    // Display a confirmation message.
                    MessageLabel.Text = "Record " + keyFieldValue +
                      " updated successfully. ";

                    // Display the new and original values.
                    DisplayValues((OrderedDictionary)e.NewValues, (OrderedDictionary)e.OldValues);
                }
                else
                {
                    // Display an error message.
                    MessageLabel.Text = "An error occurred during the update operation.";

                    // When an error occurs, keep the FormView
                    // control in edit mode.
                    e.KeepInEditMode = true;
                }
            }
            else
            {
                // Insert the code to handle the exception.
                MessageLabel.Text = e.Exception.Message;

                // Use the ExceptionHandled property to indicate that the 
                // exception has already been handled.
                e.ExceptionHandled = true;

                e.KeepInEditMode = true;
            }
        }

        protected void FormView1_DataBound(object sender, EventArgs e)
        {

        }

        void DisplayValues(OrderedDictionary newValues, OrderedDictionary oldValues)
        {

            MessageLabel.Text += "<br/></br>";

            // Iterate through the new and old values. Display the
            // values on the page.
            for (int i = 0; i < oldValues.Count; i++)
            {
                MessageLabel.Text += "Old Value=" + oldValues[i].ToString() +
                  ", New Value=" + newValues[i].ToString() + "<br/>";
            }

            MessageLabel.Text += "</br>";

        }

        protected void SqlDataSourceDetails_Updating(object sender, SqlDataSourceCommandEventArgs e)
        {
        }
    }
}

ВОЗМОЖНОЕ РЕШЕНИЕ: Разница между полями, которые будут обновлены, и полем, которое не будет, является валютой / строкой, соответственно. Я перехватил команду обновления в событии SqlDataSource_Updating и переопределил, используя значения поля EditItemTemplate с добавлением одинарных кавычек вокруг значения текстового поля "QBooksEnteredBy":

protected void SqlDataSourceDetails_Updating(object sender, SqlDataSourceCommandEventArgs e)
    {
        e.Command.CommandText = $@"UPDATE [Donations] SET [QBooksEnteredBy] = '{(FormView1.FindControl("QBooksEnteredByTextBox") 
            as TextBox).Text.ToString()}' WHERE ([ID] = {(FormView1.FindControl("IDLabel1") as Label).Text.ToString()})";
    }

Я бы предположил, что указание типа параметра позволило бы правильно обработать строковое значение, но установка типа ничего не изменила.

...