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 'Pro de Steven Sanderson ASP.NET MVC Framework ' Livre. À la page 132, conformément à la recommandation de l'auteur, j'ai téléchargé le ASP.NET MVC futures assembly, et l'a 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 en savoir plus généralement:
- Comment dois-je résoudre ce problème?
- Que dois-je chercher?
- Quelle pourrait être la cause première?
Il semble que je devrais comprendre le routage et les contrôleurs à un niveau plus profond que maintenant.
24 réponses
J'ai juste eu 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éterminait une méthode responsable de la création d'une nouvelle instance d'un modèle.
Système.Web.Mvc.DefaultModelBinder. CreateModel (ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
Voici un exemple:
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
{
}
}
Cela peut également être causé si votre modèle utilise une SelectList, car cela n'a pas de constructeur sans paramètre :
public class MyViewModel
{
public SelectList Contacts { get;set; }
}
Vous devrez 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és:
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 l'approche @ Mark et @ krilovich, il suffit de remplacer SelectList à IEnumerable, cela fonctionne avec MultiSelectList trop.
public class MyViewModel
{
public Contact SelectedContact { get;set; }
public IEnumerable<SelectListItem> Contacts { get;set; }
}
Vous avez besoin de l'action qui correspond au contrôleur pour ne pas avoir de paramètre.
Ressemble à la combinaison contrôleur / action que vous avez:
public ActionResult Action(int parameter)
{
}
Mais vous avez besoin de
public ActionResult Action()
{
}
Aussi, consultez Route Debugger de Phil Haack pour dépanner les routes.
Par défaut, les contrôleurs MVC nécessitent un constructeur par défaut sans paramètres. Le plus simple serait de faire 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
donner un exemple de Helper
.
Cela vous permet d'utiliser des frameworks D'Injection de dépendances avec MVC, et vraiment de tout découpler. Un bon exemple de ceci est plus à le site web StructureMap . Tout le quickstart est bon, et il devient spécifique à MVC vers le bas au "câblage automatique".
Cette erreur se produit également lors de l'utilisation d'un IDependencyResolver, par exemple lors de l'utilisation d'un conteneur IoC, et le résolveur de dépendances renvoie 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 levée chaque fois que le résolveur de dépendances fourni aura renvoyé 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
Vous pouvez obtenir cette exception à de nombreux endroits différents dans le framework MVC (par exemple, il ne peut pas créer le contrôleur, ou il ne peut pas créer un modèle pour donner ce contrôleur).
Le seul moyen facile que j'ai trouvé pour diagnostiquer ce problème est de remplacer MVC le plus près possible de l'exception avec votre propre code. Ensuite, votre code se cassera dans Visual Studio lorsque cette exception se produira, et vous pouvez lire le Type à l'origine du problème à partir de la trace de la pile.
Cela semble être une manière horrible pour aborder ce problème, mais c'est très rapide, et très cohérent.
Par exemple, si cette erreur se produit dans le MVC DefaultModelBinder (que vous connaîtrez en vérifiant la trace 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 mettre à jour votre Global.asax.cs:
public class MvcApplication : System.Web.HttpApplication
{
...
protected void Application_Start(object sender, EventArgs e)
{
ModelBinders.Binders.DefaultBinder = new MyDefaultModelBinder();
}
}
Maintenant, La prochaine fois que vous obtenez cette exception, Visual Studio s'arrêtera dans votre classe MyDefaultModelBinder, et vous pouvez vérifier la propriété "modelType" pour voir quel type a causé problème.
L'exemple ci-dessus fonctionne lorsque vous obtenez l'exception "aucun constructeur sans paramètre défini pour cet objet" lors de la liaison du modèle, uniquement. Mais un code similaire peut être écrit pour d'autres points d'extension dans MVC (par exemple, la construction du contrôleur).
J'ai eu la même erreur, le coupable dans mon cas, c'était le constructeur qui est ni public ni privé.
Aucun constructeur sans paramètre défini pour cet objet.
Détails De L'Exception: Système.MissingMethodException: aucun constructeur sans paramètre défini pour cet objet.
Code Repro: assurez-vous que le constructeur a public avant.
public class Chuchi()
{
Chuchi() // The problem is this line. Public is missing
{
// initialization
name="Tom Hanks";
}
public string name
{
get;
set;
}
}
Première vidéo sur http://tekpub.com/conferences/mvcconf
47: 10 minutes dans Afficher l'erreur et montre comment remplacer le ControllerFactory par défaut. C'est-à-dire pour créer l'usine de contrôleur de carte de structure.
Fondamentalement, vous essayez probablement d'implémenter l'injection de dépendance??
Le problème est que c'est la dépendance de l'interface.
J'ai eu la même erreur quand:
En utilisant un ModelView personnalisé, les deux Actions (GET et POST) passaient le ModelView qui contenait deux objets:
public ActionResult Add(int? categoryID)
{
...
ProductViewModel productViewModel = new ProductViewModel(
product,
rootCategories
);
return View(productViewModel);
}
Et le POST acceptant également la même vue de modèle:
[HttpPost]
[ValidateInput(false)]
public ActionResult Add(ProductModelView productModelView)
{...}
Problème était la vue a reçu le ModelView (nécessaire à la fois produit et liste des catégories info), mais après soumis renvoyait seulement l'objet produit, mais comme le post Add attendait un ProductModelView il a passé un NULL mais le ProductModelView seulement le constructeur avait besoin de deux paramètres (Product, RootCategories), puis il a essayé de trouver un autre constructeur sans paramètres pour ce cas NULL puis échoue avec "no parameterles..."
Donc, en fixant le POST ajouter comme suit corriger 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 pour le découvrir!).
La même chose pour moi. Mon problème est apparu parce que j'ai oublié que ma classe de modèle de base a déjà une propriété avec le nom qui a été 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 contrôleur traitement Modèle:
[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 "constructeur sans paramètre" sur la demande POST.
J'espère que ça aide.
J'ai eu un problème similaire, et fondamentalement le point est qu'il y a des arguments dans la méthode d'action qui n'ont pas été fournis par le processus de liaison du modèle, (et 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 manquant est un type nullable.
Le problème pourrait également être le résultat d'une faute de frappe, dans lequel le nom de l'argument et le nom du champ de formulaire ne sera pas identique.
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.
J'ai eu ce problème aussi et j'ai pensé que je partagerais puisque je ne peux pas trouver mon problème ci-dessus.
C'était mon code
return RedirectToAction("Overview", model.Id);
Appel de cette ActionResult:
public ActionResult Overview(int id)
J'ai supposé qu'il serait assez intelligent pour comprendre que la valeur que je passe est le paramètre id pour la vue d'ensemble, mais ce n'est pas le cas. Cela l'a corrigé:
return RedirectToAction("Overview", new {id = model.Id});
J'ai eu la même exception car il n'y avait pas de contrôleur public sans paramètre
Le Code était comme ceci:
public class HomeController : Controller
{
private HomeController()
{
_repo = new Repository();
}
Changé de
public class HomeController : Controller
{
public HomeController()
{
_repo = new Repository();
}
Problème résolu pour moi.
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 package 4-nudget ) pour pouvoir utiliser une constructure dans votre classe de contrôleur. Cela vous donnera un dossier DependencyResolution. Il suffit de changer la ligne commentée avec votre For() et D'utiliser ().
Bien que cela puisse être évident pour certains, le coupable de cette erreur pour moi était ma méthode MVC était liée à un modèle qui contenait une propriété de type Tuple<>
. Tuple<>
n'a pas de constructeur sans paramètre.
Toutes les réponses disent de créer un constructeur sans Paramètres ce qui n'est pas idéal si vous ne voulez pas d'autres développeurs l'utiliser et seulement le classeur de modèle.
L'attribut [Obsolete("For model binding only", true)]
Au-dessus d'un constructeur public lancera une erreur de compilateur si un autre dev essaie de l'utiliser. Ça m'a pris du temps pour trouver ça, j'espère que ça aide quelqu'un.
J'ai eu cette erreur. J'utilisais des interfaces dans mon constructeur et mon résolveur de dépendance n'était pas capable de résoudre, quand je l'ai enregistré, l'erreur est partie.
Cette erreur a commencé pour moi quand j'ai ajouté une nouvelle façon 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é quand j'ai fait ce changement, en ajoutant un constructeur sans paramètre. Je crois 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;
}
}
J'avais ajouté un DropDownList
à mon formulaire, mais dans mon cas, il n'était pas (et n'était pas destiné à être) soumis avec le formulaire car il était en dehors des balises <form></form>
:
@Html.DropDownList("myField", Model.MyField)
Comme le modèle contenait le champ uniquement pour l'affichage, cela a également provoqué l'erreur No parameterless constructor defined for this object
car le champ n'a pas été 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)
Cela m'est arrivé, et les résultats sur cette page étaient une bonne ressource qui m'a conduit dans de nombreuses directions, mais je voudrais 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.
Quel était mon 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){...}
Fonctionne:
public CustomerWrapper(CustomerDto customer){...}
public CustomerWrapper():this(null){}
Très probablement, vous pourriez avoir un constructeur paramétré dans votre contrôleur et quel que soit le résolveur de dépendance que vous utilisez, il n'est pas capable de résoudre correctement la dépendance. Vous devez mettre le point d'arrêt où la méthode de résolveur de dépendance est écrite et vous obtiendrez l'erreur exacte dans l'exception interne.
J'ai eu le même problème, mais plus tard trouvé l'ajout d'une nouvelle interface et la classe correspondante nécessite qu'elle soit enregistrée sous le Module Initialisable pour l'injection de dépendance. Dans mon cas, il était à l'intérieur du code comme suit:
[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)
{
}
}
}
J'ai eu le même problème.
Vient de supprimer HttpFileCollectionBase files
de l'argument de la méthode Post Action
et ajouté comme HttpFileCollectionBase files = Request.Files;
dans le corps de la méthode.
J'ai donc reçu ce message avant aussi, en faisant un appel ajax. Donc, ce qu'il demande fondamentalement, c'est un constructeur dans cette classe de modèle qui est appelé par le contrôleur, n'a aucun paramètre.
Voici un exemple
public class MyClass{
public MyClass(){} // so here would be your parameterless constructor
}