ASP.NET MVC: для этого объекта не определен конструктор без параметров - PullRequest
162 голосов
/ 31 августа 2009
Server Error in '/' Application.
--------------------------------------------------------------------------------

No parameterless constructor defined for this object. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

Source Error: 


Line 16:             HttpContext.Current.RewritePath(Request.ApplicationPath, false);
Line 17:             IHttpHandler httpHandler = new MvcHttpHandler();
Line 18:             httpHandler.ProcessRequest(HttpContext.Current);
Line 19:             HttpContext.Current.RewritePath(originalPath, false);
Line 20:         }

Я следил за книгой Стивена Сандерсона « Pro ASP.NET MVC Framework ». На странице 132 в соответствии с рекомендацией автора я загрузил сборку ASP.NET MVC Futures и добавил ее в свой проект MVC. [Примечание: это может быть красная сельдь.]

После этого я больше не мог загружать свой проект. Вышеуказанная ошибка остановила меня холодным.

Мой вопрос , а не , «Не могли бы вы помочь мне исправить мой код?»

Вместо этого я хотел бы знать более широко:

  • Как мне решить эту проблему?
  • Что я должен искать?
  • Какая может быть основная причина?

Кажется, я должен понимать маршрутизацию и контроллеры на более глубоком уровне, чем сейчас.

Ответы [ 25 ]

213 голосов
/ 02 сентября 2010

У меня просто была похожая проблема. Такое же исключение возникает, когда Model не имеет конструктора без параметров.

Стек вызовов вычислял метод, отвечающий за создание нового экземпляра модели.

System.Web.Mvc.DefaultModelBinder. CreateModel (ControllerContext controllerContext, ModelBindingContext bindingContext, Тип modelType)


Вот пример:

public class MyController : Controller
{
    public ActionResult Action(MyModel model)
    {

    }
}

public class MyModel
{
    public MyModel(IHelper helper) // MVC cannot call that
    {
        // ...
    }

    public MyModel() // MVC can call that
    {
    }
}
84 голосов
/ 21 октября 2011

Это также может быть вызвано, если ваша Модель использует SelectList, , так как у нее нет конструктора без параметров :

public class MyViewModel
{
    public SelectList Contacts { get;set; }
}

Вам нужно будет провести рефакторинг вашей модели, чтобы сделать это по-другому, если это является причиной. Таким образом, используя IEnumerable<Contact> и написание метода расширения, который создает раскрывающийся список с различными определениями свойств:

public class MyViewModel
{
    public Contact SelectedContact { get;set; }
    public IEnumerable<Contact> Contacts { get;set; }
}

public static MvcHtmlString DropDownListForContacts(this HtmlHelper helper, IEnumerable<Contact> contacts, string name, Contact selectedContact)
{
    // Create a List<SelectListItem>, populate it, return DropDownList(..)
}

Или вы можете использовать подход @Mark и @krilovich, просто нужно заменить SelectList на IEnumerable, он также работает с MultiSelectList.

 public class MyViewModel
    {
        public Contact SelectedContact { get;set; }
        public IEnumerable<SelectListItem> Contacts { get;set; }
    }
22 голосов
/ 31 августа 2009

Требуется действие, которое соответствует контроллеру, чтобы не иметь параметра.

Похоже на комбинацию контроллер / действие, которую вы имеете:

public ActionResult Action(int parameter)
{

}

но вам нужно

public ActionResult Action()
{

}

Также, посмотрите Route Debugger Фила Хаака для устранения проблем маршрутов.

20 голосов
/ 31 августа 2009

По умолчанию для контроллеров MVC требуется конструктор по умолчанию без параметров. Простейшим было бы сделать конструктор по умолчанию, который вызывает конструктор с параметрами:

public MyController() : this(new Helper()) {
}

public MyController(IHelper helper) {
  this.helper = helper;
}

Однако вы можете переопределить эту функцию, свернув свой собственный ControllerFactory. Таким образом, вы можете сказать MVC, что при создании MyController присвойте ему экземпляр Helper.

Это позволяет вам использовать каркас Dependency Injection с MVC и действительно отделить все. Хорошим примером этого является веб-сайт StructureMap . Весь быстрый запуск хорош, и он становится специфичным для MVC в нижней части «Auto Wiring».

17 голосов
/ 04 октября 2011

Эта ошибка также возникает при использовании IDependencyResolver , например, при использовании контейнера IoC, и преобразователь зависимостей возвращает ноль. В этом случае ASP.NET MVC 3 по умолчанию использует DefaultControllerActivator для создания объекта. Если создаваемый объект не имеет общедоступного конструктора без аргументов, то исключение будет выдаваться каждый раз, когда предоставленный преобразователь зависимостей возвращает ноль.

