How should I pass my query from controller using ToPagedList - asp.net-mvc

Actually i want to integrate paging in my view page and for that I am retrieving data from below code and I am passing this code from controller to view but any how I am facing issue as
var model = (from sr in db.StudentRequests
join c in db.Classes
on sr.ClassId equals c.ClassId
select new { sr.StudentRequestId,c.ClassName,sr.CreatedOn,sr.Location,sr.PaymentMethod }).ToList().ToPagedList(page ?? 1, 1);
return View(model);
and I am getting issue as
Type : InvalidOperationException
Message : The model item passed into the dictionary is of type 'PagedList.PagedList`1[<>f__AnonymousType3`5[System.Int32,System.String,System.Nullable`1[System.DateTime],System.String,System.String]]', but this dictionary requires a model item of type 'PagedList.IPagedList`1[Student_Tutor.Models.StudentRequest]'.
Source : System.Web.Mvc
My view side is as
#using PagedList;
#using PagedList.Mvc;
#model IPagedList<Student_Tutor.Models.StudentRequest>
#if (ViewBag.StudentRequest != null)
{
var StudentRequestId = (int)Model.First().StudentRequestId;// Here I am able to get the StudentRequestId
var StudentRequestTimecount = StudentRequestTime.Where(d => d.StudentRequestId == StudentRequestId).ToList();
var TutorStudentRequestcount = TutorStudentRequest.Where(d => d.StudentRequestId == StudentRequestId).ToList();
#Html.Displayfor(model => model.First().StudentRequestId)// here only text is displaying as StudentRequestId
#Html.Displayfor(Model => Model.First().CreatedOn)//here only text is diplaying as created on
}
please expalin why I am getting this error?
Update 1
var model = (from sr in db.StudentRequests
join c in db.Classes
on sr.ClassId equals c.ClassId
select new Studentvm{ StudentRequestId = sr.StudentRequestId,ClassName= c.ClassName,
CreatedOn =Convert.ToDateTime(sr.CreatedOn),Location= sr.Location,PaymentMethod= sr.PaymentMethod })
.ToList().ToPagedList(page ?? 1, 1);
return View(model);
but I am getting error as
An exception of type 'System.NotSupportedException' occurred in Student_Tutor.dll but was not handled in user code
Additional information: LINQ to Entities does not recognize the method 'System.DateTime ToDateTime(System.Object)' method, and this method cannot be translated into a store expression.

This part of your LINQ code
select new { sr.StudentRequestId,c.ClassName,sr.CreatedOn,sr.Location,sr.PaymentMethod }
That is creating an annonymous object for each item in the result collection you get from your LINQ query and you are creating a PagedList from that. But your view is strongly typed to PagedList<StudentRequest>
The ideal solution is to create a viewmodel to represent the data needed for this view and use that in the projection part of your LINQ query
public class StudentVm
{
public int StudentRequestId { set;get;}
public string ClassName { set;get;}
public DateTime CreatedOn { set;get;}
public string Location { set;get;}
}
Now use this view model for your projection
select new StudentVm { StudentRequestId = sr.StudentRequestId,
ClassName= c.ClassName,
Location = sr.Location,
CreatedOn = sr.CreatedOn }
And make sure your view is not strongly typed to PagedList<StudentVm>
#using PagedList;
#model PagedList<YourNamespace.StudentVm>
<table>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(a=> item.ClassName)</td>
<td>#Html.DisplayFor(a=> item.Location)</td>
<td>#Html.DisplayFor(a=> item.StudentRequestId)</td>
<td>#Html.DisplayFor(a=> item.CreatedOn)</td>
</tr>
}
</table>
Also, from your question, you are not really using the PagedList. To pass just a list of items, you do not need to convert that to PagedList<T> . You can simply send a List<StudentVm> from action method and change your view to be strongly typed to do that. Use PagedList if you are really using it (for paging)

Related

Want to Implement Pagination in my ASP.NET MVC TestProject Application

