简体   繁体   中英

passing model in layout in asp.net mvc with multiple classes

I have 4 view models , one controller , _layout.cshtml and index.cshtml . the objective is to get left accordian menu in the _layout but with model

left menu willl be like a accordian menu , where clicked submenu will open and when clicked again it will close .

js - css is totaly fine - the only problem i am facing of object reference null error .

if i try it in a new view , it works , creates problem when its in layout . But i have to put it in layout.cshtml

-----------------_layout.cshtml-------------

@model LeftSubMenuFinal.ViewModels.LayoutViewModel

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
     @using (Html.BeginForm("Index", "Menu"))
        {
            <div id="accordian">
                <ul>
                    <li>
                        @{
            foreach (var MenuItem in Model._homeViewModel.LeftMenuModel)
            {
                var SubMenuItem = Model._homeViewModel.LeftSubMenuModel.Where(m => m.MainMenuID == MenuItem.ID);

                <h3><a href="@MenuItem.MainMenuURL"> @MenuItem.MainMenuItem </a></h3>

                if (SubMenuItem.Count() > 0)
                {
                    <ul>
                        @foreach (var SubItem in SubMenuItem)
                        {
                            @*<li><a href='@SubItem.SubMenuURL'>@SubItem.SubMenuItem</a></li>*@
                            <li>@Html.ActionLink(@SubItem.SubMenuItem, @SubItem.SubMenuActionURL, @SubItem.SubMenuControllerURL)</li>
                        }
                    </ul>
                }

            }
                        }
                </ul>
            </div>

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

---------------------LayoutViewModel ---------------------

public HomeViewModel _homeViewModel { get; set; }


        public LayoutViewModel()
        {

            _homeViewModel.LeftMenuModel= new List<MainMenu>();
            _homeViewModel.LeftMenuModel = _homeViewModel.GetMainMenu();
            _homeViewModel.LeftSubMenuModel = new List<SubMenu>();
            _homeViewModel.LeftSubMenuModel = _homeViewModel.GetSubMenu();
        }

-------------------------HomeViewModel---------------

 public class HomeViewModel :LayoutViewModel
    {
        public List<MainMenu> LeftMenuModel { get; set; }
        public List<SubMenu> LeftSubMenuModel { get; set; }         


        public List<MainMenu> GetMainMenu()
        {
            List<MainMenu> ObjMainMenu = new List<MainMenu>();
            ObjMainMenu.Add(new MainMenu { ID = 1, MainMenuItem = "Parent menu 1 ", MainMenuURL = "#" });
            ObjMainMenu.Add(new MainMenu { ID = 2, MainMenuItem = "Parent menu 2", MainMenuURL = "#" });
            ObjMainMenu.Add(new MainMenu { ID = 3, MainMenuItem = "Parent menu 3", MainMenuURL = "#" });
            ObjMainMenu.Add(new MainMenu { ID = 4, MainMenuItem = "Parent menu 4", MainMenuURL = "#" });
            return ObjMainMenu;
        }
        public List<SubMenu> GetSubMenu()
        {
            List<SubMenu> ObjSubMenu = new List<SubMenu>();
            ObjSubMenu.Add(new SubMenu { MainMenuID = 1, SubMenuItem = "sub menu1", SubMenuControllerURL = "#", SubMenuActionURL = "#" });
            ObjSubMenu.Add(new SubMenu { MainMenuID = 1, SubMenuItem = "sub menu2", SubMenuControllerURL = "#", SubMenuActionURL = "#" });
            ObjSubMenu.Add(new SubMenu { MainMenuID = 1, SubMenuItem = "sub menu3", SubMenuControllerURL = "#", SubMenuActionURL = "#" });


            ObjSubMenu.Add(new SubMenu { MainMenuID = 2, SubMenuItem = "sub menu1", SubMenuControllerURL = "Home", SubMenuActionURL = "Index" });
            ObjSubMenu.Add(new SubMenu { MainMenuID = 2, SubMenuItem = "sub menu2", SubMenuControllerURL = "#", SubMenuActionURL = "#" });
            ObjSubMenu.Add(new SubMenu { MainMenuID = 2, SubMenuItem = "sub menu3", SubMenuControllerURL = "#", SubMenuActionURL = "#" });
            return ObjSubMenu;
        }
    }

-----------------------MainMenu.cs------

public class MainMenu :LayoutViewModel
    {

        public int ID;
        public string MainMenuItem;
        public string MainMenuURL;
    }

------------------SubMenu.cs--------------------

 public class SubMenu :LayoutViewModel
    {
        public int MainMenuID;
        public string SubMenuItem;
        public string SubMenuControllerURL;
        public string SubMenuActionURL;
    }

-------------------------MenuController ------------

 public class MenuController : Controller
    {
        //
        // GET: /Menu/
        public ActionResult Index()
        {
            HomeViewModel model = new HomeViewModel();           

            return View("Index",model);
        }
    }

------------------Index.cshtml -- Menu controller -----------------

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
Menu - Index

----------------------Js =-----------------------

$(document).ready(function () {
    $("#accordian h3").click(function () {
        $("#accordian ul ul").slideUp();
        if (!$(this).next().is(":visible")) {
            $(this).next().slideDown();
        }
    });
});

------------------------css files --------------------------

#accordian {
    background: #4D6974;
    width: 300px;
    margin: 50px auto 0 auto;
    color: white;
   position:absolute;
   height:400px;
    /*Shadow */
    box-shadow: 0 5px 15px 1px rgba(0, 0, 0, 0.6), 0 0 200px 1px rgba(255, 255, 255, 0.5);
}
    /*heading styles*/
    #accordian h3 {
        font-size: 30px;
        line-height: 30px;
        padding: 0 15px;
        cursor: pointer;
        /*fallback for browsers not supporting gradients*/
        background: #003040;
        background: linear-gradient(#003040, #002535);
    }
        /*heading hover effect*/
        #accordian h3:hover {
            text-shadow: 0 0 1px rgba(255, 255, 255, 0.7);
        }
        /*iconfont styles*/
        #accordian h3 a {
            color: white;
            text-decoration: none;
            font-size: 20px;
            line-height: 30px;
            padding: 0 10px;
            /*transition for smooth hover animation*/
        }

            #accordian h3 a:hover {
                color: #E1E1E1;
            }
    /*list items*/
    #accordian li {
        list-style-type: none;
        background: #4D6974;
    }
    /*links*/
    #accordian ul ul li a {
        color: white;
        text-decoration: none;
        font-size: 15px;
        line-height: 27px;
        display: block;
        padding: 0 15px;
        /*transition for  hover animation*/
        transition: all 0.15s;
    }
        /*hover effect on links*/
        #accordian ul ul li a:hover {
            background: #003545;
            border-left: 10px solid red;
        }
    /* hide the non active */
    #accordian ul ul {
        display: none;
    }

    #accordian li.active ul {
        display: block;
    }

-----error coming in the below place of _layout.cshtml the model is always null

 <li>
                    @{
        foreach (var MenuItem in Model._homeViewModel.LeftMenuModel)
        {
            var SubMenuItem = Model._homeViewModel.LeftSubMenuModel.Where(m => m.MainMenuID == MenuItem.ID);

            <h3><a href="@MenuItem.MainMenuURL"> @MenuItem.MainMenuItem </a></h3>

If it's only an issue with your layout page, perhaps you need to reconsider how you have structured your view models. Something seems off in regards to the order of your Models. It should probably be structured closer to something like:

@model ViewModels.LayoutViewModel.LeftSubMenuFinal  

You could also render it as a partial view within the layout. Something like:

@{
   Html.RenderPartial("your view", your_model);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM