6

I am creating a Sitecore 8.2 MVC test website and I am getting couple of errors and client form validation Issue. Get methods are working fine but post method is not working. I have exact same test site working fine with ASP.NET MVC but now I am trying to convert into a Sitecore application.

Here is my code

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*"));

        // Use the development version of Modernizr to develop with and learn from. Then, when you're
        // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
        bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                    "~/Scripts/modernizr-*"));

        bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                  "~/Scripts/bootstrap.js",
                  "~/Scripts/respond.js"));

        bundles.Add(new StyleBundle("~/Content/css").Include(
                  "~/Content/bootstrap.css",
                  "~/Content/site.css"));
    }
}

Here is my controller

public class MoviesController : SitecoreController
{
    public ActionResult GetMovieItems()
    {
        var movieItemsDatasource = Sitecore.Context.Database.GetItem("/sitecore/content/CustomData/Movies");
        List<MovieItem> movieItems = new List<MovieItem>();
        foreach (var item in movieItemsDatasource.Children)
        {
            var movieItem = new MovieItem(item as Sitecore.Data.Items.Item);
            movieItems.Add(movieItem);
        }
        //return View("~/Views/MVCDemo/Renderings/Movies/MoviesList.cshtml", movieItems);
        return View("~/Views/MVCDemo/Renderings/Movies/MoviesList.cshtml", movieItems);
    }
    public ActionResult GetByName(string Name)
    {
        var movieItemsDatasource = Sitecore.Context.Database.SelectItems("/sitecore/content/CustomData/Movies//*[@Title = \"First Movie\"]").FirstOrDefault();
        return View("~/Views/MVCDemo/Renderings/Movies/MovieDetail.cshtml", new MovieItem(movieItemsDatasource as Sitecore.Data.Items.Item));
    }
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddNew(MovieItem movieItem)
    {
        if (ModelState.IsValid)
        {
            var movieItemsDatasource = Sitecore.Context.Database.SelectItems("/sitecore/content/CustomData/Movies//*[@Title = \"First Movie\"]").FirstOrDefault();
            return RedirectToAction("GetMovieItems");
        }
        return GetDefaultAction();
    }
    public ActionResult AddNewMovie()
    {
        return View("~/Views/MVCDemo/Renderings/Movies/AddMovie.cshtml");
    }
}

GetMovieItems and GetByName methods are working fine. I have created an AddMovie form

@using Sitecore8MVC.Web.Code
@model MovieItem

<h1>Add NewMovie</h1>
@using(Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.
SitecoreRoute 
Name, FormMethod.Post))
{ 
@Html.Sitecore().FormHandler("Movies", "AddNew")
@Html.AntiForgeryToken()
<div class="form-horizontal">
    <h4>Movie</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Title, "asdsa", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.ReleaseDate, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.ReleaseDate, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.ReleaseDate, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Genre, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Genre, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Genre, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.Rating, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Rating, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Rating, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

When I post my form, validation is not working, here is my Model

public class MovieItem1
{
    [Required(ErrorMessage = "Please supply an address")]
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public string Price { get; set; }
    public string Rating { get; set; }
}

and

public class MovieItem : CustomItem
{

    public MovieItem(Item innerItem) : base(innerItem)
    {
    }
    public string Title { get { return InnerItem["Title"]; } }
    public DateTime ReleaseDate { get { return ((Sitecore.Data.Fields.DateField)InnerItem.Fields["Release Date"]).DateTime; } }
    public string Genre { get { return InnerItem["Genre"]; } }
    public string Price { get { return InnerItem["Price"]; } }
    public string Rating { get { return InnerItem["Rating"]; } }
}

Here is the snapshot of all Css and JS classes loaded through bundle

enter image description here

and my main.cshtml page

@using Sitecore.Mvc
@using System.Web.Optimization
@* @using Sitecore.Mvc.Analytics.Extensions *@
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
@Html.Sitecore().ViewRendering("~/Views/MVCDemo/Layouts/Metadata.cshtml")
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")

@Html.Sitecore().ControllerRendering("TopNavigation", "GetMenuItems")

<div class="container body-content">
    @Html.Sitecore().Placeholder("body")
    <hr />
    <footer>
        <p>&copy; @DateTime.Now.Year - MVC Movie</p>
    </footer>
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")

Issues

Update Validation issue has been fixed, client validation issue fixed by adding "ClientValidationEnabled" and "UnobtrusiveJavaScriptEnabled" in web.config file or you can add directly on Layout.cshtml page. Modal issue also got fixed by changing router as told by Peter Prochazka.

I am still getting "No parameterless constructor defined for this object." after submitting the form which is due to the Modal being inherited form sitecore CustomItem, If I use other Modal which is not being inherited from CustomItem, It works fine.

  • Ali, this was an excellent example of 'showing your work'. I really hope somebody can help you, thank you for being so thorough! – Jason St-Cyr Jul 5 '18 at 1:46
  • Instead of your using... Begin.form line add this:@using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post)) { @Html.Sitecore().FormHandler("Movies", "AddNew") – Peter Procházka Jul 5 '18 at 8:36
  • code updated with changes you recommended but form validation is still not working, secondly I had to use MovieItem1 Modal which is not inheriting from CustomItem, When I post the form, I get Modal.IsValid false and it just returns the same page back. – Ali Jul 9 '18 at 0:39
  • @Ali Can you take your update of the answer that fixed it for you, and place that as an answer and mark it as the answer. – Dylan Young Sep 27 '18 at 19:06
  • It is partially fixed. – Ali Sep 28 '18 at 22:05
0

I am still getting "No parameterless constructor defined for this object." after submitting the form which is due to the Modal being inherited form sitecore CustomItem, If I use other Modal which is not being inherited from CustomItem, It works fine.

Answer of yours last pending issue: Here below code,model MovieItem you need to define default constructor so MVC can call this.

        public class MovieItem : CustomItem
        {
            // MVC can call this.
            public MovieItem() 
            {
            }

            // MVC can't call this.
            public MovieItem(Item innerItem) : base(innerItem) 
            {
            }

            public string Genre { get { return InnerItem["Genre"]; } }
            public string Price { get { return InnerItem["Price"]; } }
            public string Rating { get { return InnerItem["Rating"]; } }
        }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.