MVC5 passing a Model item from View to a Controller - c#

I am using .Net MVC5 and I am trying to create an Index view with an Edit Link(or button) that will POST(so I can't use ActionLink) an entire Model item Entity from the list of entities presented in the View. How do I do it?
my code(so far) is below
#model IEnumerable<Projname.Models.MyEntity>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>Hello there</th>
<th>life is good</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#using (Html.BeginForm("Edit", "Edit", FormMethod.Post))
{
#Html.Hidden(mytem => item);
<input type="submit" value="Edit" class="btn btn-default" />
}
</td>
<td>
#Html.ActionLink("Details", "Details", new { id = item.PrimeKey }) |
#Html.ActionLink("Delete", "Delete", new { id = item.PrimeKey })
</td>
</tr>
}
</table>
</body>
</html>
I am assuming that there is a better way to do it instead of creating a hidden field for each of the properties of the entity.

You need to put the items you want to edit or change into a form
<form class="form-horizontal" action="GetItemsFromView" method="post">
<input type="text" name="EditedModelItem">
</form>
Afterwards you can call any edited item in your controller, through
string hold = Request.Form["EditedModelItem"];
in the GetItemsFromView method.

Wrap everything in:
#using (Html.BeginForm("Edit", "Edit", FormMethod.Post))
{
}
Then:
public ActionResult Edit(Model model)
{
if (ModelState.IsValid)
{
}
}
Or:
public ActionResult Edit(FormCollection formCollection)
{
}

Related

MVC replacing Edit/Details/Delete with Icons

