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

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. [Примечание: это может быть красная селедка.]

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

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

Вместо этого я хотел бы узнать более подробно:

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

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

Ответ 1

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

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

System.Web.Mvc.DefaultModelBinder. CreateModel (ControllerContext controllerContext, ModelBindingContext bindingContext, Type 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
    {
    }
}

Ответ 2

Это также может быть вызвано, если ваша модель использует 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; }
    }

Ответ 3

Вам нужно, чтобы действие, соответствующее контроллеру, не имело параметра.

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

public ActionResult Action(int parameter)
{

}

но вам нужно

public ActionResult Action()
{

}

Кроме того, ознакомьтесь с Phil Haack Отладчик маршрутов для устранения неполадок маршрутов.

Ответ 4

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

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

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

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

Это позволяет использовать фреймворки зависимостей с MVC и действительно разделить все. Хорошим примером этого является сайт StructureMap. Весь быстрый старт хорош, и он становится специфичным для MVC в нижней части "Автоматическая проводка".

Ответ 5

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

Здесь одна такая трассировка стека:

[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

Ответ 6

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

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

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

Например, если эта ошибка возникает внутри 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 (например, для конструкции контроллера).

Ответ 7

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

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

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

Проблема заключается в зависимости от интерфейса.

Ответ 8

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

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

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

Repro code: убедитесь, что конструктор открыт для него.

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

    public string name
    {
        get;
        set;
    }
}

Ответ 9

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

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

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

И POST также принимает тот же вид модели:

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

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

Итак, исправление POST Add следующим образом исправляет проблему:

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

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

Ответ 10

То же самое для меня. Моя проблема возникла из-за того, что я забыл, что мой базовый класс уже имеет свойство с именем, которое было определено в представлении.

public class CTX : DbContext {  // context with domain models
    public DbSet<Products> Products { get; set; }  // "Products" is the source property
    public CTX() : base("Entities") {}
}

public class BaseModel : CTX { ... }
public class ProductModel : BaseModel { ... }
public class OrderIndexModel : OrderModel  { ... }

... и модель обработки контроллера:

[HttpPost]
[ValidateInput(false)]
public ActionResult Index(OrderIndexModel order) { ... }

Ничего особенного, не так ли? Но затем я определяю представление...

<div class="dataItem">
    <%=Html.Label("Products")%>
    <%=Html.Hidden("Products", Model.index)%>   // I FORGOT THAT I ALREADY HAVE PROPERTY CALLED "Products"
    <%=Html.DropDownList("ProductList", Model.products)%>
    <%=Html.ActionLink("Delete", "D")%>
</div>

... который вызывает ошибку "Parameterless constructor" при запросе POST.

Надеюсь, что это поможет.

Ответ 11

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

Эта проблема возникнет, даже если все аргументы, кроме одного, будут предоставлены, и даже если один из них отсутствует, это тип с нулевым значением.

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

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

Ответ 12

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

Это был мой код

return RedirectToAction("Overview", model.Id);

Вызов этого ActionResult:

public ActionResult Overview(int id)

Я предположил, что это было бы достаточно разумно, чтобы понять, что значение, которое я передаю, это идентификатор для Обзор, но это не так. Это зафиксировало это:

return RedirectToAction("Overview", new {id = model.Id});

Ответ 13

У меня получилось такое же исключение из-за отсутствия безрежимного публичного конструктора

Код был примерно таким:

public class HomeController : Controller
{        
    private HomeController()
    {
        _repo = new Repository();
    }

изменено на

 public class HomeController : Controller
{        
    public HomeController()
    {
        _repo = new Repository();
    }

проблема решена для меня.

Ответ 14

У меня была та же проблема...

Если вы используете интерфейс для развязки своего соединения с вашим DbContext (например, я), вы можете использовать structmap.mvc (3 или 4 - nudget package), чтобы иметь возможность использовать структуру в контроллере класс. Это даст вам папку DependencyResolution. Просто измените прокомментированную строку с помощью параметра For & InterfaceClass > () и использовать <DbContextClass> ().

Ответ 15

Хотя это может быть очевидным для некоторых, виновником этой ошибки для меня был мой метод MVC, был привязан к модели, которая содержала свойство типа Tuple<>. Tuple<> не имеет конструктора без параметров.

Ответ 16

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

Атрибут [Obsolete("For model binding only", true)] над публичным конструктором вызовет ошибку компилятора, если другой разработчик попытается использовать это. Взял меня, чтобы найти это, надеюсь, что это поможет кому-то.

Ответ 17

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

Пример:

    public class myClass
    {
         public string id{ get; set; }
         public List<string> myList{get; set;}

         // error happened after I added this
         public myClass(string id, List<string> lst)
         {
             this.id= id;
             this.myList= lst;
         }
     }

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

    public class myClass
    {
         public string id{ get; set; }
         public List<string> myList{get; set;}

         // error doesn't happen when I add this
         public myClass() { }

         // error happened after I added this, but no longer happens after adding above
         public myClass(string id, List<string> lst)
         {
             this.id= id;
             this.myList= lst;
         }
     }

Ответ 18

Я добавил в форму DropDownList, но в моем случае это не было (и не было предназначено), представленное с формой, поскольку оно было вне тегов <form></form>:

@Html.DropDownList("myField", Model.MyField)

Поскольку модель содержала только поле для отображения, это также вызвало ошибку No parameterless constructor defined for this object, потому что поле вообще не было отправлено.

В этом случае я исправил его, добавив привязку exclude:

public ActionResult Foo(int id, int? page, [Bind(Exclude = "MyField")]MyModel model)

Ответ 19

Это случилось со мной, и результаты на этой странице были хорошим ресурсом, который привел меня во многих направлениях, но я хотел бы добавить еще одну возможность:

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

В чем была моя проблема: конструктор с параметрами по умолчанию также вызвал это исключение.

Дает ошибки:

public CustomerWrapper(CustomerDto customer = null){...}

Работает:

public CustomerWrapper(CustomerDto customer){...}
public CustomerWrapper():this(null){}

Ответ 20

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

Ответ 21

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

Ответ 22

У меня была такая же проблема, но позже я обнаружил, что добавление любого нового интерфейса и соответствующего класса требует его регистрации в Initializable Module для инъекции зависимостей. В моем случае он был внутри кода следующим образом:

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class DependencyResolverInitialization : IConfigurableModule
{

    public void ConfigureContainer(ServiceConfigurationContext context)
    {
        context.Container.Configure(ConfigureContainer);
        var structureMapDependencyResolver = new StructureMapDependencyResolver(context.Container);
        DependencyResolver.SetResolver(structureMapDependencyResolver);
        GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), structureMapDependencyResolver);
    }

    private void ConfigureContainer(ConfigurationExpression container)
    {
        container.For<IAppSettingService>().Use<AppSettingService>();
        container.For<ISiteSettingService>().Use<SiteSettingService>();
        container.For<IBreadcrumbBuilder>().Use<BreadcrumbBuilder>();
        container.For<IFilterContentService>().Use<FilterContentService>().Singleton();
        container.For<IDependecyFactoryResolver>().Use<DependecyFactoryResolver>();
        container.For<IUserService>().Use<UserService>();
        container.For<IGalleryVmFactory>().Use<GalleryVmFactory>();
        container.For<ILanguageService>().Use<LanguageService>();
        container.For<ILanguageBranchRepository>().Use<LanguageBranchRepository>();
        container.For<ICacheService>().Use<CacheService>(); 
        container.For<ISearchService>().Use<SearchService>();
        container.For<IReflectionService>().Use<ReflectionService>();
        container.For<ILocalizationService>().Use<LocalizationService>();
        container.For<IBookingFormService>().Use<BookingFormService>();
        container.For<IGeoService>().Use<GeoService>();
        container.For<ILocationService>().Use<LocationService>();
        RegisterEnterpriseAPIClient(container);
    }

   public void Initialize(InitializationEngine context)
    {
    }

    public void Uninitialize(InitializationEngine context)
    {
    }

    public void Preload(string[] parameters)
    {
    }
}

}

Ответ 23

Итак, я получил это сообщение раньше, когда делаю вызов ajax. Так что он в основном запрашивает конструктор в том классе модели, который вызывается контллером, не имеет никакого параметра.

Вот пример

public class MyClass{

     public MyClass(){} // so here would be your parameterless constructor

 }