Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

MVC4 ASP.NET IRepository problem

Posted on 2013-12-30
3
Medium Priority
?
519 Views
Last Modified: 2013-12-31
Hi,

I'm using MVC4 and having real difficulty getting my head around where Iam going wrong. In fact I have been stuck for two weeks now. All I am trying to do is post a comment back to database using the IRepository approach. I get the following error. I was hoping someone could enlighten me on where I might be going wrong here.

No parameterless constructor defined for this object

So here is my code...

Abstract Class

public interface IBlogRepository : IDisposable
    {
        IList<Entry> Posts();
        void InsertComment(Comment comment);
        void Save();

    }

Open in new window


Inherited Class on the InsertComment method Comment being my database table. So I should be able to call in that and pass in my model to update table using this apporach with ease.

public class BlogRepository : IBlogRepository, IDisposable
    {
        private BlogDataDataContext _dataContext;
        public BlogRepository() { _dataContext = new BlogDataDataContext(); }

       // #region IBlogRepository Members

        public IList<Entry> Posts()
        {
            var entries = from m in _dataContext.Entries select m;
            return entries.ToList();
        }

        public void InsertComment(Comment comment)
        {
            _dataContext.Comments.InsertOnSubmit(comment);
        }

        public void Save()
        {
            _dataContext.SubmitChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    _dataContext.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

       // #endregion
    }

Open in new window


Here is my ListView Model that validate comments and does some other stuff.
public class ListView
    {
        [Required(ErrorMessage = " A Name is required *")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(160, MinimumLength = 2, ErrorMessage = "Must be between 2 & 160 characters in length.")]
        public string AuthorName { get; set; }

        [Required(ErrorMessage = "Email address required *")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(160, MinimumLength = 2, ErrorMessage = "Must be between 2 & 160 characters in length *")]
        [EmailValidation(ErrorMessage = "Must be valid email *")]
        public string AuthorEmail { get; set; }

        [Required(ErrorMessage = " A Message is required *")]
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [StringLength(4000, MinimumLength = 2, ErrorMessage = "Must be between 2 & 4000 characters in length *")]
        public string Body { get; set; }
        
        public ListView(IBlogRepository blogRepository)
        {
            Posts = blogRepository.Posts();
        }

        public IList<Entry> Posts { get; private set; }
        public IList<Comment> Comment { get; private set; }
    }

Open in new window



Here is my BlogController...

public class BlogController : Controller
    {
        
        private IBlogRepository _repository;
        public BlogController() : this(new BlogRepository()) { }
        public BlogController(IBlogRepository repository) {
 
            this._repository = repository;
        }

        public ActionResult BlogList(){
            var viewModel = new ListView(_repository);
            return View("BlogList", viewModel);            
        }     
        public ActionResult BlogPost(int id, string title){
            var viewModel = new ListView(_repository);            
            ViewData["id"] = id;
            return View("BlogPost", viewModel);
        }

        [HttpPost]
        public ActionResult BlogPost(ListView model)
        {
            // CANNOT GET TO HERE WITH ERROR.
            if (ModelState.IsValid) {
            
            
        
                return RedirectToAction("BlogPost");
            }
            return View();
        }
    }

Open in new window


Here is my initial BlogList.cshtml file which displays each blog in a list. We then click and a get is sent to controller to fetch the right blog.

@model MyProgram.Models.ListView
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    Page.Title = "";
}

@section head{
 <meta name="description" content=""/>
}

<section>
    <div>
        <h1 class="customCol1">Blog List - Recent Posts</h1>
        @{
            foreach (var ch in Model.Posts)
            {
                <div class="blogDiv"> 
                    <div class="blogSummary" >                        
                            <ul><li class="lnkBlog">@Html.ActionLink(@ch.Title, "BlogPost", "Blog", new { id = @ch.EntryId, title = @ch.MetaTitle }, new { @class = "lnkBlogAct" })</li></ul>                        
                            <p class="blogListSummary">@ch.Summary.ToString()</p>
                            <span><strong>@ch.Published.ToString("dd/MM/yyyy HH:mm:ss")</strong></span>
                    </div>
                </div>
            }            
        }        
    </div>
</section>

Open in new window


