I have started to use MVC and i have set up a simple project that has a controller than returns a value from entity FrameWork. I have a controller for the index page which visual studio setup as default in its template.
I am hoping that this value will be returned to the index page of the website.
Controller code
MISEntities db = new MISEntities();
public ActionResult Index()
{
ViewBag.Message = "Real Time Production";
var scrap = from r in db.tbl_dppIT
select r.CastGood;
return View(scrap);
}
How do i access the var scrap using razor?
I have looked at the viewbag method and other razor syntax but cant seem to find how i access this item.
Just because the controller variable is declared using the var keyword doesn't mean it doesn't have a type. Rather, this tells C# that the type should be inferred by its context (in this case, an IEnumerable<T> of whatever type tbl_dppIT.CastGood is).
So, the other three answers are partly correct, you need to define the type of model being passed into the View via the razor keyword #model as noted by the other answers:
// In your view Razor:
#model IEnumerable</* type of CastGood */>
There is an alternative to the three answers already specified, and that is sticking the scrap variable into the ViewBag in your controller:
ViewBag.Scrap = scrap;
When you access the expando property Scrap from the ViewBag in the view, it will be a dynamic object, so you won't get the aid of IntelliSense. But, it is another way, just so that you know all the possibilities.
UPDATE:
Based on your comments below, it looks like if CastGood is a database column that is allowed to be null and whose type is int, then you'd want:
#model IEnumerable<int?>
HTH.
You need to declare the type of the variable scrap as the model inside the View using the #model keyword.
// View.cshtml
#model IEnumerable<Namespace.ScrapType>
#foreach(var item in Model) {
<p>#item.SomeProperty</p>
}
See Part 3: Views and ViewModels of the MVC Music Store example.
You need to strongly type your view and it will available as the Model instance.
#model IEumerable<MyType>
#foreach(var item in Model)
{
#*do something with it *#
}
Related
Im trying to pass a string from a Controller to a view and Im not quite sure what Im missing. I cannot make the action method in the controller static because the View then errors with
an object reference is required for the non-static field.
How do I fix this? I would appreciate a detailed explanation, or links to your sources so I can learn.
My controller (LC) has:
...
public ActionResult Action()
{
LC vm = new LC();
vm.LicenseTable = DataPull(); //setting a variable in the controller
return View("LicenseView", vm); //return a view named 'LicenseView'
}
...
my lcview.cshtml:
#using iw.Models //yes I screwed up and put a controller in the models folder
#model LC
<body>
//<p>#LC.LicenseView</p> //calling the Model the the View name FAILS
<p>#LC.Action()</p> //Fails because of error below
</body>
Error:
An object reference is required for the non-static method LC.Action()
As mentioned in my comment, in your cshtml, use
<p>#Model.Action()</p>
The "#model LC" declares the object type used as the model, but when you need to access the actual object you use the "model" keyword instead.
EDIT
Are you trying to display the LC.LicenseTable string in the HTML?
Use the following:
<p>#Model.LicenseTable</p>
It looks like you are trying to call the action method named Action of your controller name LC.
You need to use Html.Action as it looks like you want to call the action and render view in the p element:
<p>#Html.Action("Action","LC")</p>
We specify the controller name and action name in this method and it will return the view which will be rendered as html.
I'm sending the following model to my view.
return View(new { url = returnUrl });
In the view, I'm don't want to specify any particular class for my object (since I wish to keep it flexible and elastic for now). So, the #Model is the apparently an object and as such, it's got no url property. Hence the error.
Additional information: 'object' does not contain a definition for 'url'
Now, I do know that the thing inside the object has url property. I have assigned it to it and I also see it when watching the variable as the exception's been thrown.
My question is how to access the field. Is my only option declaring a class and type the model using #model Something? I can't use as keyword to type it to var...
In "plain" C# we can do something like this.
var some = new {thing = "poof"};
string output = some.thing;
How do I do the equivalent of it in CSHTML file under Razor?
Strongly-typed view models are the way to go. Create a type that suits the needs of the view and treat reusability/duplication as a secondary concern.
However, let me explain why your attempt did not work.
It is legal to pass an anonymous type--even between assemblies[1]--as long as it is cast to object. In fact, the MVC framework assemblies consume anonymous types in many helper methods. Those anonymous types are then evaluated using reflection (optimized by caching).
1: I believe there are some caveats to this, and it certainly isn't good practice in most cases.
A view is compiled into a class so that it can be executed. Part of the class's contract is the type of model it expects, as indicated by #model in your view markup.
This presents a problem with anonymous types, as you cannot indicate their type in your view and type object doesn't expose the properties you set when declaring the type. Thus, you end up with a view that only knows that its model is an object.
Again, use strongly-typed models, or the ViewBag if you truly only need one or two values.
However, to prove that the anonymous type can be passed to the view, look at this (horrible) example:
Controller
return View( new { property1 = "hello world"} );
View
#model object
#{
var rvd = new RouteValueDictionary( Model );
}
#rvd["property1"]
We passed an anonymous type to the view as an object, and then read the object's properties using RouteValueDictionary.
You can use ViewData and ViewBag to send objects to the view page, in your case you can write in the controller something like this:
ViewData["url"] = url ; //Or whatever
return View();
Now in the view you can simply use your object example:<div>#ViewData["url"]</div>
But mainly in MVC it is more recommended to use strongly typed View Models
You may want to look into using the dynamic type in C#. See https://msdn.microsoft.com/en-us/library/dd264736.aspx for details.
While the standard would be to use a strongly-typed view model, there are some scenarios where you might want to use dynamic as your model type (or as a property of your strongly-typed view model), such as in a CMS where the properties are built dynamically by the CMS Provider.
Example view:
#model dynamic
<p>
Url: #Model.url
</p>
I'm trying to develop an mvc page that upfront we don't know what model to use until certain conditions are met. When we have the model needed, the view has to resemble that information.
Since we are using MVC 4 and using models with lambda notation we can't render every property from the model because all of them have different properties with different variable types and we need to use only one view and one controller to accomplish this.
I implemented dynamic classes but got stuck when trying to render the view since I don't know what properties will there be nor the names they have.
Any pointers how to get this done or tutorials out there that explain this situation.
I don't know if this answers your question, but you can specify both what model you want to send, and what view you want to send it to, without really doing anything too fancy:
public ActionResult Index(int id)
{
var model1 = new Model1();
var model2 = new Model2();
if (id == 1)
{
return View("ViewForModel1", model1);
}
if (id == 2)
{
return View("ViewForModel2", model2);
}
// if it gets this far, return index
return View();
}
MSDN: http://msdn.microsoft.com/en-us/library/dd460310(v=vs.118).aspx
This is messy. But if your view takes a dynamic model you could do something like this in your view:
#model dynamic
#if(Model is Model1)
{
...
return;
}
#if(Model is Model2)
{
...
return;
}
In general if you want something dynamic it might be best to do things in a weakly typed fashion. You might want to avoid using the lambda helpers and instead use the weakly typed html helper counter parts. You can get the property names using reflection or the model meta data engine. You might also want to take a look at Dynamic MVC.
http://dynamicmvc.com
I have a submenu I want to display only when certain controllers are used and a certain model is present. I created a partial and tried to render it in the _Layout.cshtml but I get an error stating model item passed is of type ... but this dictionary requires item of type...
I could put the menu in each of my views for the controllers with the right type of model being passed but that seems like the less flexible way.
Currently I am checking if my model is null in the _submenu partial
#if(Model != null)
However, this will let any type of model through and then when it is the wrong type it errors.
I thought the best way would be to specify that my #Html.Partial is only run when certain controllers are used. Or Is there a way to verify the model type so the code doesn't run if the model passed to the view is incorrect?
It sounds like you need your model to be dynamic (Check this website for more information on this), then on your view you can just check the type of the model and act accordingly:
#model dynamic
#{
ViewBag.Title = "IndexNotStonglyTyped";
}
<h2>Index Not Stongly Typed</h2>
<p>
#if(Model is MyType) {
<span>got myType!</span>
}
</p>
Note: Original example taken from the website mentioned above.
I'm learning MVC and I'm trying to create an implicitly typed variable for my model but not sure how to reference it in the view #model IEnumerable<???>
Controller...
public ActionResult Users() {
var model = from MembershipUser u in Membership.GetAllUsers()
select new {user = u, roles = string.Join(", ", Roles.GetRolesForUser(u.UserName))};
View(model);
}
You can't reference an anonymous-typed variable in the view (or anywhere outside its local scope). It's possible to use a dynamic type:
#model IEnumerable<dynamic>
But this way you don't have Intellisense/compile-time type checking; the best approach would be to just create a class for your model.
That's an anonymous type you're returning. I believe you'll want to use an actual type. If you don't have one for what you're selecting in your query, you'll want to create one.
Once you have your type, here's an example of using it in the view.
This is the first line in my view:
#model IEnumerable<AutoTrackerCommon.Entities.TrackerJob>
And I'm using it in a WebGrid:
#{
var grid = new #WebGrid(
source: Model,
rowsPerPage: 10);
}
You reference it as Model, but why would you do such a thing?
Use ViewModels, don't go with untyped or implicitly typed models. Its a nightmare to work with: you lose everything from IDE support to automatic validation. Don't complicate your life unnecessarily. View Models (or strongly typed views) are the way to go.
Good article to read about this: View Models in ASP.NET MVC.
Hope this is of help to you & good luck