web-dev-qa-db-fra.com

ASP.NET MVC: aucun constructeur sans paramètre défini pour cet objet

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:         }

Je suivais le livre ' Pro ASP.NET MVC Framework ' de Steven Sanderson. À la page 132, conformément à la recommandation de l'auteur, j'ai téléchargé l'assembly ASP.NET MVC Futures Assembly et l'ajouté à mon projet MVC. [Note: Cela pourrait être un hareng rouge.]

Après cela, je ne pouvais plus charger mon projet. L'erreur ci-dessus m'a arrêté froid.

Ma question est pas , "Pourriez-vous m'aider à réparer mon code?"

Au lieu de cela, j'aimerais savoir plus généralement:

  • Comment dois-je résoudre ce problème?
  • Que devrais-je rechercher?
  • Quelle pourrait être la cause racine?

Il semble que je devrais comprendre le routage et les contrôleurs à un niveau plus profond que ce que je fais maintenant.

163
Jim G.

Je viens d'avoir un problème similaire. La même exception se produit lorsqu'un Model n'a pas de constructeur sans paramètre.

La pile d'appels définissait une méthode responsable de la création d'une nouvelle instance d'un modèle.

System.Web.Mvc.DefaultModelBinder .CreateModel (ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)


Voici un échantillon:

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
    {
    }
}
217
SandRock

Cela peut aussi être causé si votre modèle utilise une liste de sélection, car elle n’a pas de constructeur sans paramètre:

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

Vous aurez besoin de refactoriser votre modèle pour le faire d'une manière différente si c'est la cause. Donc, en utilisant un IEnumerable<Contact> et en écrivant une méthode d'extension qui crée la liste déroulante avec les différentes définitions de propriété:

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(..)
}

Ou vous pouvez utiliser les approches @Mark et @krilovich, il suffit de remplacer SelectList par IEnumerable, cela fonctionne également avec MultiSelectList.

 public class MyViewModel
    {
        public Contact SelectedContact { get;set; }
        public IEnumerable<SelectListItem> Contacts { get;set; }
    }
84
Chris S

L'action correspondant à l'automate ne doit pas avoir de paramètre.

Ressemble à la combinaison contrôleur/action que vous avez:

public ActionResult Action(int parameter)
{

}

mais vous avez besoin

public ActionResult Action()
{

}

Consultez également le Route Debugger de Phil Haack pour dépanner les itinéraires.

22
Martin

Par défaut, les contrôleurs MVC nécessitent un constructeur par défaut sans paramètre. Le plus simple serait de créer un constructeur par défaut qui appelle celui avec des paramètres:

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

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

Cependant, vous pouvez remplacer cette fonctionnalité en lançant votre propre ControllerFactory. De cette façon, vous pouvez dire à MVC que lorsque vous créez un MyController, donnez-lui une instance de Helper.

Cela vous permet d'utiliser les infrastructures d'injection de dépendances avec MVC et de tout découpler. Un bon exemple de ceci est sur le site Web StructureMap . Tout le démarrage rapide est bon, et il se spécialise dans MVC vers le bas dans "Câblage automatique".

20
swilliams

Cette erreur se produit également lors de l'utilisation de IDependencyResolver , par exemple lors de l'utilisation d'un conteneur IoC, et si le résolveur de dépendance renvoie la valeur null. Dans ce cas, ASP.NET MVC 3 utilise par défaut DefaultControllerActivator pour créer l'objet. Si l'objet en cours de création n'a pas de constructeur public no-args, une exception sera alors levée chaque fois que le résolveur de dépendance fourni aura renvoyé la valeur null.

Voici une telle trace de pile:

[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
17
Kaleb Pederson

Vous pouvez obtenir cette exception à différents endroits du framework MVC (par exemple, il ne peut pas créer le contrôleur ou il ne peut pas créer de modèle à donner à ce contrôleur).

Le seul moyen facile que j'ai trouvé de diagnostiquer ce problème consiste à remplacer MVC aussi près que possible de l'exception par votre propre code. Votre code se cassera alors dans Visual Studio lorsque cette exception se produira et vous pourrez lire le type à l'origine du problème à partir de la trace de la pile.

Cela semble être une façon horrible d’aborder ce problème, mais c’est très rapide et très cohérent.

Par exemple, si cette erreur se produit à l'intérieur de MVC DefaultModelBinder (que vous saurez en vérifiant le suivi de la pile), remplacez le DefaultModelBinder par ce code:

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);
    }
}

