我在MVC 4应用程序中变得很奇怪(至少对我而言)。
我整个晚上都在谷歌上搜索;我也阅读了很多SO帖子 - 没有快乐;我知道我不能直接实例化接口。
在这个特定的应用程序中,我使用Ninject进行DI。 在控制器构造函数中,我实现了一个接口,并且此时一切都很好 - 实际上我相信Ninject或它的用法根本没有问题。
此外,我确信这段代码工作一次,之后没有引入任何更改,除非将Ninject库更新到3.2.2.0 - 无法记住之前的那个;显然年纪大了...
我在同一个控制器中有简单的CRUD操作,它占用了我的另一个WEB服务。 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
}
答案 0 :(得分:0)
我认为您的行动声明是问题,请尝试:
[HttpPost]
public ActionResult Create(List<NonFederalWorkingDayDto> models)
{
...
}
[HttpPost]
public ActionResult Update(List<NonFederalWorkingDayDto> models)
{
...
}
[HttpPost]
public ActionResult Delete(List<NonFederalWorkingDayDto> models)
{
...
}
真的解释是在消息中,即它不能创建接口的实例,因为你说构造函数很酷,所以问题在于IEnumerable,它需要是一个具体的可枚举类(如List for例子)。