在Visual Studio 2012中开发Webforms站点时,在将方法注册到ListView的UpdateMethod参数时遇到以下错误:
Constructor on type 'System.Web.UI.WebControls.ListViewUpdateEventArgs' not found.
堆栈跟踪:
[MissingMethodException: Constructor on type 'System.Web.UI.WebControls.ListViewUpdateEventArgs' not found.]
System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark) +1136
System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) +128
System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) +18
System.Web.SecurityUtils.SecureCreateInstance(Type type, Object[] args, Boolean allowNonPublic) +104
System.Web.ModelBinding.MutableObjectModelBinder.CreateModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) +26
System.Web.ModelBinding.MutableObjectModelBinder.EnsureModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) +42
System.Web.ModelBinding.MutableObjectModelBinder.BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) +37
System.Web.ModelBinding.DefaultModelBinder.BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext) +196
System.Web.UI.WebControls.ModelDataSourceView.EvaluateMethodParameters(DataSourceOperation dataSourceOperation, ModelDataSourceMethod modelDataSourceMethod, IDictionary controlValues, Boolean isPageLoadComplete) +996
System.Web.UI.WebControls.ModelDataSourceView.EvaluateMethodParameters(DataSourceOperation dataSourceOperation, ModelDataSourceMethod modelDataSourceMethod, IDictionary controlValues) +18
System.Web.UI.WebControls.ModelDataSourceView.EvaluateUpdateMethodParameters(IDictionary keys, IDictionary values, IDictionary oldValues) +144
System.Web.UI.WebControls.ModelDataSourceView.GetUpdateMethodResult(IDictionary keys, IDictionary values, IDictionary oldValues) +21
System.Web.UI.WebControls.ModelDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) +23
System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values, IDictionary oldValues, DataSourceViewOperationCallback callback) +87
System.Web.UI.WebControls.ListView.HandleUpdate(ListViewItem item, Int32 itemIndex, Boolean causesValidation) +1643
System.Web.UI.WebControls.ListView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +1070
System.Web.UI.WebControls.ListView.OnBubbleEvent(Object source, EventArgs e) +315
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
System.Web.UI.WebControls.ListViewDataItem.OnBubbleEvent(Object source, EventArgs e) +141
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) +114
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +159
System.Web.UI.WebControls.Button.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) +35
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724
项目配置为.NET 4.5编译,据我所知,所需的构造函数应该存在。以下是从MetaData检索的ListViewUpdateEventArgs的定义:
#region Assembly System.Web.Extensions.dll, v4.0.0.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.Extensions.dll
#endregion
using System;
using System.Collections.Specialized;
using System.ComponentModel;
namespace System.Web.UI.WebControls
{
// Summary:
// Provides data for the System.Web.UI.WebControls.ListView.ItemUpdating event.
public class ListViewUpdateEventArgs : CancelEventArgs
{
// Summary:
// Initializes a new instance of the System.Web.UI.WebControls.ListViewUpdateEventArgs
// class.
//
// Parameters:
// itemIndex:
// The index of the item being updated.
public ListViewUpdateEventArgs(int itemIndex);
// Summary:
// Gets the index of the data item that is being updated.
//
// Returns:
// The index of the data item that is being updated.
public int ItemIndex { get; }
//
// Summary:
// Gets a dictionary of field name/value pairs that represent the key or keys
// of the item to update.
//
// Returns:
// The field name/value pairs that represent the key or keys of the item to
// update.
public IOrderedDictionary Keys { get; }
//
// Summary:
// Gets a dictionary that contains the revised values of the item to update.
//
// Returns:
// The revised values of the item to update.
public IOrderedDictionary NewValues { get; }
//
// Summary:
// Gets a dictionary that contains the original values of the item to update.
//
// Returns:
// The original values of the item to update.
public IOrderedDictionary OldValues { get; }
}
}
以下是我的观点:
<%@ Page
Title="View Blog Post"
Language="C#"
MasterPageFile="~/Site.Master"
AutoEventWireup="true"
CodeBehind="Record.aspx.cs"
Inherits="Pritchard.Jumpstart.Webforms.BlogPost.Record"
%>
<%@ Import Namespace="Microsoft.AspNet.FriendlyUrls" %>
<%@ Import Namespace="Pritchard.Jumpstart.Common.Data" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:ListView runat="server"
ID="BlogPostContainer"
ItemType="Pritchard.Jumpstart.Common.Data.BlogPost"
ItemPlaceholderID="BlogPost"
SelectMethod="GetBlogPost"
UpdateMethod="UpdateBlogPost"
InsertMethod="InsertBlogPost">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="BlogPost" />
</LayoutTemplate>
<EmptyDataTemplate>
Sorry. There are no blog posts to show.
</EmptyDataTemplate>
<ItemTemplate>
<h2>
<%# Item.Title %>
</h2>
<p>
<strong>Author:</strong> <%# Item.Author %>
<br />
<strong>Created On:</strong> <%# Item.CreatedOn %>
</p>
<p>
<strong>Post Summary</strong>
<br />
<%# Item.Summary %>
</p>
<p>
<strong>Full Text</strong>
<br />
<%# Item.FullText %>
</p>
<p>
<strong>Tags</strong>
<br />
<%# Item.Tags %>
</p>
</ItemTemplate>
<EditItemTemplate>
<h2>
Edit Blog Post
</h2>
Title:
<asp:TextBox runat="server" ID="BlogTitle" ClientIDMode="Static" Text='<%# Bind("Title") %>' />
<br />
Author:
<asp:TextBox runat="server" ID="Author" ClientIDMode="Static" Text='<%# Bind("Author") %>' />
<br />
Text:
<asp:TextBox runat="server" ID="FullText" ClientIDMode="Static" Text='<%# Bind("FullText") %>' TextMode="MultiLine" />
<br />
Tags:
<asp:TextBox runat="server" ID="Tags" ClientIDMode="Static" Text='<%# Bind("Tags") %>' />
<br />
<asp:Button runat="server" CommandName="Update" Text="Update" />
<asp:Button ID="Button1" runat="server" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
</asp:ListView>
</asp:Content>
这是我的代码隐藏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.AspNet.FriendlyUrls;
using Pritchard.Jumpstart.Common.Data.Services;
using Pritchard.Jumpstart.Webforms.Common;
namespace Pritchard.Jumpstart.Webforms.BlogPost
{
public partial class Record : BasePage
{
private int id = 0;
protected void Page_Load(object sender, EventArgs e)
{
var mode = "read";
Int32.TryParse(Request.GetFriendlyUrlSegments().FirstOrDefault(), out id);
mode = Request.QueryString["mode"];
switch (mode)
{
case "read":
break;
case "update":
BlogPostContainer.EditIndex = 0;
break;
case "insert":
break;
}
if (id != 0)
Model = BlogPostService.Get(id);
}
public IEnumerable<Jumpstart.Common.Data.BlogPost> GetBlogPost()
{
var list = new List<Jumpstart.Common.Data.BlogPost>();
var item = BlogPostService.Get(id);
if (item != null)
list.Add(item);
return list;
}
public void UpdateBlogPost(Object sender, ListViewUpdateEventArgs args)
{
var blogPost = (Jumpstart.Common.Data.BlogPost) args.NewValues[0];
BlogPostService.Update(blogPost);
}
public void InsertBlogPost()
{
throw new NotImplementedException();
}
}
}
其他详情:
我环境中的所有内容似乎都设置为.NET 4.5。我已尽可能彻底地检查了这一点。
使用FormView而不是ListView会导致同样的问题。
使用替代的UpdateMethod签名(int id)会导致将null id传递给已注册的UpdateMethod。
答案 0 :(得分:0)
这个修改过的代码有效,但它绝对不是我想要的解决方案。我不得不使用ListView / FormView模型绑定并改为使用ObjectDataSource。:
查看:
<%@ Page
Title="View Blog Post"
Language="C#"
MasterPageFile="~/Site.Master"
AutoEventWireup="true"
CodeBehind="Record.aspx.cs"
Inherits="Pritchard.Jumpstart.Webforms.BlogPost.Record"
%>
<%@ Import Namespace="Microsoft.AspNet.FriendlyUrls" %>
<%@ Import Namespace="Pritchard.Jumpstart.Common.Data" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:ObjectDataSource ID="BlogPostDataSource" runat="server"
SelectMethod="GetBlogPost"
InsertMethod="InsertBlogPost"
UpdateMethod="UpdateBlogPost"
TypeName="Pritchard.Jumpstart.Webforms.BlogPost.Record"
DataObjectTypeName="Pritchard.Jumpstart.Common.Data.BlogPost" />
<asp:FormView runat="server"
ID="BlogPostContainer"
ItemType="Pritchard.Jumpstart.Common.Data.BlogPost"
ItemPlaceholderID="BlogPost"
DataSourceID="BlogPostDataSource"
DataKeyNames="PostID" >
<EmptyDataTemplate>
Sorry. There are no blog posts to show.
</EmptyDataTemplate>
<ItemTemplate>
<h2>
<%# Item.Title %>
</h2>
<p>
<strong>Author:</strong> <%# Item.Author %>
<br />
<strong>Created On:</strong> <%# Item.CreatedOn %>
</p>
<p>
<strong>Post Summary</strong>
<br />
<%# Item.Summary %>
</p>
<p>
<strong>Full Text</strong>
<br />
<%# Item.FullText %>
</p>
<p>
<strong>Tags</strong>
<br />
<%# Item.Tags %>
</p>
</ItemTemplate>
<EditItemTemplate>
<asp:HiddenField runat="server" ID="PostID" Value='<%# Bind("PostID") %>'/>
<asp:HiddenField runat="server" ID="CreatedOn" Value='<%# Bind("CreatedOn") %>'/>
<asp:HiddenField runat="server" ID="CustomCSS" Value='<%# Bind("CustomCSS") %>'/>
<asp:HiddenField runat="server" ID="CustomJavaScript" Value='<%# Bind("CustomJavaScript") %>'/>
<asp:HiddenField runat="server" ID="Inactive" Value='<%# Bind("Inactive") %>'/>
<asp:HiddenField runat="server" ID="PermanentURL" Value='<%# Bind("PermanentURL") %>'/>
<h2>
Edit Blog Post
</h2>
Title:
<asp:TextBox runat="server" ID="BlogTitle" ClientIDMode="Static" Text='<%# Bind("Title") %>' />
<br />
Author:
<asp:TextBox runat="server" ID="Author" ClientIDMode="Static" Text='<%# Bind("Author") %>' />
<br />
Text:
<asp:TextBox runat="server" ID="FullText" ClientIDMode="Static" Text='<%# Bind("FullText") %>' TextMode="MultiLine" />
<br />
Tags:
<asp:TextBox runat="server" ID="Tags" ClientIDMode="Static" Text='<%# Bind("Tags") %>' />
<br />
<asp:Button runat="server" CommandName="Update" Text="Update" />
<asp:Button ID="Button1" runat="server" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
</asp:FormView>
</asp:Content>
代码隐藏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.AspNet.FriendlyUrls;
using Pritchard.Jumpstart.Common.Data.Services;
using Pritchard.Jumpstart.Webforms.Common;
namespace Pritchard.Jumpstart.Webforms.BlogPost
{
public partial class Record : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
var id = 0;
var mode = "read";
Int32.TryParse(Request.GetFriendlyUrlSegments().FirstOrDefault(), out id);
mode = Request.QueryString["mode"];
switch (mode)
{
case "read":
break;
case "update":
BlogPostContainer.DefaultMode = FormViewMode.Edit;
break;
case "insert":
break;
}
if (id != 0)
Model = BlogPostService.Get(id);
}
public IEnumerable<Jumpstart.Common.Data.BlogPost> GetBlogPost()
{
var list = new List<Jumpstart.Common.Data.BlogPost>();
var item = BlogPostService.Get( ((Jumpstart.Common.Data.BlogPost)Model).PostID);
if (item != null)
list.Add(item);
return list;
}
public void UpdateBlogPost(Jumpstart.Common.Data.BlogPost blogPost)
{
BlogPostService.Update(blogPost);
}
public void InsertBlogPost(Jumpstart.Common.Data.BlogPost blogPost)
{
throw new NotImplementedException();
}
}
}
请注意,我必须将“Model”属性移动到Session中,因为ViewState没有保留它:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.AspNet.FriendlyUrls;
namespace Pritchard.Jumpstart.Webforms.Common
{
public class BasePage : System.Web.UI.Page
{
public object Model
{
get { return Session["Model"]; }
set { Session["Model"] = value; }
}
}
}
这里发生了什么?我真的希望只在ListView中使用新的ASP.NET 4.5模型绑定。现在我必须使用单独的数据源?为什么呢?