ASP.NET MVC show collection of data in View inside of TextArea - asp.net-mvc

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)

Related

IEnumerable<Twitter Status> View Output MVC 5

I am trying to output a set of tweets with a certain hashtag.
I have the following code in the controller:
public ActionResult Test() {
var service = new TwitterService("xxx", "xxx");
service.AuthenticateWith("xxx", "xxx");
var options = new SearchOptions { Q = "#test" };
TwitterSearchResult tweets = service.Search(options);
IEnumerable<TwitterStatus> status = tweets.Statuses;
ViewBag.Tweets = status;
//var tweets = service.Search(options);
return View();
}
I want to output the results that are in the IEnumerable in a view.
But I am finding it difficult to output these results in a view. Can anyone help please?
Your question is a bit vague but I think I understand your problem.
You'll want to pass the data into your view from your action.
public ActionResult Test() {
var service = new TwitterService("xxx", "xxx");
service.AuthenticateWith("xxx", "xxx");
var options = new SearchOptions { Q = "#test" };
TwitterSearchResult tweets = service.Search(options);
IEnumerable<TwitterStatus> status = tweets.Statuses;
//var tweets = service.Search(options);
return View(status);
}
Notice I pass in the status object into the view.
Now in your view you can just bind that object.
#model IEnumerable<TwitterStatus>
#foreach(var status in Model){
<div>
#status.Id #*Id is an exmaple property. Use the actual properties inside "TwitterStatus"*#
</div>
}
Edit:
If you want to have multiple things inside your page you'll have to use Partial Views.
You'll need a view that will encompass all your other partial views. To do this, just define a action for your twitter info that will be your parent view.
public ActionResult AllInfo() {
return View();
}
Then your razor:
//AllInfo.cshtml
#Html.Action("Test", "YourController")
In AllInfo.cshtml we call the action "Test" inside "YourController". We'll change "Test" to return a PartialView instead of a View.
public ActionResult Test() {
var service = new TwitterService("xxx", "xxx");
service.AuthenticateWith("xxx", "xxx");
var options = new SearchOptions { Q = "#test" };
TwitterSearchResult tweets = service.Search(options);
IEnumerable<TwitterStatus> status = tweets.Statuses;
return PartialView(status);
}
The razor stays the same for your partial view:
//Test.cshtml
#model IEnumerable<TwitterStatus>
#foreach(var status in Model){
<div>
#Model.Id #*Id is an exmaple property. Use the actual properties inside "TwitterStatus"
</div>
}
You can call #Html.Action() as many times as you want in your AllInfo.cshtml page and add all the PartialViews you need.

How should I pass my query from controller using ToPagedList

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)

"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
}

An item with the same key has already been added when loading Kendo MVC Grid

