Displaying results in View linq to sql mvc 4 - c#

I have been reading and reading , and I can't seem to get this to work at all. I am very very new to asp.net MVC - after all the tutorials I read I finally got this much accomplished.
public class EventsController : Controller
{
private EventsDBDataContext db = new EventsDBDataContext();
public ActionResult Index()
{
var a = (from x in db.tblEvents
where x.StartDate >= DateTime.Now
select x).Take(20).ToList();
return View(a);
}
}
This is successfully finding 20 rows (like it is supposed to). Now how do I display these in the view ?? Does it have to be a strongly typed view?? It doesn't seem like it should have to be... I have tried both , I tried typing a whole view, but for now it would be nice to just get one property of tblEvents to show up in the view. This is not working, I have tried many many variations.
#{foreach( var item in Model){
#Html.DisplayFor( item.ID)
}
}
How do I get the results from the controller displayed in the view? Just the ID is good for now - I can go from there.

The problem is that your View doesn't know what type your Model is. Use the #model syntax to define the type of your model.
#model List<YourEventClass>
#foreach( var item in Model )
{
#item.ID<br />
}
See i.e. here for more information

from the root of the web project you should have a directory called Views. Within the views folder create a new folder named Events. In the Events folder create a razor view named Index. put your markup and template code in this file.
You are correct, views do not need to be strongly typed. I find it's a good idea to do so because it provides another compile time check, but it's not required.
when you run the application you will navigate from the root (typically home/index) to Events/Index. there you should see the list of 20 items rendered in the view.

I guess you can not do something like this:
#{foreach( var item in Model){
#Html.DisplayFor(modelItem => item.ID)
}
unless the view knows what Type Model is returned as (still seems weird that .Net can't figure that out on its own. So I fixed the problem and got the ID displayed properly by adding this to the View.
#model IEnumerable<GetEvents.Models.tblEvent>
This works fine for this example - I am returning one table , so the Model type is just the class for the table. But this doesn't seem right - what if I wanted to query and join tables then what would the Model Type be?? Adding this fixed my problem , but if someone has a better answer for this then I will accept that.

Related

Determining If Element is In Dependent View (Revit API)

I'm trying to write a macro for Revit 2020 and 2018 in C#. So far, I have written a program that takes selected elements and filters them if they are within a particular view. However, issues arise when using dependent views because when selecting all elements in a view, it also selects everything in the other dependent views. I don't want this to happen. I'd like to find a way of filtering elements that are only within one particular dependent view.
I've tried having the user select from all available views, but it still treats a dependent view as though it were the larger superview.
The easiest way to solve this would be if there were a way to check membership to a particular view. However, I haven't figured out how to do this. Any suggestions?
Copied from Tray Gates' answer to check if the parameter exist - check if the view is dependent or callout:
You can check to see if a view is a dependent view using GetPrimaryViewId from a view element.
If the result is -1, it is NOT a dependent view.
If it is any other integer, it is a dependent.
Here is an example:
var views = new FilteredElementCollector(doc)
.OfClass(typeof(View));
foreach (View view in views)
{
ElementId parentId = view.GetPrimaryViewId();
if (parentId.IntegerValue == -1 && !view.IsTemplate)
{
// View is NOT a dependent
}
else if (parentId.IntegerValue != -1 && !view.IsTemplate)
{
// View is dependent
}
}
Note that -1 is shorthand for ElementId.InvalidElementId.
Later: I see that you asked the same question in the Revit API forum thread on Determining If Element is in Dependent View, received other answers there, and discovered that your need is in fact different and more complicated...

Object with items : View-Controller communication

So, I have no clue how to search for an answer to this problem, mainly because there are several aspects to it which I don't know how to solve. So - here it is.
I have an object, let's call it ObjectWithItems which has a List<Item> of Item objects. Both have separate Views and Controllers (which seems logical to me, but I can't be sure).
What I'm trying to achieve is this – go to Create action of ObjectWithItemsController and fill the necessary information specific to it. Then, I click an ActionLink "Add item", which takes me to the Create action of the ItemController. The View is rendered and I enter information for that specific Item.
What I don't know how to do is the following: when I submit the current Item, it should be passed to the former Create view of the ObjectWithItems and added to the List<Item>. Furthermore, it should contain the information inputted before calling the Item Create method and the rendering of the corresponding View.
I know this is a bit blurry description, but that is because I have just started learning ASP MVC and still don't know what's what. Any tested approaches for this?
Using Session["key"] object allow you to store any kind of object, Ex :
List<Table> Rows = db.Table.Where(t => t.id < 100).ToList(); // 100 first rows
Session["TableRows"] = Rows;
And later when you want to retreive them :
List<Table> Rows = (List<Table>)Session["TableRows"] // don't forget to cast it
Your objects will exist in Session as long as you don't reach the ASP timeout
Communication between View-controller is done through HTTP Post of the form.
< form class="form-horizontal" method="post" >
or #using (Html.BeginForm())
More info here with example

