MissingMethodException[不能创建接口实例]被ASP选择性抛出..NET MVC控制器
本文关键字:选择性 NET 控制器 MVC ASP 不能 创建 接口 实例 MissingMethodException | 更新日期: 2023-09-27 18:10:00
我在MVC 4应用程序中得到奇怪的(至少对我来说)行为。
我整个晚上都在用谷歌搜索;我也读了很多SO帖子-没有乐趣;我知道我不能直接实例化一个接口。
在这个特殊的应用程序中,我使用Ninject作为DI。在控制器构造器中,我实例化了一个接口,在那一点上一切都很好——事实上,我相信Ninject或它的使用没有任何问题。
我也确信这段代码曾经工作过,从那以后没有任何变化,除了Ninject库更新到3.2.2.0 -不记得在那之前是哪个;
在使用我的另一个WEB服务的同一个控制器中有简单的CRUD操作。4个方法中有2个工作正确(LOL) - Index()
和Create()
。然而,Update()
和Delete()
抛出了上述异常;下面是堆栈跟踪:
[MissingMethodException: Cannot create an instance of an interface.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +119
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +11
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +183
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +563
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +416
.
.
.
这里是控制器,非常简单的一个,真的…
public class NonFederalWorkingDayController : BaseController
{
private readonly INonFederalWorkingDayManagementService _nonFederalWorkingDayService = null;
public NonFederalWorkingDayController(INonFederalWorkingDayManagementService nonFederalWorkingDayService)
{
_nonFederalWorkingDayService = nonFederalWorkingDayService;
}
private JsonResultModel<IEnumerable<NonFederalWorkingDayDto>> InvokeService(Func<IEnumerable<NonFederalWorkingDayDto>, I9UserDto, IEnumerable<NonFederalWorkingDayDto>> operation, IEnumerable<NonFederalWorkingDayDto> models)
{
var result = new JsonResultModel<IEnumerable<NonFederalWorkingDayDto>>();
if (ModelState.IsValid)
{
var modifier = new I9UserDto
{
Id = SiteContext.User.UserId
};
try
{
result.Model = operation(models, modifier);
result.Message = "Operation completed successfully.";
}
catch (Exception ex)
{
result.HasError = true;
#if DEBUG
result.Message = string.Concat("Operation failed: ", ex.Message);
#else
result.Message = "Operation failed: Internal server error.";
#endif
}
if (result.Model != null)
{
foreach (var dto in result.Model)
{
dto.CreatedOn = null;
dto.Creator = null;
dto.ModifiedOn = null;
dto.Modifier = null;
}
}
}
else
{
result.HasError = true;
result.Message = "Invalid data.";
}
return result;
}
public ActionResult Index()
{
var model = _nonFederalWorkingDayService.Load();
return View(model);
}
[HttpPost]
public ActionResult Create(IEnumerable<NonFederalWorkingDayDto> models)
{
var result = InvokeService(_nonFederalWorkingDayService.Create, models);
return Json(result);
}
[HttpPost]
public ActionResult Update(IEnumerable<NonFederalWorkingDayDto> models)
{
var result = InvokeService(_nonFederalWorkingDayService.Update, models);
return Json(result);
}
[HttpPost]
public ActionResult Delete(IEnumerable<NonFederalWorkingDayDto> models)
{
var result = InvokeService(_nonFederalWorkingDayService.Delete, models);
if (!result.HasError)
{
var plurality = models.Count() == 1 ? "Entity" : "Entities";
result.Message = string.Concat(plurality, " deleted successfully.");
}
return Json(result);
}
}
正如我提到的,问题在于最后两个方法:Update()
和Delete()
。实际上,执行永远不会进入其中的任何一个—在模型绑定期间会引发错误。但是请注意,除了IEnumerable<>
之外,没有其他接口可以很好地绑定到同一应用程序中的其他方法中,包括这个控制器中的Create()
方法。我不确定具体是怎么回事,但DefaultBinder
似乎足够聪明,可以看出IEnumerable
实际上是List
。所以不应该是这样,对吧?
另外,我需要说明的是,我是通过AJAX调用这些操作的,而不是普通的请求。这重要吗?
我似乎不知道怎么了…请帮助!
我继承了DefaultModelBinder
,以便挂钩到模型绑定管道。所以我连接到BindModel()
controllerContext.Controller
实际上是NonFederalWorkingDayController
的全功能实例
更新2
以下是NonFederalWorkingDayDto
的代码清单:
public class NonFederalWorkingDayDto : DtoBase, INonFederalWorkingDay
{
public static NonFederalWorkingDayDto Consume(INonFederalWorkingDay Donor)
{
NonFederalWorkingDayDto result = null;
if (Donor != null)
{
result = DtoBase.Consume<NonFederalWorkingDayDto>(Donor);
result.Description = Donor.Description;
result.FallsOn = Donor.FallsOn;
result.Id = Donor.Id;
result.Name = Donor.Name;
}
return result;
}
public string Description { get; set; }
public DateTime? FallsOn { get; set; }
public string Name { get; set; }
#region INonFederalWorkingDay support
DateTime INonFederalWorkingDay.FallsOn
{
get { return FallsOn ?? default(DateTime); }
}
int IIdentifier<int>.Id
{
get { return Id ?? default(int); }
}
#endregion
}
我认为你的动作声明是问题,尝试:
[HttpPost]
public ActionResult Create(List<NonFederalWorkingDayDto> models)
{
...
}
[HttpPost]
public ActionResult Update(List<NonFederalWorkingDayDto> models)
{
...
}
[HttpPost]
public ActionResult Delete(List<NonFederalWorkingDayDto> models)
{
...
}
真正的解释是在消息中,即它不能创建接口的实例,正如你所说的构造函数很酷,所以问题在于IEnumerable需要是一个具体的可枚举类(如List)。