.net MVC passing linq data from controller to view - asp.net

I am trying to pass data from controller to view. I have searched the web but could not find a solution.
if I do this it works:
Controller:
var yyy = (from a in Connection.Db.Authorities select a) ;
ViewBag.data = yyy;
View:
#foreach(var item in ViewBag.data)
{
#item.Value
}
But the following code does not work:
Controller:
var yyy = (from a in Connection.Db.Authorities select new {Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)}) ;
ViewBag.data = yyy;
View:
#foreach(var item in ViewBag.data)
{
#item.Value
}
It gives "item does not contain a definition for Value" for the view file.
Any help would be great.
Thank you.
-edited: updated the second controller linq query. and corrected the first controller linq query.

It's because You already select Value and Value has no such property as Value. You should change in controller:
var yyy = (from a in Connection.Db.Authorities select a.Value); to
var yyy = (from a in Connection.Db.Authorities select a);
OR change the view to
#foreach(var item in ViewBag.data)
{
#item
}
//////////////////////////////////////////////// EDITS ////////////////////////////////////////////////
Than You should not use anonymous object. You should create ViewModelClass. For Example:
public class AuthoritiesViewModel
{
public string Value { get; set; }
public string TypeCode { get; set; }
public string Return { get; set; }
}
And change your controller:
var yyy = (from a in Connection.Db.Authorities select new AuthoritiesViewModel{ Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)});
ViewBag.data = yyy;
and in your view you will be able to use:
<table>
<tr>
<th>Value</th>
<th>TypeCode</th>
<th>Return</th>
</tr>
#foreach(AuthoritiesViewModel item in ViewBag.data)
{
<tr>
<td>#item.Value<td>
<td>#item.TypeCode<td>
<td>#item.Return<td>
</tr>
}
</table>
Also, I have a question to You. Why do You use ViewBag to pass data from controller to view? Why don't You use Model to pass these data to view according to MVC pattern?
//////////////////////////////////////////////// MORE EDITS ////////////////////////////////////////////////
To send more than one query result You can create more complex model. For example:
public class AuthoritiesViewModel
{
public string Value { get; set; }
public string TypeCode { get; set; }
public string Return { get; set; }
}
public class AnotherQueryViewModel
{
public string AnotherQueryValue { get; set; }
public string AnotherQueryTypeCode { get; set; }
public string AnotherQueryReturn { get; set; }
}
public class ModelClass
{
IEnumerable<AuthoritiesViewModel> Authorities { get; set; }
IEnumerable<AnotherQueryViewModel> AnotherQueryResults { get; set; }
}
And change the controller:
var yyy = (from a in Connection.Db.Authorities select new AuthoritiesViewModel{ Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)});
// do your another select
var zzz = (from smthing select new AnotherQueryViewModel ...)
// create model instance
ModelClass model = new ModelClass()
{
Authorities = yyy.AsEnumerable(),
AnotherQueryResults = zzz..AsEnumerable()
}
// return view with model
return View("view", model);
and in view you can use:
#model ModelClass
#*display first query result*#
<table>
<tr>
<th>Value</th>
<th>TypeCode</th>
<th>Return</th>
</tr>
#foreach(AuthoritiesViewModel item in Model.Authorities)
{
<tr>
<td>#item.Value<td>
<td>#item.TypeCode<td>
<td>#item.Return<td>
</tr>
}
</table>
#*display second query result*#
<table>
<tr>
<th>Another Query Value</th>
<th>Another Query TypeCode</th>
<th>Another Query Return</th>
</tr>
#foreach(AnotherQueryViewModel item in Model.AnotherQueryResults)
{
<tr>
<td>#item.AnotherQueryValue<td>
<td>#item.AnotherQueryTypeCode<td>
<td>#item.AnotherQueryReturn<td>
</tr>
}
</table>

use sth like this
ViewBag.qualification = new SelectList(db.Lookups.Where(x => x.lookup_type == "Qualification"), "lookup_content", "lookup_content");

Related

How to take value from Select/Option and inserted into href

I need help if it is possible. I have a list of classrooms, as it is in the picture below. I want to list all teachers in the "select option" and when the user selects the teacher he can click save and the classroom will be updated, as it is in the href. How can I take the value after the foreach loop?
<select id="teachers">
#foreach(var teacher in #Model.Teachers){
<option value="#teacher.Id">#teacher.Id</option>
}
</select>
<a asp-controller="Classroom" asp-action="Update" asp-route-teacherId=""></a>
<a asp-controller="Classroom" asp-action="Update" asp-route-teacherId="XX">Save</a>
First, for the above a tag helper, the generated HTML like this:
Save
or
Save
Besides, to update teachers in specific classrooms, you should also submit the classroom id to the Update action method, so, the generated URL should have multiple parameters(teacherid and classroomId), like this: Save
More detail information, see Anchor Tag Helper.
I have a list of classrooms, as it is in the picture below. I want to
list all teachers in the "select option" and when the user selects the
teacher he can click save and the classroom will be updated, as it is
in the href. How can I take the value after the foreach loop?
From your description, each classroom (row) should have a <select> element to choose the teacher and a "Save" button to update the current row update, right?
In this scenario, you could use the select element's change event to get the selected value, and then update the <a> tag href attribute.
You can refer the following sample:
Model:
public class ClassRoom
{
public int ID { get; set; }
public string Classroom { get; set; }
public string SubJect { get; set; }
public string Teacher { get; set; }
public DateTime Date { get; set; }
}
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Subject
{
public int Id { get; set; }
public string SubjectName { get; set; }
}
public class ClassRoomViewModel
{
public List<ClassRoom> ClassRooms { get; set; }
public List<Teacher> Teachers { get; set; }
public List<Subject> Subjects { get; set; }
}
Controller:
public class ClassRoomController : Controller
{
public IActionResult Index()
{
// you could query the database to get the data. The following is the test data.
var viewmodel = new ClassRoomViewModel();
viewmodel.ClassRooms = new List<ClassRoom>()
{
new ClassRoom(){ ID=1, Classroom="EOIS1", Date=DateTime.Now },
new ClassRoom(){ ID=2, Classroom="EOIS2", Date=DateTime.Now }
};
viewmodel.Teachers = new List<Teacher>()
{
new Teacher(){ Id=101, Name="Tom"},
new Teacher(){ Id=102, Name="Jack"}
};
return View(viewmodel);
}
public IActionResult Update(int teacherId, int classroomid)
{
//update the classroom
//redirect to the Index page and refresh the page.
return RedirectToAction(nameof(Index));
}
}
View Page:
#model MVCWebApplication.Models.ClassRoomViewModel
<table class="table" id="customers" >
<thead>
...
</thead>
<tbody>
#foreach (var item in Model.ClassRooms) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Classroom)
</td>
<td>
#Html.DisplayFor(modelItem => item.SubJect)
</td>
<td>
<select id="teachers" class="teachers">
<option value="0">select teacher</option>
#foreach (var teacher in #Model.Teachers)
{
<option value="#teacher.Id">#teacher.Name</option>
}
</select>
</td>
<td>
<a asp-controller="ClassRoom" asp-action="Update" asp-route-classroomid="#item.ID" asp-route-teacherId="">Save</a>
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
</tr>
}
</tbody>
</table>
#section Scripts{
<script>
$(function () {
$(".teachers").each(function (Index, item) {
$(item).change(function () {
var teacherid = $(this).val(); //get the selected value.
var existinghref = $(item).parent().parent().find("a").attr("href"); //get the hyperlink href attribute.
if (teacherid != 0) {
existinghref = existinghref + "&teacherId=" + teacherid; //add the parameter at the end of the request url.
$(item).parent().parent().find("a").attr("href", existinghref); //update the hyperlink href attribute.
}
else {
alert("Please select teacher"); //show prompt to let user select teacher.
}
});
});
});
</script>
}
The result as below:

asp net mvc3 post a list of objects to action