I am trying to populate a Kendo mvcGrid and I keep getting the error An item with the same key has already been added.
I have seen elsewhere that duplicate model properties is the likeliest source of the problem but I have no duplicate properties in my model. I've even simplified everything to just a basic mock up to eliminate as many possible variables as possible..and I cant get the grid to load data.
I've tried it as a Html.Partial where its not loaded initially because of a empty model and then loading it through jquery...Ive tried with passing in am empty model so that the grid will load initially without data and then doing a datasource refresh...no luck there either. Basically as soon as I try to add content to the grid with a populated model I get the error and no data is loaded.
Been fighting this issue for 2 days now and had no luck. Ill post my code here maybe someone else can see what I'm missing.
One variable that cant change is the grid resides on a partial view with a model different from its parent view.
in the parent view I have tried both
<div id ="columnkgrid">#{Html.RenderPartial("Columns", new TestFieldIssue.Models.FieldListModel());}</div>
and
<div id="columnkgrid">#Html.Partial("Columns", new TestFieldIssue.Models.FieldListModel())</div>
either way will succeed in posting a grid with no data..it has no data yet because its populated by the selection of a value in a dropdown list.
so as to not over complicate the sample I've just set a hard coded value in the jquery function I have been using to refresh the grid.
function loadgrid() {
var grid = $("#grid").data("kendoGrid");
var val = 1;
grid.dataSource.read({ table_pk: val });
grid.refresh();
}
the grid code in the partial once again kept it simple without any bells and whistles just to test.
#(Html.Kendo().Grid(Model.fields)
.DataSource(data => data
.Ajax()
.Model(model => model.Id(m => m.field_pk))
.Read(r => r.Action("Columns","Home"))
)
.Name("grid")
.Columns(c =>
{
c.Bound(m => m.field_name).Title("Field Name").Width(100);
})
)
and the controller methods loading some mock data
public ActionResult Columns(int? table_pk)
{
FieldListModel model;
if (table_pk == null)
{
model = GetEmptyColumns();
}
else
{
model = GetColumns();
}
return PartialView("Columns", model);
}
public FieldListModel GetColumns()
{
FieldListModel model = new FieldListModel();
model.fields = new List<FieldModel>();
model.fields.Add(new FieldModel { field_name = "field1", field_pk = 1 });
model.fields.Add(new FieldModel { field_name = "field2", field_pk = 2 });
model.fields.Add(new FieldModel { field_name = "field3", field_pk = 3 });
return model;
}
public FieldListModel GetEmptyColumns()
{
FieldListModel model = new FieldListModel();
model.fields = new List<FieldModel>();
model.fields.Add(new FieldModel { field_name = "", field_pk = 0 });
return model;
}
and a very simple Model
public class FieldListModel
{
public List<FieldModel> fields { get; set; }
}
public class FieldModel
{
public int field_pk { get; set; }
public string field_name { get; set; }
}
I made few changes to run your code (correct version of Kendo and JQuery). May be those related to setup at my machine. I was able to reproduce the problem.
Then I changed the action code and was able to see the values populated in Grid:
public ActionResult Columns(int? table_pk, [DataSourceRequest] DataSourceRequest request)
{
FieldListModel model;
if (table_pk == null)
{
model = GetEmptyColumns();
}
else
{
model = GetColumns();
}
return Json(model.fields.ToDataSourceResult(request));
}
The change is accepting an additional parameter in action method of type DataSourceRequest. The Kendo grid wraps request in this object to specify sorting and paging information. The grid itself gets updated with data wrapped under DataSourceRequest object (note in return statement). More information here.

List of class properties

I have ASP.NET MVC 4 application with one view model class and about 20 views representing this view model. This views differs only by fields which user can edit. I want to merge all that views to one and define list of properties available to editing in strongly-typed manner. Ideally, I want something like this:
// Action
public ActionResult EditAsEngineer(int id)
{
//...
viewModel.PropertiesToChange = new List<???>()
{
v => v.LotNumber,
v => v.ShippingDate,
v => v.Commentary
};
return View(viewModel);
}
// View
if (#Model.PropertiesToChange.Contains(v => v.LotNumber)
{
#Html.TextBoxFor(m => m.LotNumber)
}
else
{
#Model.LotNumber
}
Is it possible to do something like this? Or is there a better solution?
Thank you.
Why note something like this (its pseudo code)
public class Prop{
string PropertyName {get;set;}
bool PropertyEditable {get;set;}
}
public ActionResult EditAsEngineer(int id)
{
viewModel.PropertiesToChange = new List<Prop>()
{
new Prop{PropertyName = LotNumber, PropertyEditable = true}
};
return View(viewModel);
}
#foreach (var pin Model.PropertiesToChange)
{
if(p.PropertyEditable){
#Html.TextBoxFor(p)
}else{
#Html.DisplayFor(p)
}
}
This will solve HALF of your problem. You will also need to create a IEqualityComparer<Expression> for your code to work (the default is to check for ref-equals).
return from p in typeof(T).GetProperties()
let param = System.Linq.Expressions.Expression.Parameter(typeof(T), "x")
let propExp = System.Linq.Expressions.Expression.Property(param, p)
let cast = System.Linq.Expressions.Expression.Convert(propExp, typeof(object))
let displayAttribute = p.CustomAttributes.OfType<System.ComponentModel.DataAnnotations.DisplayAttribute>()
.Select(x => x.Order).DefaultIfEmpty(int.MaxValue).FirstOrDefault()
orderby displayAttribute
select System.Linq.Expressions.Expression.Lambda<Func<T, object>>(cast, new [] {param});
This will list out ALL the properties for T. You would also probabily want to use Expression<Func<T, object>> as the type for defining your list of properties.
This will allow you to create a generic view over all properties.
Also you will want to wrap this in some kind of a cache, as this code is SLOW.

Resources