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
}

MissingMethodException[不能创建接口实例]被ASP选择性抛出..NET MVC控制器

我认为你的动作声明是问题,尝试:

[HttpPost]
public ActionResult Create(List<NonFederalWorkingDayDto> models)
{
    ...
}
[HttpPost]
public ActionResult Update(List<NonFederalWorkingDayDto> models)
{
    ...
}
[HttpPost]
public ActionResult Delete(List<NonFederalWorkingDayDto> models)
{
    ...
}

真正的解释是在消息中,即它不能创建接口的实例,正如你所说的构造函数很酷,所以问题在于IEnumerable需要是一个具体的可枚举类(如List)。