Et mettez à jour votre fichier Global.asax.cs:

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

La prochaine fois que vous obtiendrez cette exception, Visual Studio s'arrêtera dans votre classe MyDefaultModelBinder et vous pourrez vérifier la propriété "modelType" pour voir quel type a provoqué le problème.

L'exemple ci-dessus fonctionne uniquement lorsque vous obtenez uniquement l'exception "Aucun constructeur sans paramètre défini pour cet objet" lors de la liaison du modèle. Cependant, un code similaire peut être écrit pour d'autres points d'extension dans MVC (par exemple, la construction du contrôleur).

13
Josh Mouch

J'ai eu la même erreur, le coupable dans mon cas était le constructeur qui n'était ni public ni privé.

Aucun constructeur sans paramètre défini pour cet objet.

Détails des exceptions: System.MissingMethodException: aucun constructeur sans paramètre défini pour cet objet.

Code repro: Assurez-vous que le constructeur a un public devant lui.

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

    public string name
    {
        get;
        set;
    }
}
8
Hammad Khan

Première vidéo sur http://tekpub.com/conferences/mvcconf

47:10 minutes dans montrent l'erreur et montre comment remplacer le ControllerFactory par défaut. C'est à dire. créer une usine de contrôleur de carte de structure.

Fondamentalement, vous essayez probablement de mettre en œuvre l'injection de dépendance?

Le problème est que c'est la dépendance de l'interface.

7
Dan B

J'ai eu la même erreur quand:

À l'aide d'une ModelView personnalisée, les deux actions (GET et POST) transmettaient la ModelView qui contenait deux objets:

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

Et le POST accepte également la même vue de modèle:

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

Le problème était que la vue ait reçu la vue ModelView (il avait besoin des informations sur le produit et la liste des catégories), mais une fois renvoyé, il ne renvoyait plus que l'objet Product, mais comme POST Add attendait un ProductModelView, il passait NULL, mais ensuite ProductModelView. seul le constructeur avait besoin de deux paramètres (Product, RootCategories), puis il a essayé de trouver un autre constructeur sans paramètre pour ce cas NULL, puis il a échoué avec "aucun paramètre ...".

Donc, en corrigeant le POST Add comme suit, corrigez le problème:

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

J'espère que cela peut aider quelqu'un (j'ai passé presque une demi-journée à le découvrir!).

6
Nestor

J'ai eu un problème similaire, et l'essentiel est que la méthode d'action contient des arguments qui n'ont pas été fournis par le processus Model Binding (en d'autres termes, ces champs n'ont pas été soumis par la page de soumission).

Ce problème se posera même si tous les arguments sauf un sont fournis et même si celui qui manque est un type nullable.

Le problème peut également résulter d'une faute de frappe, dans laquelle le nom de l'argument et le nom du champ de formulaire ne seront pas identiques.

La solution consiste à 1) vérifier que les noms correspondent 2) fournir une valeur par défaut pour l'argument 3) ou fournir une autre méthode d'action sans cet argument.

5
yoel halb

La même chose pour moi. Mon problème est apparu car j'ai oublié que ma la classe de modèle de base a déjà une propriété avec le nom défini dans la vue.

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  { ... }

... et le modèle de traitement du contrôleur:

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

Rien de spécial, non? Mais alors je définis la vue ...

<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>

... ce qui provoque une erreur "Parameterless constructor" sur la demande POST.

J'espère que ça t'as aidé.

5
Anonymous

J'ai eu ce problème aussi et je pensais partager car je ne trouve pas mon problème ci-dessus.

C'était mon code

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

Appelant cette ActionResult:

public ActionResult Overview(int id)

J'ai supposé qu'il serait assez intelligent de comprendre que la valeur que je transmets est le paramètre id pour Overview, mais ce n'est pas le cas. Cela l'a corrigé:

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

