MVC 3 passing entity as an Interface

不羁岁月 提交于 2019-12-10 14:44:42

问题


I'm currently working on an MVC 3 project using Ninject as my DI, the business objects are stored in a separate assembly. I'm running into an issue with the controller parameters, when posting back for CRUD operations I'm getting the error "Cannot create an instance of an interface". I am aware that you can't create an instance of an interface, but it seems like the only way I can get around this is to use a custom model binder and pass the FormCollection through. This seems really messy and I want to keep as much type specific code out of the project as I can - hence interfaces everywhere and Ninject to DI the concretes. Not only does custom model binding seem messy - won't I also lose my DataAnnotations?

Some code to describe what I have:

public ActionResult Create()
{
    // I'm thinking of using a factory pattern for this part
    var objectToCreate = new ConcereteType();
    return (objectToEdit);
}

[HttpPost]
public ActionResult Create(IRecord record)
{
    // check model and pass to repository
    if (ModelState.IsValue)
    {
        _repository.Create(record);
        return View();
    }

    return View(record);
}

Has anyone run into this before? How did you get over it?

Thanks!


回答1:


Data passed to controllers action are simply holders for values. There shouldn't be any logic in them so there is nothing to decouple from. You can use concrete types (e.g Record) instead of interface (IRecord)




回答2:


but it seems like the only way I can get around this is to use a custom model binder

A custom model binder is the correct way to go. And by the way you should use view models as action arguments, not domain models or interfaces.

Not only does custom model binding seem messy - won't I also lose my DataAnnotations?

I don't know why you think that a custom model binder would make things messy. For me it's a great way to separate mapping logic into a reusable class. And, no you will not lose DataAnnotations. They will work perfectly fine on the concrete instance that the custom model binder would return.




回答3:


I made the same simple mistake. Ninject injects parameters into your constructor, but you added parameters to the Index Controller action.

It should look like this:

public class HomeController : Controller
{
    private IRecord _record;

    public HomeController(IRecord record)
    {
        _record = record;
    }

    public ActionResult Index()
    {
        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application. " +
                          _record .HelloWorld();

        return View();
    }
}

Make sense?



来源:https://stackoverflow.com/questions/8215337/mvc-3-passing-entity-as-an-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!