Вот одна из таких трассировок стека:

[MissingMethodException: No parameterless constructor defined for this object.]
   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) +98
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67

[InvalidOperationException: An error occurred when trying to create a controller of type 'My.Namespace.MyController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +232
   System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
   System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8963444
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
13 голосов
/ 08 марта 2013

Вы можете получить это исключение во многих разных местах в инфраструктуре MVC (например, он не может создать контроллер или не может создать модель для предоставления этого контроллера).

Единственный простой способ диагностировать эту проблему - переопределить MVC как можно ближе к исключению с помощью собственного кода. Тогда ваш код сломается внутри Visual Studio, когда возникнет это исключение, и вы сможете прочитать тип, вызывающий проблему, из трассировки стека.

Это кажется ужасным способом решения этой проблемы, но он очень быстрый и очень последовательный.

Например, если эта ошибка происходит внутри MVC DefaultModelBinder (что вы узнаете, проверив трассировку стека), замените DefaultModelBinder следующим кодом:

public class MyDefaultModelBinder : System.Web.Mvc.DefaultModelBinder
{
    protected override object CreateModel(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext, Type modelType)
    {
        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

И обновите свой Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
{
...
    protected void Application_Start(object sender, EventArgs e)
    {
        ModelBinders.Binders.DefaultBinder = new MyDefaultModelBinder();
    }
}

Теперь, когда в следующий раз вы получите это исключение, Visual Studio остановится внутри вашего класса MyDefaultModelBinder, и вы можете проверить свойство "modelType", чтобы увидеть, какой тип вызвал проблему.

Приведенный выше пример работает, когда вы получаете исключение «Не определен конструктор без параметров для этого объекта» только во время привязки модели. Но подобный код может быть написан для других точек расширения в MVC (например, конструкция контроллера).

8 голосов
/ 14 августа 2013

Я получил ту же ошибку, виновником в моем случае был конструктор, который не был ни публичным, ни приватным .

Для этого объекта не определен конструктор без параметров.

Сведения об исключении: System.MissingMethodException: для этого объекта не определен конструктор без параметров.

Код Repro: убедитесь, что перед конструктором есть public.

public class Chuchi()
{
     Chuchi()    // The problem is this line. Public is missing
     {
         // initialization
         name="Tom Hanks";
     }

    public string name
    {
        get;
        set;
    }
}
7 голосов
/ 07 февраля 2011

Первое видео на http://tekpub.com/conferences/mvcconf

47: через 10 минут отобразится сообщение об ошибке и показано, как переопределить стандартную ControllerFactory. То есть создать фабрику контроллера структурной карты.

В принципе, вы, вероятно, пытаетесь внедрить внедрение зависимостей ??

Проблема в том, что это интерфейсная зависимость.

6 голосов
/ 13 октября 2010

Я получил ту же ошибку, когда:

Используя пользовательский ModelView, оба Действия (GET и POST) передавали ModelView, который содержал два объекта:

public ActionResult Add(int? categoryID)
{
    ...
    ProductViewModel productViewModel = new ProductViewModel(
            product,
            rootCategories
            );
    return View(productViewModel); 
}

И ПОСТ также принимает ту же модель:

[HttpPost]
[ValidateInput(false)]
public ActionResult Add(ProductModelView productModelView)
{...}

Проблема заключалась в том, что представление получило ModelView (требовалась информация как о продукте, так и о списке категорий), но после отправки возвращало только объект Product, но, поскольку POST Add ожидал ProductModelView, он передавал NULL, но тогда требовался только конструктор ProductModelView два параметра (Product, RootCategories), затем он попытался найти другой конструктор без параметров для этого случая NULL, а затем завершился неудачно с "no parameterles ..."

Итак, исправление POST Добавьте следующее, чтобы исправить проблему:

[HttpPost]
[ValidateInput(false)]
public ActionResult Add(Product product)
{...}

Надеюсь, это кому-нибудь поможет (я потратил почти полдня, чтобы выяснить это!).

5 голосов
/ 13 августа 2012

У меня была похожая проблема, и в основном дело в том, что в методе действия есть некоторые аргументы, которые не были предоставлены процессом связывания моделей (иными словами, эти поля не были отправлены страницей отправки).

Эта проблема возникнет, даже если будут предоставлены все аргументы, кроме одного, и даже если пропущенный аргумент имеет тип NULL.

Проблема также может быть результатом опечатки, в которой имя аргумента и имя поля формы не будут идентичны.

Решение состоит в том, чтобы: 1) убедиться, что имена совпадают, 2) предоставить значение по умолчанию для аргумента 3) или предоставить другой метод действия без этого аргумента.

...