Avatar of georgemmm
georgemmm
 asked on

MVC4 ASP.NET IRepository problem

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.
.NET ProgrammingC#Programming

Avatar of undefined
Last Comment
Imran Javed Zia

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
Imran Javed Zia

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
georgemmm

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

Thanks for your advice.
Imran Javed Zia

generally, view model should be a poco only. and may not contain any business logic or other implementation.
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy