Solved

MVC4 ASP.NET IRepository problem

Posted on 2013-12-30
3
486 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
Comment Utility
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
Comment Utility
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
Comment Utility
generally, view model should be a poco only. and may not contain any business logic or other implementation.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
XML to SQL Table using c# 5 44
Expando 4 33
Code works but how can I download the file? 20 44
Not needed 13 53
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
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 …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

743 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now