Different Case of There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key

I will really appreciate some help with the following.
I am trying to populate a Drop Down from a List and keep getting this error. I read and tried all of the suggestions in the similar titled posts and can't get it work.
in the controller I have:
public ActionResult Search(string stringInput)
{
ClassManager manger = new ClassManager();
ViewData["myList"] = manger.GetData(stringInput, SearchBy);//Returns List<string>
return View();
}
In the View I have:
#Html.DropDownList("MyList", (IEnumerable<SelectListItem>)ViewData["myList"], "Select...")
Thank you very much.
You can use SelectList to populate a List<string> object in a DropDownList
#Html.DropDownList("MyList",
new SelectList((IEnumerable)ViewData["myList"]), "Select...")
DropDownList is always looking for a list of the SelectListItem type, not your specific model instances. This seems to trip up almost everyone.
The solution is to translate the list you want to display (IEnumerable<string>) into IEnumerable<SelectListItem>. The easiest approach is something like ViewData["myList"] = new SelectList(manger.GetData(stringInput, SearchBy)) which may or may not work for your example.
I personally use a ViewModel that consists of the view for the model as one property and the SelectList as another. As I post the result, I pull the elements out and into the respective database/repository calls as necessary. It's a bit of abstraction up front but it feels a little cleaner on the view side.

MVC Strongly typed IQueryable<IGrouping<TKey, TElement>> model

I'm trying to create a strongly typed model for one of my Views in MVC. The model is the result of a LINQ GroupBy query so it is the type shown below (grouping employees by first letter of surname).
#model IQueryable<IGrouping<string, Employee>>
I'm unsure why but it doesn't let me have a model of this type. The error message I get is:
An opening "<" is missing the corresponding closing ">". Which is incorrect.
I know I can create a view specific model and populate that instead but I'd like to know why this model doesn't seem to work?
By default, a very limited set of namespaces are available for direct use in razor views. Try to expand it to fully qualified names and see if the problem persists:
#model System.Linq.IQueryable<System.Linq.IGrouping<string, Name.Space.Employee>>
I don't know why you'd be getting this error, since you appear to be using correct Razor code. It's possible that there's actually a bug elsewhere in the page that is being made manifest through this incorrect error message.
A workaround, which may help you determine the real source of the bug, would be to create your own strongly-typed model class, which could have this data as its property:
public class EmployeeListViewModel
{
public IQueryable<IGrouping<string, Employee>> EmployeesByCompanyTitle {get;set;}
}
(There are those who would argue that this is a better approach anyway, since you can now add information to your view model more easily.)

UpdateModel is not updating "deep" property

I have an ASP.NET MVC application. At a certain point I get a FormCollection in a Controller method that I want to use to update a model. In the collection not all of the values are properties of that model and the property to be updated is an item from a list, and that list is also an item from another list. Something like this (I hope this is clear):
propertyToUpdate --> model.Items[0].Subitems[0].SomePropertyClass.Value;
I tried this in my Controller:
UpdateModel(model);
The problem is that this is not working and I assume it has something to do with the fact that the reflection is not working. I went searching and stumbled upon this article. So I understand that using the prefix-parameter solves the problem. But not in my case, as the properties lie "deeper" in the model as items from a list.
Does anyone know how I can solve this?
Update:
Here's the EditorTemplate for the property:
#model Q95.Domain.Property
<li>
#Html.DisplayFor(p => p.Description) :
#Html.DisplayFor(p => p.Quantity.Value)
#Html.DisplayFor(p => p.Quantity.Unit.Description)
<br />
#Html.TextBoxFor(p => p.Quantity.Value)
</li>
This template is called like this:
<ul>
#Html.EditorFor(model => model.SegmentRequirement.MaterialRequirements[j].Properties)
</ul>
Is this enough code or is there something still missing?
Update2:
Ok, in all the sub-properties I defined parameterless constructors and now I call:
UpdateModel(segmentRequirement, "SegmentRequirement", form.ToValueProvider());
This updates the model, but everything from MaterialRequirements is re-instantiated... :S
UpdateModel works fine on "Deep properties".
The problem is probably the data in the collection you get isn't equal to the properties names.
Check 3 places to see the values you get from the page
The form values.
The route data
The query string
In exact that order.
The keys should match you model properties names.
Update:
How to match the keys to properties names?
The input id will be the key you will get, change the the ids to match your properties names, or even better, use the HtmlTextBoxFor helper: see this article:
Maybe you should create flattened ViewModel and then use that to populate the view, and later synchronize it with the real model.
Can you show us your model and your view, if you are not using htmlhelper, you then have to understand the naming convention very well in order to make the model binding work with your model. so the first thing in first is to show us your model and view.

Categories

Resources