Обновление ASP.NET GridView с использованием Entity Framework и ObjectDataSource
Я новичок в Entity Framework и ObjectDataSource. Я пытаюсь заставить свою сетку обновить элемент, но получаю следующую ошибку. Что я делаю неправильно?
Ошибка сервера в приложении '/' В экземпляре объекта не задана ссылка на объект. Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде. Сведения об исключении: System.NullReferenceException: ссылка на объект не установлена для экземпляра объекта. Ошибка источника: Во время выполнения текущего веб-запроса было сгенерировано необработанное исключение. Информация о происхождении и местоположении исключения может быть идентифицирована с помощью трассировки стека исключений ниже. Трассировки стека: [NullReferenceException: ссылка на объект не установлена для экземпляра объекта.] GalleryApp.Logic.FileActions.UpdateFile(GalleryItemFile newFile) +377 [TargetInvocationException: исключение было выдано целью вызова.] System.RuntimeMethodHandle.InvokeMethod(цель объекта, аргументы объекта [], сигнатура сигнатуры, логический конструктор) +0 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(параметры объекта, параметры объекта [], параметры объекта []) +92 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder Binder, параметры Object[], CultureInfo culture) +108 System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(метод ObjectDataSourceMethod, логический тип disposeInstance, объект и экземпляр) +487 System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(метод ObjectDataSourceMethod) +39 System.Web.UI.WebControls.ObjectDataSourceView.ExecuteUpdate(ключи IDictionary, значения IDictionary, IDictionary oldValues) +1830 System.Web.UI.DataSourceView.Update(ключи IDictionary, значения IDictionary, обратный вызов Dataictionary oldValues, DataSourceViewOperationCallback) +87 System.Web.UI.WebControls.GridView.HandleUpdate(строка GridViewRow, Int32 rowIndex, логические причины Validation) +1210 System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, логические причины, проверка, строка проверки группы) +738 System.Web.UI.WebControls.GridView.OnBubbleEvent(Источник объекта, EventArgs e) +89 System.Web.UI.Control.RaiseBubbleEvent(Источник объекта, аргументы EventArgs) +37 System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Источник объекта, EventArgs e) +88 System.Web.UI.Control.RaiseBubbleEvent(Источник объекта, аргументы EventArgs) +37 System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +121 System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +156 System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13 System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +9642610 System.Web.UI.Page.ProcessRequestMain(логическое значение includeStagesBeforeAsyncPoint, логическое значение includeStagesAfterAsyncPoint) +1724 Информация о версии: Microsoft .NET Framework Версия:4.0.30319; ASP.NET версия:4.0.30319.18056
Вот мой код из ASPX.
<asp:GridView runat="server" DataSourceID="dsFiles" ID="gvFiles"
EmptyDataText="No Files Associated with this gallery item yet."
DataKeyNames="fileID,galleryItem" AutoGenerateColumns="false" CssClass="formtable" OnRowUpdating="gvFiles_RowUpdating">
<Columns>
<asp:BoundField HeaderText="filename" DataField="filename" />
<asp:TemplateField HeaderText="File Type" SortExpression="fileType">
<ItemTemplate>
<%# Eval("FileType.fileType") %>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList runat="server" ID="cboFileType" DataSourceID="dsFileTypes" DataTextField="fileType" DataValueField="fileTypeID" SelectedValue='<%# Eval("FileType.fileTypeID") %>' />
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList runat="server" ID="cboFileType" DataSourceID="dsFileTypes" DataTextField="fileType" DataValueField="fileTypeID" SelectedValue='<%# Bind("FileType.fileTypeID") %>' />
</InsertItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Active" DataField="active" />
<asp:BoundField HeaderText="Resolution" DataField="resolution" />
<asp:CommandField ShowDeleteButton="true" ShowEditButton="true" ShowHeader="true" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource runat="server" ID="dsFiles"
TypeName="GalleryApp.Logic.FileActions"
DataObjectTypeName="GalleryApp.Models.GalleryItemFile"
SelectMethod="GetFiles"
InsertMethod="AddFile"
UpdateMethod="UpdateFile"
DeleteMethod="DeleteFile" OnUpdating="dsFiles_Updating">
<SelectParameters>
<asp:ControlParameter Name="galleryItemID" ControlID="hidGalleryItemID" Type="Int32" />
</SelectParameters>
<InsertParameters>
<asp:ControlParameter Name="galleryItemID" ControlID="hidGalleryItemID" Type="Int32" />
<asp:Parameter Name="fileTypeID" Type="Int32" />
<asp:Parameter Name="filename" Type="String" />
<asp:Parameter Name="active" Type="Boolean" />
<asp:CookieParameter Name="userCommonName" Type="String" />
<asp:Parameter Name="resolution" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="fileID" Type="Int32" />
<asp:ControlParameter Name="galleryItemID" ControlID="hidGalleryItemID" Type="Int32" />
<asp:Parameter Name="fileTypeID" Type="Int32" />
<asp:Parameter Name="filename" Type="String" />
<asp:Parameter Name="active" Type="Boolean" />
<asp:CookieParameter Name="userCommonName" Type="String" />
<asp:Parameter Name="resolution" Type="String" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="fileID" Type="Int32" />
</DeleteParameters>
</asp:ObjectDataSource>
<asp:ObjectDataSource runat="server" ID="dsFileTypes"
TypeName="GalleryApp.Logic.FileTypeActions"
DataObjectTypeName="GalleryApp.Models.FileType"
SelectMethod="GetFileTypes">
</asp:ObjectDataSource>
FileActions - мой класс логики. Я переключил все методы на статические, потому что видел это в одном примере, но это ничего не изменило. Я предполагаю, что речь идет об объекте GalleryItemFile, который является одним из объектов.
Сетка загружается, нажмите "Изменить", затем измените имя файла и нажмите "Сохранить", и я получаю желтый экран.
РЕДАКТИРОВАТЬ: Вот функция, которая вызывается. Исключение происходит через строку после первого "else".
public static GalleryItemFile UpdateFile(GalleryItemFile newFile)
{
GalleryContext _db = new GalleryContext();
_db.Database.Log = HttpContext.Current.Response.Write; //Used for Tracing SQL
int saved = 0;
GalleryItemFile origFile = _db.GalleryItemFiles.FirstOrDefault(g => g.fileID == newFile.fileID);
HttpContext.Current.Response.Write(origFile.filename);
if (origFile == null)
{
//ITEM NOT FOUND
}
else
{
origFile.galleryItem.galleryItemID = newFile.galleryItem.galleryItemID;
origFile.fileType.fileTypeID = newFile.fileType.fileTypeID;
origFile.filename = newFile.filename;
origFile.active = newFile.active;
origFile.createdOn = DateTime.Now;
origFile.createdBy = newFile.createdBy;
origFile.resolution = newFile.resolution;
saved = _db.SaveChanges();
}
if (saved > 0)
{
return origFile;
}
else { return null; }
}
Во время отладки я убедился, что файл origFile восстанавливается правильно. Это новый файл, который был отправлен из ObjectDataSource, который, кажется, генерирует нулевую ссылку.
РЕДАКТИРОВАТЬ: Вот модель для GalleryItemFile.
Опять же, я новичок в Entity Framework, но я подумал, что он автоматически загрузит galleryItem.
namespace GalleryApp.Models
{
[Serializable]
public class GalleryItemFile
{
[Key]
public int fileID { get; set; }
public virtual GalleryItem galleryItem { get; set; }
public virtual FileType fileType { get; set; }
[MaxLength(75)] public string filename { get; set; }
public bool active { get; set; }
public DateTime? createdOn { get; set; }
[MaxLength(150)] public string createdBy { get; set; }
[MaxLength(50)] public string resolution { get; set; }
}
}
namespace GalleryApp.Models
{
[Serializable]
public class FileType
{
[Key]
public int fileTypeID { get; set; }
[MaxLength(50)] public string fileType { get; set; }
[MaxLength(15)] public string extension { get; set; }
[MaxLength(250)] public string icon { get; set; }
[MaxLength(400)] public string description { get; set; }
[MaxLength(400)] public string warnings { get; set; }
}
}
Ошибка сервера в приложении '/' В экземпляре объекта не задана ссылка на объект. Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде. Сведения об исключении: System.NullReferenceException: ссылка на объект не установлена для экземпляра объекта. Ошибка источника: Строка 160: { Строка 161: origFile.galleryItem.galleryItemID = newFile.galleryItem.galleryItemID; Строка 162: origFile.fileType.fileTypeID = newFile.fileType.fileTypeID; Строка 163: origFile.filename = newFile.filename; Строка 164: origFile.active = newFile.active; Исходный файл: c:\Users\holcombelr\SkyDrive\Public\Projects\UHV\GalleryApp\Logic\GalleryItemFileActions.cs Строка: 162 Трассировки стека: [NullReferenceException: ссылка на объект не установлена для экземпляра объекта.] GalleryApp.Logic.FileActions.UpdateFile (GalleryItemFile newFile) в каталоге c:\Users\holcombelr\SkyDrive\Public\Projects\UHV\GalleryApp\Logic\GalleryItemFileActions.cs:162
Здесь больше информации. Добавление serializable сделало меня на один шаг ближе, но теперь ошибка находится на следующей строке, и я теперь добавил сериализуемый для всех своих объектов.
РЕДАКТИРОВАТЬ: У кого-нибудь есть ответ на это? У меня все еще есть проблема.
1 ответ
Я думаю, что я понял это. Очевидно, что когда у вас есть подобъекты, подобные этим, вы должны включить объекты в DataKeyNames вида сетки.