Странная проблема с обновлением 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" /> <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" /> <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()})";
}
Я бы предположил, что указание типа параметра позволило бы правильно обработать строковое значение, но установка типа ничего не изменила.