Controller to View via ViewData - asp.net-mvc

This is View File here Displaying error for student in list
#model IEnumerable<Controller2View.Models.Students>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div class="container">
<div class="btn btn-default">
<ul class="list-group">
#foreach (var std in ViewData["StudentData"] as List<Students>)
{
<li class="list-unstyled">
std.StudentName
</li>
}
</ul>
</div>
</div>
</body>
</html>
This is Controller file which have a list defined and viewdata for transferring data from controler to View. Model also defined well but dont know whu its not working.
public ActionResult Index()
{
List<Students> studentList = new List<Students>() {
new Students(){ StudentId=1, StudentName="Steve"},
new Students(){ StudentId=2, StudentName="Bill"},
new Students(){ StudentId=3, StudentName="Ram"}
};
ViewData["StudentData"] = studentList;
return View(studentList);
}

Would be good to know what exactly is not working. But still 2 things:
Either use the view with a model or with ViewData.
I guess you get a list of 3 items with "std.StudentName", that's because it must read #std.StudentName

Use below code in controller
public ActionResult Index()
{
var studentList = new List<Students>() {
new Students(){ StudentId=1, StudentName="Steve"},
new Students(){ StudentId=2, StudentName="Bill"},
new Students(){ StudentId=3, StudentName="Ram"}
};
return View(studentList);
}
Now, In View use below code
#model IEnumerable<Controller2View.Models.Students>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div class="container">
<div class="btn btn-default">
<ul class="list-group">
#foreach (var std in Model)
{
<li class="list-unstyled">
std.StudentName
</li>
}
</ul>
</div>
</div>
</body>
</html>
Hopefully it will works as I am using model directly instead of casting it into list.

Related

Returning string to _Layout.cshtml using PartialView

I'm trying to return a string list to a navigation menu that appears on the side of my _Layout.cshtml page. I can return a string fine, but I'm supposed to be returning a PartialViewResult. This is the error I get:
{"The partial view 'Menu' was not found or no view engine supports the searched locations. The following locations were searched:\r\n~/Views/Nav/Menu.aspx\r\n~/Views/Nav/Menu.ascx\r\n~/Views/Shared/Menu.aspx\r\n~/Views/Shared/Menu.ascx\r\n~/Views/Nav/Menu.cshtml\r\n~/Views/Nav/Menu.vbhtml\r\n~/Views/Shared/Menu.cshtml\r\n~/Views/Shared/Menu.vbhtml"}
My Controller code:
using SportsStore.Domain.Abstract;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace SportsStore.WebUI.Controllers
{
public class NavController : Controller
{
private IProductRepository repository;
public NavController(IProductRepository repo)
{
repository = repo;
}
public PartialViewResult Menu()
{
IEnumerable<string> categories = repository.Products
.Select(x => x.Category)
.Distinct()
.OrderBy(x => x);
return PartialView(categories);
}
}
}
My _Layout.cshtml file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
<title>#ViewBag.Title</title>
</head>
<body>
<div class="navbar navbar-inverse" role="navigation">
<a class="navbar-brand" href="#">SPORTS STORE</a>
</div>
<div class="row panel">
<div id="categories" class="col-xs-3">
#Html.Action("Menu", "Nav")
</div>
<div class="col-xs-8">
#RenderBody()
</div>
</div>
</body>
</html>
Where is your Menu view located?
If you don't explicitly define what your View is called, MVC will take the initiative and assume it's named the same as your Action, so in this case, you need to have a Menu.cshtml file in one of the following locations :
~/Views/Nav/Menu.cshml
~/Views/Shared/Menu.cshtml
Or if it is named anything other than Menu.cshtml, you may want to consider specifying that within your code :
// This assumes your partial view is named "_Menu.cshtml"
return PartialView("_Menu",categories);
#Rion Willimas, you are correct. The book I was following had a small mistake. In the next chapter, it had me create a Menu.cshtml file and then it all rendered fine.
Menu.cshtml below:
#model IEnumerable<string>
#Html.ActionLink("Home", "List", "Product", null,
new { #class = "btn btn-block btn-default btn-lg"})
#foreach (var link in Model)
{
#Html.RouteLink(link, new
{
controller = "Product",
action = "List",
category = link,
page = 1
}, new
{
#class = "btn btn-block btn-default btn-lg"
})
}

Ajax missunderstanding, or an error?