I created a page with aspnet mvc3. It show all users info as a list. I want to do something with this list. There are some checkboxes that belong to each items. When I click some checkboxes and press submit button, I want to post the whole list as a collection and save each items of this collection to database. There are several notes on internet but there is no exact solution. I have a UserDto. and want to use this to transfer users data in all sections.
Does anyone have any full solution about this or can they give any idea?
Thanks in advance.
Kerem
I added some of my codes. You can see the lead sentences what they are about.
this is my index view detail:
#model List<DomainModel.UserApprovalDto>
#{
ViewBag.Title = "Manage Users";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
Manage Users</h2>
<div>#Html.Partial("_PartialManageUsers", (List<DomainModel.UserApprovalDto>)Model) </div>
this is my partial view detail:
#model List<DomainModel.UserApprovalDto>
#using (Html.BeginForm("ConfirmUsers", "ManageUsers", FormMethod.Post))
{
<table>
<tr>
<th>
Name
</th>
<th>
Is Reported
</th>
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model[i].FirstName)
</td>
<td>
#Html.CheckBox("IsReported", Model[i].IsReported.HasValue ? Model[i].IsReported.Value : false)
#*#Html.CheckBoxFor(modelItem => Model[i].IsReported.Value);*# #* #if (Model[i].IsReported != null)
{
#Html.CheckBoxFor(modelItem => Model[i].IsReported.Value);
}
else
{
#Html.CheckBoxFor(modelItem => Model[i].IsReported.Value);
}*#
</td>
<td>
</td>
</tr>
}
</table>
<div>
<input name="submitUsers" type="submit" value="Save" />
</div>
}
this is my controller submit method
[HttpPost]
public ActionResult ConfirmUsers(List<DomainModel.UserApprovalDto> collection)
{
if (ModelState.IsValid)
{
//TO-DO
}
return RedirectToAction("Index");
}
this last one is my DTO class detail:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DomainModel
{
public class UserApprovalDto
{
public long UserId { get; set; }
public Guid CarUserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhotoPath { get; set; }
public string PhotoSmallPath { get; set; }
public string PhotoSquarePath { get; set; }
public string PhotoBigPath { get; set; }
public bool IsBlocked { get; set; }
public bool IsDeleted { get; set; }
}
}
when I submit this code my list return null collection to my controller method.
thanks for your comments.
Assuming you are creating a screen which adds/ remove users to a course. So let's create some viewmodels
public class CourseVM
{
public string Name { set;get;}
public int CourseID { set;get;}
public List<UserVM> Users { set;get;}
public CourseVM()
{
Users=new List<UserVM>();
}
}
public class UserVM
{
public string Name { set;get;}
public int UserID{ set;get;}
public bool IsSelected { set;get;}
}
Now in your GET Action, you will fill the values of the ViewModel and sent it to the view.
public ActionResult Add()
{
var vm = new CourseVM();
//The below code is hardcoded for demo. you may replace with DB data.
vm.Users.Add(new UseVM { Name = "Jon" , UserID=1});
vm.Users.Add(new UseVM { Name = "Scott", UserID=2 });
return View(vm);
}
Now Let's create an EditorTemplate. Go to Views/YourControllerName and Crete a Folder called "EditorTemplates" and Create a new View there with the same name as of the Property Name(UserVM.cshtml)
Add this code to your new editor template.
#model ChannelViewModel
<p>
<b>#Model.Name</b> :
#Html.CheckBoxFor(x => x.IsSelected) <br />
#Html.HiddenFor(x=>x.Id)
</p>
Now in your Main View, Call your Editor template using the EditorFor Html Helper method.
#model CourseVM
#using (Html.BeginForm())
{
<div>
#Html.EditorFor(m=>m.Users)
</div>
<input type="submit" value="Submit" />
}
Now when you post the form, Your Model will have the Users Collection where the Selected Checkboxes will be having a True value for the IsSelected Property.
[HttpPost]
public ActionResult Add(CourseVM model)
{
if(ModelState.IsValid)
{
//Check for model.Users collection and Each items
// IsSelected property value.
//Save and Redirect(PRG pattern)
}
return View(model);
}

Pass a model to an MVCMailer view

I have a controller, which passes a model (ovw.ToList()) to a view:
//
// GET: /Clinic/Overview/
public ActionResult Overview()
{
IEnumerable<Clinic> ovw = from c in db.Clinics
select c;
return View(ovw.ToList());
}
View:
#model IEnumerable<ttp.Models.Clinic>
#foreach (var item in Model)
{
<div>#item.ClinicName</div>
#foreach (var item2 in item.Properties)
{
<div>#item2.Address</div>
This works absolutely fine on screen.
When using MVCMailer, however , if I want to display the same layout in the email, how do I pass the ovw.ToList() to the mailer view, so that I can reference the same model in this way:
(I'm stuck on what to put in as the first line in the view):
#model IEnumerable<ttp.Models.Clinic>
#foreach (var item in Model)
Thanks for any help,
Mark
You should find your answer in the 'Pass Data to Mailer Views' part of this guide: https://github.com/smsohan/MvcMailer/wiki/MvcMailer-Step-by-Step-Guide
To pass your model along with the view to MVCMailer, you need to use ViewData:
var comment = new Comment {From = me, To = you, Message = "Great Work!"};
ViewData = new ViewDataDictionary(comment);
In my project i doing like this it's below
i am showing all my category list in my index view
in my model class
public List<CategoryDetails> CategoryData { get; set; }
and i am also create CategoryDetails class and create a property to all my field
like this
public int CatID { get; set; }
[Required(ErrorMessage = "Enter Category Name")]
public string CatName { get; set; }
public string CatImage { get; set; }
and create a function in my main model class like this
public void LoadCategory()
{
CategoryData = (from con in dbData.Categorys
select new CategoryDetails()
{
CatID = con.CatID,
CatName = con.CatName,
CatImage = con.CatImage,
}).ToList();
}
In my controller i create a action like this
create my model class object and pass my model function to action
public ActionResult Index()
{
CategoryModel categorymodel = new CategoryModel();
categorymodel.LoadCategory();
return View(categorymodel);
}
and in my view
#model PMS.Models.CategoryModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Category Name
</th>
<th>
</th>
</tr>
#foreach (var item in Model.CategoryData)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CatName)
</td>
</tr>
}
</table>
i think this will help you

Dynamic link issue in an MVC 3 website

I'm creating my first ASP.NET MVC 3 website for my company's intranet. It's a pretty cool, I play audio recorded by our phone system and saved in our db. That's working good, but I'm having a hard time figuring out how to do something that should be simple. Please forgive any syntax errors I most likely have, this is a rough draft.
I have a table in the Index View /Apps that list all the AppName's, and next to each AppName I want to display a link to another view, with the text of the link being a Count() of all CallDetails associated with that App.
I have two classes:
public class Apps
{
public int AppId { get; set; }
public string AppName { get; set; }
}
public class CallDetail
{
public int Id { get; set; }
public int AppID { get; set; }
public byte[] FirstName { get; set; }
public byte[] LastName { get; set; }
....etc
}
a context for each:
public class AppsContext : DbContext
{
public DbSet<Apps> Apps { get; set; }
}
public class CallContext : DbContext
{
public DbSet<CallDetail> CallDetails { get; set; }
}
a controller method for each:
// AppsController
private AppsContext db = new AppsContext();
public ViewResult Index()
{
return View(db.Apps.ToList());
}
// CallController method (from my current attempt)
public ActionResult CallCheck(int id)
{
bool? enabled = null;
var appcalls = from s in db.CallDetails
where s.AppID == id
&& s.Enabled.Equals(enabled)
select s;
string callnum = appcalls.Count().ToString();
return View(callnum);
}
It displays the AppName just fine in this portion of the View below, and I can create a link to a View for each associated CallDetail just fine. But I don't know how to display info I'd get from the CallDetail Controller since the View's Model is Apps and its Controller, AppsController.
#model IEnumerable<myMessagePlayer.Models.Apps>
...
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.AppName)
</td>
<td class="appLink">
...
</td>
</tr>
}
I've tried many different methods, some that I might have gotten to work, but they seemed semantically un-MVC. So I figured I'd just ask a general "whats the standard practice?" type of question.
The path you are currently going down would end up hitting the database for each app you have in your database. There is a way to display all the information with only one hit to the database.
Your context needs to change to this:
public class ApplicationContext : DbContext
{
public DbSet<Apps> Apps { get; set; }
public DbSet<CallDetail> CallDetails { get; set; }
}
You could create a view model object called AppCallInfo that has three properties:
public class AppCallInfo
{
public int AppID { get; set; }
public string AppName { get; set; }
public int CallCount { get; set; }
}
In your Index action you need to do something like this:
public ViewResult Index()
{
var model = from a in db.Apps
join c in db.CallDetails on a.AppID equals c.AppID
where c.Enabled == enabled
group a by new { AppName = a.AppName, AppID = a.AppID } into g
select new AppCallInfo {
AppName = g.Key.AppName,
AppID = g.Key.AppID,
CallCount = g.Count()
};
return View(model.ToList());
}
Now you have everything you need for each row in your table in one object.
#model List<myMessagePlayer.ViewModels.AppCallInfo>
...
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.AppName)
</td>
<td class="appLink">
#Html.ActionLink(item.CallCount, "ViewCalls", "Call", new { Id = item.AppID }, null)
</td>
</tr>
}
Using this method avoids hitting the database for each app you have in your table.
Is the view CallCheck a partial view?
In your index view you could use
#Html.RenderAction("CallCheck", "AppsController", new { Id = #Model.AppId } )
The syntax may not be 100% correct, but it should get you going in the right direction.

The model item is of type CookMeIndexViewModel, but requires a model item of type IEnumerable<CookMeIndexViewModel>

I am following along with the music store example to try learn ASP.NET MVC. I'm creating a cookbook application.
I have created my viewmodel that looks like this:
namespace CookMe_MVC.ViewModels
{
public class CookMeIndexViewModel
{
public int NumberOfReceipes { get; set; }
public List<string> ReceipeName { get; set; }
}
}
my controller looks like this
public ActionResult Index()
{
var meals= new List<string> { "Dinner 1", "Dinner 2", "3rd not sure" };
//create the view model
var viewModel = new CookMeIndexViewModel
{
NumberOfReceipes = meals.Count(),
ReceipeName = meals
};
return View(viewModel);
}
Finally my view looks like this
#model IEnumerable<CookMe_MVC.ViewModels.CookMeIndexViewModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th></th>
<th>
Meals
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
<td>
#item.ReceipeName
</td>
</tr>
}
</table>
I get this error.
The model item passed into the dictionary is of type CookMeIndexViewModel, but this dictionary requires a model item of type IEnumerable<CookMeIndexViewModel>.
I have followed the example. I can't see what I am doing wrong. Should I be returning my viewmodel as a generic list?
In your view you are using #model IEnumerable<CookMe_MVC.ViewModels.CookMeIndexViewModel> which indicates that the model expected by the View is of type IEnumerable of CookMeIndexViewModel.
However in the controller you are passing an object of type CookMeIndexViewModel as a model return View(viewModel); hence the error.
Either change the view to have #model CookMe_MVC.ViewModels.CookMeIndexViewModel
or pass a IEnumerable of CookMeIndexViewModel as model to the view in controller as given below:
public ActionResult Index()
{
var meals= new List<string> { "Dinner 1", "Dinner 2", "3rd not sure" };
//create the view model
var viewModel = new CookMeIndexViewModel
{
NumberOfReceipes = meals.Count(),
ReceipeName = meals
};
List<CookMeIndexViewModel> viewModelList = new List<CookMeIndexViewModel>();
viewModelList.Add(viewModel);
return View(viewModelList);
}
I got this message when I had a conflict between what the #model directive in the _Layout.cshtml layout view and an "inner page" view.
The _Layout.cshtml had directive..
#model MyProject.Models.MyObject
My inner page had...
#model IEnumerable<MyProject.Models.MyObject>
I was working on some test / experiment code and hit this issue when I created new controller etc. It was only when I renamed Model Object and compiled afterwards that I found the source of the problem.
Hope this helps.
Q.
in kendo ui Grid do :
public class BookBean
{
[ScaffoldColumn(false)]
public Int32 Id { set; get; }
public String Title { set; get; }
public String Author { set; get; }
public String Publisher { set; get; }
[UIHint("Integer")]
public Int32 Price { set; get; }
[UIHint("Integer")]
public Int32 Instore { set; get; }
[UIHint("Integer")]
public Int32 GroupId { get; set; }
}
in Integer.ascx in Shared/EditorTemplate folder do :
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int?>" %>
<%: Html.Kendo().IntegerTextBoxFor(m => m)
.HtmlAttributes(new { style = "width:100%" })
.Min(int.MinValue)
.Max(int.MaxValue)
%>

Resources