4
Brik

J'ai eu la même exception parce qu'il n'y avait pas de constructeur public sans paramètre

Le code était comme ceci:

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

remplacé par

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

problème résolu pour moi.

4
Muru Bakthavachalam

J'ai eu cette erreur. J'utilisais des interfaces dans mon constructeur et mon résolveur de dépendances n'était pas capable de résoudre, lorsque je l'ai enregistré, l'erreur a disparu.

2
Ahmed

Bien que cela puisse sembler évident à certains, le coupable de cette erreur est que ma méthode MVC était liée à un modèle contenant une propriété de type Tuple<>. Tuple<> n'a pas de constructeur sans paramètre.

2
Tyler Forsythe

J'ai eu le même problème...

Si vous utilisez une interface pour découpler votre connexion avec votre DbContext (comme moi), vous pouvez utiliser structuremap.mvc (3 ou 4 - paquet nudget ) pour pouvoir utiliser une construction dans votre classe de contrôleur. Cela vous donnera un dossier DependencyResolution. Modifiez simplement la ligne commentée avec votre <InterfaceClass> () et utilisez <DbContextClass> ().

2
JeppePepp

Toutes les réponses suggèrent de créer un constructeur sans paramètres, ce qui n’est pas idéal si vous ne voulez pas que d’autres développeurs l’utilisent et uniquement le classeur.

L'attribut [Obsolete("For model binding only", true)] situé au-dessus d'un constructeur public émettra une erreur de compilation si un autre développeur essaie de l'utiliser. Cela m’a pris beaucoup de temps pour trouver ça, espère que ça aidera quelqu'un.

2
Martin Dawson

Très probablement, vous avez peut-être paramétré le constructeur dans votre contrôleur et le résolveur de dépendances que vous utilisez n'est pas en mesure de résoudre correctement la dépendance. Vous devez définir un point d'arrêt où la méthode de résolution des dépendances est écrite et vous obtiendrez l'erreur exacte dans une exception interne.

0
Mahendra Savale

J'ai eu le même problème.

Vient juste de retirer HttpFileCollectionBase files de l'argument de méthode Post Action et l'ajoute comme HttpFileCollectionBase files = Request.Files; dans le corps de la méthode.

0
Muhammad Yasir

J'avais ajouté un DropDownList à mon formulaire, mais dans mon cas, il n'a pas été envoyé (et ne devait pas l'être) avec le formulaire, car il se trouvait en dehors des balises <form></form>:

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

Comme le modèle contenait le champ à afficher uniquement, cela provoquait également l'erreur No parameterless constructor defined for this object, car le champ n'était pas soumis du tout.

Dans ce cas, je l'ai corrigé en ajoutant une liaison d'exclusion:

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

Dans mon cas, ma classe avait l'attribut [Serializable].

Vous devez avoir un constructeur qui ne prend aucun paramètre si votre classe est [Serializable]

0
Kolob Canyon

Cela m'est arrivé et les résultats sur cette page ont été une bonne ressource qui m'a conduit dans de nombreuses directions, mais j'aimerais ajouter une autre possibilité:

Comme indiqué dans d'autres réponses, la création d'un constructeur avec des paramètres supprime le constructeur implicite sans paramètre, vous devez donc le taper explicitement.

Ce qui me posait problème, c’est qu’un constructeur avec des paramètres par défaut a également déclenché cette exception.

Donne des erreurs:

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

Travaux:

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

Cette erreur a commencé pour moi lorsque j'ai ajouté un nouveau moyen d'instancier une classe.

Exemple:

    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;
         }
     }

L'erreur a été résolue lorsque j'ai ajouté ce changement en ajoutant un constructeur sans paramètre. Je pense que le compilateur crée un constuctor sans paramètre par défaut, mais si vous ajoutez le vôtre, vous devez le créer explicitement.

    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;
         }
     }
0
chuck

J'ai eu le même problème, mais plus tard, l'ajout d'une nouvelle interface et la classe correspondante nécessitaient son enregistrement sous Module initialisable pour une injection de dépendance. Dans mon cas, c'était le code interne suivant:

[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)
    {
    }
}

}

0
arokanika