Can you please explain me how should i use Ajax properly.
I have an easy example in Asp.Net MVC:
This is my layout view
<html>
<head>
//scripts
</head>
<body>
<div id="header">
<div class="logo">
<img id="LogoImg" src="http://www.ruralcomshow.com/wpontent/uploads/2014/06/Midwest-Data-Center-Logo-175x75.png" />
</div>
</div>
<div class="wrapper">
<div class="left-side">
//some navigation
</div>
<div id="right-side">
#RenderBody()
</div>
</div>
<div id="footer">
<div class="clearfix">
//some footer
</div>
</div>
</body>
</html>
This is my controller:
public class HomeController : Controller
{
public PartialViewResult Ajax()
{
return PartialView();
}
public ActionResult Index()
{
return View();
}
}
This is Ajax partial view:
<h2>This is how it's done</h2>
#Html.ActionLink("back :C","Index","Home")
This is Index view:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Ajax.ActionLink("Go, go Ajax!", "Ajax", "Home", new AjaxOptions { UpdateTargetId = "right-side", InsertionMode = InsertionMode.Replace})
So, as I understood when i click Ajax ActionLink my whole page should not rerender, and the only thing that should change is div with id "right-side"? So the problem is that the whole page always gets rerendered.
Am I doing something wrong? Or is this a problem of my understanding?
Include jquery and unobtrusive-ajax at the bottom of the page as shown :-
</footer>
#Scripts.Render("~/bundles/jquery")
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
#RenderSection("scripts", required: false)
</body>
</html>

Jquery mobile dialog return in MVC post action

I am using JQuery Mobile 1.4 and MVC 4 to test dialog. But I don’t know what should be returned in dialog post action.
There are two questions:
1. What should be returned for dialog action
2. The input data in master page will be lost after dialog post
Master page View Code:
#model MvcApplication4.Models.ViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TestDialog</title>
<meta name="viewport" content="width=device-width" />
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="/Content/site.css" rel="stylesheet"/>
<link href="/Content/jquery.mobile-1.4.0-beta.1.css" rel="stylesheet" />
<script src="/Scripts/modernizr-2.6.2.js"></script>
<script src="/Scripts/jquery-2.0.3.js"></script>
<script src="/Scripts/jquery-ui-1.10.3.js"></script>
<script src="/Scripts/jquery.mobile-1.4.0-beta.1.js"></script>
</head>
<body>
<div id="layoutPage" data-role="page" data-theme="a">
<div id="layoutHeader" data-role="header">
<h2>TestDialog</h2>
</div>
<div id="layoutContent" data-role="content">
#using (Html.BeginForm())
{
<div>
<div class="editor-label">
#Html.LabelFor(model => model.IDDocument)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.IDDocument)
#Html.ValidationMessageFor(model => model.IDDocument)
</div>
</div>
<div data-role="controlgroup" data-type="horizontal" data-mini="true">
<a id="addDetail" href="#Url.Action("ShowDialog", "SampleTest")" data-rel="dialog" data-role="button" >Test dialog</a>
</div>
}
</div>
</div>
<script>
$(document).on("mobileinit", function () {
$.mobile.ajaxEnabled = false;
});
</script>
</body>
</html>
Dialog View Code:
#model MvcApplication4.Models.ViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>DialogView</title>
</head>
<body>
<div id="detailPage1" data-role="dialog" >
#using (Html.BeginForm("ShowDialogActioinPost", "SampleTest", FormMethod.Post))
{
<div data-role="header">
<button type="submit" data-icon="check" class="ui-submit" data-inline="true" data-mini="true">Save</button>
<h2 >Dialog Information</h2>
<a data-rel="back" data-icon="back">Go back</a>
</div> //end header
<div data-role="content">
<div class="editor-label">
#Html.LabelFor(model => model.SeqNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SeqNo)
#Html.ValidationMessageFor(model => model.SeqNo)
</div>
</div>
}
</div>
</body>
</html>
Controller Code:
[HttpGet]
public ActionResult ShowDialog()
{
return View("DialogView");
}
[HttpPost]
public ActionResult ShowDialogActioinPost(ViewModel vm)
{
return View("Index"); // should return to master page, but it doesn't work
}
Thanks
Wilson
Try RedirectToAction("Index"); instead of View("Index");
You have to return the model to your master page.
[HttpPost]
public ActionResult ShowDialogActioinPost(ViewModel vm)
{
return View("Index", vm);
}
The answer is here.
Thanks
Wilson

Angular doesn't parse curly brackets

I don't get Angular to work. The thing that happens is dat I see literally {{ foobar }} on the screen.
Here are my files:
Index.cshtml of /App/Index:
#{
Layout = null;
}
<!DOCTYPE html>
<html data-ng-app="tournament">
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Angular/app.js"></script>
<script src="~/Angular/routes.js"></script>
</head>
<body>
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Title</a>
<ul class="nav">
<li class="active">Toernooien</li>
<li>Link</li>
<li>Link</li>
</ul>
</div>
</div>
<div data-ng-view=""></div>
</body>
</html>
app.js:
var app = angular.module("tournament", []);
routes.js:
app.config(function ($routeProvider) {
$routeProvider
.when('/', { templateUrl: '/Home/Index', controller: 'HomeController' });
});
HomeController.js:
app.controller('HomeController', function ($scope) {
$scope.foobar = 'barFoo';
});
Index.cshtml of /Home/Index
<script src="~/Angular/Controllers/HomeController.js"></script>
<div>
Home/index
<br />
<input type="text" data-ng-model="foo" />
{{ foobar }}
</div>
Thanks everyone for helping me. I finally figured it out. The problem was in my MVC controller.
This is what I had originally:
public ActionResult Index()
{
return View();
}
And this is the solution:
public ActionResult Index()
{
return PartialView();
}
Now, everything is working like it should be.