I want to implement Pagination in my ASP.NET MVC project.When i put #model PagedList.IPagedList<TestProject.Models.Test> in my Index page then the following error appears.
Compiler Error Message: CS1061: 'IPagedList' does not contain a definition for 'FName' and no extension method 'FName' accepting a first argument of type 'IPagedList' could be found
And When I put #model IEnumerable<TestProject.Models.Test> then it gives following error:
Argument 2: cannot convert from 'System.Collections.Generic.IEnumerable<TestProject.Models.Test>' to 'PagedList.IPagedList'
#Html.PagedListPager(Model, pageNumber => Url.Action("Index", new { pageNumber })
My Home Controller returns the following:
public ActionResult Index(int? pageNumber)
{
TestHandle testHandle = new TestHandle();
ModelState.Clear();
return View(testHandle.GetAll().ToList().ToPagedList(pageNumber ?? 1, 3));
}
My GetAll function retruns list:
public List<Test> GetAll()
{
clsUtilities cUtils = new clsUtilities();
DataSet ds;
List<Test> studentlist = new List<Test>();
string sSQL;
sSQL = "exec AllPhone";
ds=cUtils.GetDataSet(sSQL);
DataTable dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
studentlist.Add(
new Test
{
Id = Convert.ToInt32(dr["Id"]),
FName = Convert.ToString(dr["FName"]),
LName = Convert.ToString(dr["LName"]),
Address = Convert.ToString(dr["Address"])
});
}
return studentlist;
}
Please guide me. I did so much of research but no luck. So I am posting this error. Please suggest me where i am going wrong. Any help is highly appreciated.
DisplayNameFor() only accepts IEnumerable<T> when using it for a collection property. If your model is IPagedList<T>, then you can use
#Html.DisplayNameFor(m => m.FirstOrDefault().FName)
Note this will work even if the collection is empty.
As a side note, calling ModelState.Clear(); in your GET method is pointless and can be removed.

"Object Does not Contain definition for Obtained" ASP.Net MVC [duplicate]

can someone tell me what I'm doing wrong? :-)
I have this simple query:
var sample = from training in _db.Trainings
where training.InstructorID == 10
select new { Something = training.Instructor.UserName };
And I pass this to ViewBag.
ViewBag.Sample = sample;
Then I want to access it in my view like this:
#foreach (var item in ViewBag.Sample) {
#item.Something
}
And I get error message 'object' does not contain a definition for 'Something'. If I put there just #item, I get result { Something = SomeUserName }
Thanks for help.
This cannot be done. ViewBag is dynamic and the problem is that the anonymous type is generated as internal. I would recommend you using a view model:
public class Instructor
{
public string Name { get; set; }
}
and then:
public ActionResult Index()
{
var mdoel = from training in _db.Trainings
where training.InstructorID == 10
select new Instructor {
Name = training.Instructor.UserName
};
return View(model);
}
and in the view:
#model IEnumerable<Instructor>
#foreach (var item in ViewBag.Sample) {
#item.Something
}
If you want to send in ViewData For example and don't want to send in model
you could use the same could as in the upper answer
and in the Controller
enter code here
ViewData[Instractor] = from training in _db.Trainings
where training.InstructorID == 10
select new Instructor {
Name = training.Instructor.UserName
};
and in the view you need to cast this to
`IEnumerable<Instructor>`
but to do this you should use
#model IEnumerable<Instructor>
Then you could do something like this
IEnumerable<instructors> Instructors =(IEnumerable<Instructor>)ViewData[Instractor];
then go with foreach
#foreach (var item in Instructors ) {
#item.Something
}

How to return distinct data to DropDownListFor?

