Solved

MVC4 ASP.NET IRepository problem

Posted on 2013-12-30
3
495 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 500 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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …

830 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