Value cannot be null or empty. Parameter name: contentPath

I have a multi-level Layout master pages in an ASP.NET MVC 4.
I have the following:
<title>#ViewBag.Title</title>
The order of Layout pages is as follows:
_Layout.cshtml
_SubLayout.cshtml (based on _Layout.cshtml)
Index.cshtml (based on _SubLayout.cshtml)
I am setting the #ViewBag.Title inside Index Action. However, I get the following exception:
Value cannot be null or empty. Parameter name: contentPath
Here is the code I have. I am simply making the code of ASP.NET Design Patterns books work for VS 2012 / MVC 4
_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="main">
<div id="header">
<span><a href="#Url.Content("")">
<img alt="Agatha's Clothing Store"
src="#Url.Content("/Content/Images/Structure/lg_logo.png")"
border="0" /></a></span>
</div>
<div id="headerSummary">
#RenderSection("headerBasketSummary", required: false)
</div>
<div class="topBarContainer">
<div id="background">
<div id="navigation">
#RenderSection("MenuContent", required: false)
</div>
<div id="content">
#RenderBody()
</div>
<div style="clear: both;" />
</div>
</div>
#Html.Partial("_SiteFooter")
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.0/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-jtemplates.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/agatha-common-scripts.js")"></script>
</body>
</html>
_ProductCatalogProduct.cshtml
#model BaseProductCatalogPageView
#using Agathas.Storefront.Controllers.ViewModels.ProductCatalog
#using Agathas.Storefront.UI.Web.MVC.Helpers
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#if (IsSectionDefined("MenuContent"))
{
#RenderSection("MenuContent", required: false)
}
else
{
#Html.Partial("_Categories", ((BaseProductCatalogPageView)Model).Categories)
}
#RenderBody();
Index.cshtml
#model HomePageView
#using Agathas.Storefront.Controllers.ViewModels.ProductCatalog
#using Agathas.Storefront.Services.ViewModels
#using Agathas.Storefront.UI.Web.MVC.Helpers
#{
Layout = "~/Views/Shared/_ProductCatalogLayout.cshtml";
ViewBag.Title = "Home Page";
}
<img width="559" height="297"
src="#Url.Content("~/Content/Images/Products/product-lifestyle.jpg")"
style="border-width: 0px; padding: 0px; margin: 0px" />
<div style="clear: both;"></div>
<h2>Top Products</h2>
<div id="items" style="border-width: 1px; padding: 0px; margin: 0px">
<ul class="items-list">
#foreach (ProductSummaryView product in Model.Products)
{
<li class="item-detail">
<a class="item-productimage-link" href="#Url.Action("Detail", "Product", new { id = product.Id }, null)">
<img class="item-productimage" src="#Url.Content("~/Content/Images/Products/" + product.Id.ToString() +".jpg"))" /></a>
<div class="item-productname">#Html.ActionLink(product.BrandName + " " + product.Name, "Detail", "Product", new { id = product.Id }, null)</div>
<div class="item-price">#product.Price</div>
</li>
}
</ul>
</div>
Many thanks
This piece of code is throwing the exception: <a href="#Url.Content("")">. This happens because contentPath parameter of Url.Content method cannot be null or empty.
This can happen if you are assigning a value in the Child Razor view file that is also set in the parent one, but is displayed in a partial called by the Layout.cshtml
For example
_Layout.cshtml
|
(parent of)
|
Parent.cshtml
|
(parent of)
|
Page1.cshtml
In Page1.cshtml I do
ViewBag.Title= "Value1";
In Parent.cshtml I do the same but using the Umbraco call:
ViewBag.Title = Umbraco.Field("value").ToString();
The fix is to remove the assignment in Parent.cshtml. This appears to be a bug and I'm afraid that this is the only fix I've found. Hope it helps you out...
You should check if path not null or empty before use it as source of image
#foreach (var post in Model)
{
<div class="col-md-6">
<div class="product-list post-list">
#if (!string.IsNullOrWhiteSpace(post.Photo))
{
<a href="#" class="product-list-img">
<img src="#Url.Content(post.Photo)" alt="">
</a>
}
</div>
</div>

Resources