I apply .Net MVC structure with C#. In the controller, I want to distinct specific column (IndustryName), and return the result to Html.DropDownListFor in view. But I get a running time error at view:
System.Web.HttpException: DataBinding: 'System.String' not include
'IndustryName' property.
Is there any one meet such problem, and how to solve it?
Thank you very much for your helping.
Controller:
public ActionResult Create()
{
var industrys = this._pmCustomerService.GetAll().Select (x => x.IndustryName).Distinct();
ViewBag.Industrys = new SelectList(industrys, "IndustryName", "IndustryName", null);
return View();
}
View:
#Html.DropDownListFor(model => model.IndustryName, (SelectList)ViewBag.Industrys)
Your query is returning IEnumerable<string> (you select only the IndustryName property in the .Select() clause. string does not contain an property named IndustryName so you get this error. Just change the SelectList to
ViewBag.Industrys = new SelectList(industrys);
This will bind the options value and display text to the value of IndustryName
The following sample implementation may help you fix the problem:
var industries= this._pmCustomerService.GetAll()
.GroupBy(ind => new { ind.IndustryName})
.Select(group => new SelectListItem
{
Text = group.First().Name,
Value = group .First().Name
}
);
ViewBag.Industries= industries;
You can find more about the 'GroupBy & Select' approach instead of using linq's Distinct(), here
View
#Html.DropDownList("ddlIndustries",(#ViewBag.Industries) as IEnumerable<SelectListItem>)
If you like to use DropDownListFor helper instead then modify view code as follows:
#{
var industries = ViewBag.Industriesas IEnumerable<SelectListItem>;
}
#Html.DropDownListFor(m=> industries , industries )
You get this error because you create SelectList with wrong collection. This should work i think.
var industrys = this._pmCustomerService.GetAll().Select(x => new SelectListItem
{
Value = x.IndustryName,
Text = x.IndustryName
}).Distinct();
ViewBag.Industrys = new SelectList(industrys);
return View();
You are only Selecting IndustryName which is obviously of type String, use DistinctBy() from MoreLinq by Jon Skeet, here is the reference SO post:
public ActionResult Create()
{
var industrys = this._pmCustomerService.GetAll().DistinctBy(x => x.IndustryName);
ViewBag.Industrys = new SelectList(industrys, "IndustryName", "IndustryName", null);
return View();
}

ASP.NET MVC show collection of data in View inside of TextArea

I access data with:
public ActionResult Index()
{
//IEnumerable<ChatLogs> c = from p in db.ChatLogs select p;
//return View(c);
using (var db = new ChatLogContext())
{
var list = db.ChatLogs.ToList();
return View(list);
}
}
I would like to know how to save this collection of data inside of TextArea in View? When we used webforms we could just textBox.Text = textBox.Text + "some data from database";
View:
#model IEnumerable<Chat.Models.ChatLogs>
#Html.TextArea("chatScreen", new { #Class = "chatScreen" })
Thank you.
I'd suggest that you create a view model. For example:
class ChatLogsViewModel
{
public string LogListString { get; set; }
}
Pass that to the view, instead of passing the raw list:
var list = db.ChatLogs.ToList();
var vm = new ChatLogsViewModel { LogListString = /* convert list to single string here */ };
return View(vm);
And in the view, just do something like this:
#model Your.Namespace.ChatLogsViewModel
#Html.TextAreaFor(model => model.LogListString)
Using view models will make your life easier as soon as you decide that you want to pass more information to the view than what a single domain model can carry.
In you .cshtml view, you can access data using #Model
Now, since you have a list, I'd recommend you join it and then assign it to TextArea like
#{var strList = string.Join(" ", Model)}
#Html.TextArea("myTextArea",strList)

accessing viewbag in the view

net MVC. I have assigned a list of objects to the viewbag property can anyone please tell me as to how i can get the list in the view to use it in the drop down list? here is my controller code & view code
Controller:
public ActionResult GetSection(int sectionId,int contactId)
{
ContactDetailSectionModel contactDetailSection = new ContactDetailSectionModel { SectionId = sectionId,ContactId=contactId };
contactDetailSection.FetchAllSubsections();
ContactDetailSectionModel customSections = new ContactDetailSectionModel();
customSections.FetchCustomSubSections();
if(customSections != null && customSections.ContactDetailSubSections != null)
{
ViewBag.CustomSubSections = customSections.ContactDetailSubSections;
}
return PartialView("~/Views/Contacts/Details/EditSection.cshtml", contactDetailSection);
}
View Code:
#Html.DropDownListFor(m => m.ContactDetailSubSections[1], new SelectList(ViewBag.CustomSubSections , "Name", "Name",Model.ContactDetailSubSections[1].Name))
#Html.TextAreaFor(m => m.ContactDetailSubSections[1].Text)
I think the first parameter in your #Html.DropDownlist should be string or some scalar quantity it cannot be a collection.

Resources