10

I am sure this is quite straightforward but I am a bit stuck here. The routing defined for my app is just the default. I have the following controller defined.

namespace Baynes.Wedding.Web.Controllers
{
    public class AdminController : Controller
    {
        private readonly IAuthProvider _authProvider;
        private readonly IDocumentRepository _documentRepository;

        public AdminController(IAuthProvider authProvider, IDocumentRepository documentRepository)
        {
            _authProvider = authProvider;
            _documentRepository = documentRepository;
        }

        public ViewResult EditDocument(int id)
        {
            var document = _documentRepository.Select(id);

            return View(new DocumentEditViewModel(document));
        }

        [HttpPost]
        public ActionResult EditDocument(DocumentEditViewModel model)
        {
            if (ModelState.IsValid)
            {
                _documentRepository.Update(model.ToDocument());
                return RedirectToAction("ListDocuments");
            }

            return View();
        }
    }
}

When I navigate to /Admin/EditDocument/1/ then the first action executes exactly as expected, rendering the following view:-

<h2>@ViewBag.Title</h2>
@using (Html.BeginForm("EditDocument", "Admin", FormMethod.Post)) {
    @Html.ValidationSummary(true)
    @Html.HiddenFor(m => Model.Id)
    <div>
        @Html.LabelFor(m => Model.Title)
    </div>
    <div>
        @Html.TextBoxFor(m => Model.Title)
    </div>
    <div>
        @Html.LabelFor(m => Model.Body)
    </div>
    <div>
        @Html.TextAreaFor(m => Model.Body)
    </div>
    <div>
        @Html.LabelFor(m => Model.Url)
    </div>
    <div>
        @Html.TextBoxFor(m => Model.Url)
    </div>

    <input type="submit" value="Edit" />
}

On submitting this I get an error:-

No parameterless constructor defined for this object. Other questions seemingly related questions MVC: No parameterless constructor defined for this object suggest that it is a to do with the IoC container not being set up properly, but surely the fact that the first action executes without a problem means that isn't the problem here?

Any help would be greatly appreciated.

Regards.

Simon

Community
  • 1
  • 1
baynezy
  • 6,493
  • 10
  • 48
  • 73

6 Answers6

15

add to class DocumentEditViewModel default constructor

public DocumentEditViewModel (){}
Mediator
  • 14,951
  • 35
  • 113
  • 191
  • 1
    WHY is this necessary? In my mind, controllers should have default constructors created by the system just like most classes. – levininja Nov 21 '14 at 21:54
  • @levininja JTMon answered on your question – Mediator Nov 24 '14 at 09:50
  • @Mediator my question is: what is the thinking behind designing MVC framework to not assume a default constructor for controller classes, the way .NET does with ALL classes by default. Normally the compiler assumes an empty constructor if none is specified. NOT doing that for controller classes specifically seems ridiculous to me. – levininja Nov 24 '14 at 15:06
  • @levininja, DefaultModelBinder use System.Activator.CreateInstance(Type type). The documentation told us "Creates an instance of the specified type using that type's default constructor." – Mediator Nov 25 '14 at 23:35
5

The MVC framework is trying to create an instance of the DocumentViewModel class but it can't find a publicly accessible default constructor (that does not take any arguments). You can either define such a default constructor like @simplyDenis suggested or define a cusotm ModelBinder that can create the instance using your custom constructor.

JTMon
  • 3,189
  • 22
  • 24
1

Does DocumentEditViewModel have a parameterless constructor? I believe this is needed for modelbinding on your post view.

chrisn
  • 308
  • 1
  • 6
1

Most likely you have dependency injections mechanism. But MVC requires "special" way to register container. Look at this link Adding Unity to Your Web Applications, patterns and practices

Vitaliy Markitanov
  • 2,205
  • 1
  • 24
  • 23
0

I had a slightly different problem. One of my Model classes was abstract.

Jess
  • 23,901
  • 21
  • 124
  • 145
0

If DocumentEditViewModel constructor's accessibility level is protected you will get also the same error.

Jamaxack
  • 2,400
  • 2
  • 24
  • 42