I want to replace those three fields Edit/Details/Delete with icons I just downloaded. The icons are with size 512x512, will this be a problem? Can I resize them in the code (how), or I should resize them using some program.
I've been searching through the net and I found some very long pieces of C# code but I have no idea where to put it in order to replace the text of those properties with the icons.
Here is my HTML:
#using PagedList.Mvc;
#model PagedList.IPagedList<Rating_System.Models.tblTeacher>
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Teachers List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Teachers</h2>
<p>
#Html.ActionLink("Add new", "Create")
</p>
#using (Html.BeginForm("Index", "Teachers", FormMethod.Get))
{
<p>
Търсене: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
</th>
<th>
#Html.DisplayNameFor(model => model.First().FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.First().SecondName)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Title)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
<img src="#Url.Action("GetImage", "Teachers", new {item.ID})" width="45" height="45" />
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.SecondName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.ActionLink("Редактирай", "Edit", new { id = item.ID }) |
#Html.ActionLink("Детайли", "Details", new { id = item.ID }) |
#Html.ActionLink("Изтрий", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, pageSize = Model.PageSize }))
Results #Model.FirstItemOnPage - #Model.LastItemOnPage от общо #Model.TotalItemCount Teachers
try with this code
<a href="#Url.Action("ActionName", "ControllerName", new { id = item.ID })">
<img src="#Url.Content("~/Content/imgname.jpg")" />
</a>
If you want to use an icon (Image) use the following code:
#Html.ActionLink("Редактирай", "Edit", new { id = item.ID }, new { #class="class" })
Then write you css class to include a background image
a.class
{
background: url(../Images/image.gif) no-repeat top left;
width: 50px;
height: 50px;
display: block;
text-indent: -9999px; /* hides the link text */
}
However, I would suggest using bootstrap glyphicons for example
<a href="#Url.Action("Action", "Controller")" class="btn btn-info">
Your link text
<span class="glyphicon glyphicon-time" aria-hidden="true"></span>
</a>
Or
<span class="glyphicon glyphicon-ok" style="cursor:pointer" onclick="JavascriptFunction()"></span>
And in Javascript
function JavascriptFunction() {
window.location.href = encodeURI("/Controller/Action/");
}
You can pass the ID through the javascript function

How to set page's title from the model in asp.net?

This is my view code.
#model IEnumerable<TestApplication.Models.ApplicationUser>
#{
Layout = null;
ViewBag.Title = //what goes here? Model.FirstName?
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
</body>
</html>
I want to change the ViewBag's title to whatever the FirstName is in the model. I am expecting something like ViewBag.Title = Model.FirstName. However doing so, I got an error. So what's the syntax?
The issue is that your Model is of type IEnumerable<TestApplication.Models.ApplicationUser> so you cannot call a Property of the ApplicationUser
To demonstrate the problem, try this:
ViewBag.Title = Model.First().FirstName;
The error should disapear, but this is not the correct solution. You should consider which first name out of the list of users you want to display

ASP.Net MVC random, Controllers and views

I have been having trouble creating a ASP.NET MVC program that will randomly select a student and randomly select a question and for some reason I cant get it to work in the .cshtml file. Am I doing something wrong? Also i get this Error
"The model item passed into the dictionary is of type 'QuizProgramMVC.Models.Student', but this dictionary requires a model item of type 'QuizProgramMVC.Models.StudentQuestion'."`using QuizProgramMVC.Models;
Controller
public class QuizController : Controller
{
public QuizController TheQuiz { get; set; }
// GET: Quiz
public ActionResult Index()
{
StudentQuestion sq = new StudentQuestion();
return View(sq);
}
public ActionResult QuizProgram()
{
Student program = new Student();
return View(program);
}
}
View
#model QuizProgramMVC.Models.StudentQuestion
#using QuizProgramMVC.Models;
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>QuizProgram</title>
</head>
<body>
<div>
<h1>Quiz Program</h1>
<div class="row">
<div class="col-md-6">
<table class="table table-condensed">
<thead>
<tr>
<th>Question</th>
<th>Answer</th>
</tr>
</thead>
<tbody>
#foreach (Question q in Model.Questions)
{
<tr>
<td>
#q.Quest
</td>
<td>
#q.Answer
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-6">
<table class="table table-condensed">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
#foreach (Student s in Model.Students)
{
<tr>
<td>
#s.FirstName
</td>
<td>
#s.LastName
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<br/>
#using (Html.BeginForm())
{
<div>
Type Answer: <input id="param1" name="param1" type="text" />
<br />
<input type="submit" value="Submit" />
</div>
}
</div>
</body>
</html>
The problem is you are calling the same view page with different model.
public ActionResult QuizProgram()
{
Student program = new Student();//Here you need to pass the StudentQuestion to the view.
return View(program);
}
Calling the above View Page(.cshtml) via QuizProgram() throws an error because in that view page you defined the model as
#model QuizProgramMVC.Models.StudentQuestion
It does not allow other ViewModels because it is strongly-typed View.

ASP.NET MVC PartialView with List

I am at my first MVC project. I want to create a page with a header and in this header to be placed a partial view with category list.
This is what I did so far:
I created the master page (_Home.cshtml). Than in Shared folder I created a View (Category.cshtml). See my picture.
My Category.cshtml content:
#model IEnumerable<ArtSchool.Models.Category>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Visible)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Visible)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
My master page file:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>_Home</title>
</head>
<body>
<div>
#Html.Partial("ASCX/Header")
#Html.Partial("Category")
#RenderBody()
</div>
When I run the project I got the error:
I know that is a newbie question but it's my first MVC project.
Thanks!
Solution 1
If you want to use partial view you need to pass model to this helper this way
#Html.Partial("Category", CategoryModel)
before you pass this model you have to fill it with some data.
Solution 2
also you can use #Html.Action() Method with name of ActionResult method which will return partial view for you.
for example:
#Html.Action("GetCategories", "ControllerName")
public ActionResult GetCategories() {
// fill some data for your model here
return PartialView("Category", model);
}
If you want to interpret those partials as some static sections inside your HTML, then I would suggest you to call Html.Action() which returns your partials:
#Html.Action("GetPageHeader","Home")
#Html.Action("GetPageCategories","Home")
HomeController
[HttpGet]
public ActionResult GetPageHeader()
{
return PartialView(#"~/Views/Shared/_PageHeader.cshtml");
}
[HttpGet]
public ActionResult GetPageCategories()
{
var categories = databaseContext.GetAllCategories(); //Get your categs
return PartialView(#"~/Views/Shared/_Categories.cshtml",categories);
}

The model item passed into the dictionary is of type 'a', but this dictionary requires a model item of type 'b'

public ActionResult Index(int? page)
{
var model = db.Posts.ToList();
int pageNumber = page ?? 1;
int pageSize = 10;
return View(model.ToPagedList(pageNumber, pageSize));}
in the "index" I have a box with tags, it takes the name of the tag and goes into the "Tag"
(#foreach (Webtion8.Models.Tag tag in item.Tags){
<span>#tag.Name</span>}):
#model PagedList.IPagedList<Webtion8.Models.Post>
#using PagedList.Mvc
#{
ViewBag.Title = "Index";
}
<link href="#Url.Content("/Content/PagedList.css")" rel="stylesheet" type="text/css" />
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
#foreach (var item in Model)
{<tr>
<td>
post: #Html.DisplayFor(modelItem => item.Title)
</td>
<td>
date: #Html.DisplayFor(modelItem => item.DateTime)
</td>
<td>
avtor: #Html.DisplayFor(modelItem => item.Avtor)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
<tr><td colspan="4"> tegs:
#foreach (Webtion8.Models.Tag tag in item.Tags)
{
<span>#tag.Name</span>
}
</td></tr>
<tr></tr>
<tr>
<td colspan="4">
#Html.DisplayFor(modelItem => item.Body)</td>
</tr>
<tr><td colspan="4"></td></tr>
}</table>
<div style="text-align: center;">
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }),
new PagedListRenderOptions {
LinkToFirstPageFormat = "<<",
LinkToPreviousPageFormat = "<",
LinkToNextPageFormat = ">",
LinkToLastPageFormat = ">>" })
</div>
they go to here
public ActionResult Tags(string id)
{ Tag tag = GetTag(id);
return View("Index", tag.Posts);}
and here start the problem I can not solve. In theory this code should return the page index with a sample blog entries by tag on which we clicked. But the program gives an error
The model item passed into the dictionary is of type 'System.Collections.Generic.HashSet`1[Webtion8.Models.Post]', but this dictionary requires a model item of type 'PagedList.IPagedList`1[Webtion8.Models.Post]'.
and
System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Collections.Generic.HashSet`1[Webtion8.Models.Post]', but this dictionary requires a model item of type 'PagedList.IPagedList`1[Webtion8.Models.Post]'.`
Please explain to me where I'm wrong, because the other pages I have not found an answer.
It is connected with the fact that your view is strongly typed to IPagedList<Post>
#model PagedList.IPagedList<Webtion8.Models.Post>
whereas you try to pass a HashSet of Posts as a result of your Tags action.
So instead of this:
public ActionResult Tags(string id)
{
Tag tag = GetTag(id);
return View("Index", tag.Posts);
}
You should do this:
public ActionResult Tags(string id)
{
Tag tag = GetTag(id);
//TODO define pageNumber and pageSize or pass them as parameters to your action method
return View("Index",tag.Posts.ToPagedList(pageNumber, pageSize));
}

Categories