Here is my blogpost.cshtml which is where we display selected blog with comments section at the bottom. The problem is when I post the comments back to the server it should call the HTTPPOST method and then we can insertComment. I am having trouble passing the view back and cannot work out my glaring mistake.
@model MyProgram.Models.ListView
@{
    Layout = "~/Views/Shared/_Layout.cshtml";    
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
@section head{
 <meta name="description" content="@ViewBag.Description" />
}

<article>
    <div>        
         @{            
            if (@ViewData["id"] != ""){
                int myVal = Convert.ToInt32(@ViewData["id"]);
                var myEntry = Model.Posts.Single(c => c.EntryId == myVal);
                
            <div class="blogContent" >
                <h1 class="blogH1">@myEntry.Title</h1>                
                <div class="blogEntry">@Html.Raw(myEntry.Body)</div>               
                <span class="blogPublished float-left">Posted by:&nbsp;&nbsp;@myEntry.Username</span>
                <span class="blogPublished float-right">Published Date & Time:&nbsp;&nbsp;@myEntry.Published.ToString("dd/MM/yyyy HH:mm:ss")</span>                
            </div>
                Page.Title = @myEntry.MetaTitle + " - Web Design Blog Post ";
                ViewBag.Description = @myEntry.MetaDescription;
            }
        } 
    </div>    
</article>
<div class="clear"></div>
<section>
    <div class="blogContent">
        <h1 class="blogH1">Leave a Comment</h1>
       @using (Html.BeginForm("BlogPost", "Blog"))
{
    <fieldset id="frmComments">
        <div class="frmBlogMessageContainer">
            <div class="frmBlogRwComments">
              <span class="lblBlogCntrls">@Html.LabelFor(model => model.AuthorName)*</span>
              <span>@Html.TextBoxFor(model => model.AuthorName, new { @class= "frmBlogCntrls", @maxlength = "100" })</span><br />
              <span class="lblBlogCntrls"></span>
              <span class="msgBlogComment">@Html.ValidationMessageFor(model => model.AuthorName)</span>
            </div>
            <div class="frmBlogRwComments">
              <span class="lblBlogCntrls">@Html.LabelFor(model => model.AuthorEmail)*</span>
              <span>@Html.TextBoxFor(model => model.AuthorEmail, new { @class= "frmBlogCntrls", @maxlength = "150" })</span><br />
              <span class="lblBlogCntrls"></span>
              <span class="msgBlogComment">@Html.ValidationMessageFor(model => model.AuthorEmail)</span>
            </div>
            <div class="frmBlogRwComments frmBlogCommentsMessage">
              <span class="lblBlogCntrls">@Html.LabelFor(model => model.Body)*</span>
              <span>@Html.TextAreaFor(model => model.Body, new { @class= "frmBlogCntrls", @cols = 40, @rows = 10  })</span><br />
              <span class="lblBlogCntrls">&nbsp;</span>
              <span class="msgBlogComment">@Html.ValidationMessageFor(model => model.Body)</span>
            </div>
            <br />
            <div class="frmBlogRwComments">
              <span class="lblBlogCntrls"></span>
              <span><input id="submit" name="submit" type="submit" value="Submit" /></span>
            </div>
        </div>
    </fieldset>
}
    </div>
</section>

Open in new window


Any advice at all would really help. I wouldn't normally post so much code but I just cant fathom it at all and think I am completely missing the point somewhere.



In my ListView Model I have a constructor like this...

public ListView(IBlogRepository blogRepository)
        {
            Posts = blogRepository.Posts();
        }

Now I believe this is causing an issue. I dont know MVC very well and wonder what I can do with this. Maybe moving it out into the controller. Or creating another contructor for overloading with different parameters. Please help.
0
Comment
Question by:georgemmm
  • 2
3 Comments
 
LVL 16

Accepted Solution

by:
Imran Javed Zia earned 2000 total points
ID: 39745863
Hi,

It seems you are getting error on post and even you are not able to get it in debugger. Am I right?

then kindly define a parameter less constructor in ListView.

Generally, we do not have such ViewModels.

It will be better if you make Models  viewmodel simple by taking this constructor parameter initialization in controller.

Thanks and Regards,
0
 

Author Closing Comment

by:georgemmm
ID: 39745872
Thanks that worked. What do you mean by generally we do not have such ViewModels. Whats wrong with it?

Thanks for your advice.
0
 
LVL 16

Expert Comment

by:Imran Javed Zia
ID: 39749118
generally, view model should be a poco only. and may not contain any business logic or other implementation.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Hello there! As a developer I have modified and refactored the unit tests which was written by fellow developers in the past. On the course, I have gone through various misconceptions and technical challenges when it comes to implementation. I would…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

824 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question