I am new to asp.net mvc4 and there is something i don't understand well.
Why do I have to declare the Model using #model at top of the view, if I already pass an object to the View in the controller.
Taking an example :
Controller:
public ActionResult countryDetails(int id)
{
Country country = db.Country.Find(id);
return View(country);
}
View:
#model MvcApplication2.Models.Country
#{
ViewBag.Title = "countryDetails";
}
...
The controller returns a View with an object as parameter, so the model should be already known. I'm sorry if it is obvious, but I can't figure out why this is not a "double" declaration.
Thanks for you help !
The declaration at the top will do two things for you:
It will allow intellisence to know what type you are using when you type in #Model or use any of the Html helper extensions.
It will also check at runtime that model passed in can be cast to the type the view expects.
Its not necessarily a "double declaration" as it is analogous to specifying a type to a parameter on a method. Like so
Person Someone = new Person();
RenderView(Someone);
...
void RenderView(Person model) { }
By default your view inherits from System.Web.Mvc.WebViewPage<TModel>
You can optionally override this class, it's default ASP.NET inheritance mechanism:
#inherits System.Web.Mvc.WebViewPage<List<CompanyName.MyProduct.MyCategory>>
Or you can just simplify this since MVC3 like this:
#model List<CompanyName.MyProduct.MyCategory>
This sugar syntax was made to simplify code typing.
This declaration give you some things
View automatically cast object to the preferred type
You receive type-defined 'model' property which allows you to access
to your object methods and properties
Just believe that this is a method which accepts object and cast it to the specified type that you provide
The main reason is type-safety, it allows you to work with strongly typed views with the benefit of intellisense, compiler error hints, invalid casting etc.
Also, another reason is for readability - it acts as a reminder to what sort of model it is you are actually dealing with instead of having to keep referring back to the controller.
Related
I started learning ASP.NET MVC and I have got some doubt. How do I check if a class is a Model class in MVC. I have PHP Codeigniter background, where all models inherit CI_Model. It was easy to figure out whether a class is a model class or not by checking instanceof operator but in .NET MVC Model class do not extend any class.
So how do I figure out whether a class is a model class through C# Code? How does MVC framework figure out whether the class is model or not. I have renamed folder from "Models" to "Modelss" but still model binding works with ModelState.IsValid. Any help is greatly appreciated.
Most models in an MVC application are plain old CLR objects (POCOs), that often don't have a base class because it isn't needed. You can change that, if you need to.
In the following examples, lets assume you have a object called param coming in from somewhere.
In C#, you can check if an object is of a certain type in a few ways. You can cast the object to the type, and if you don’t get an exception, the cast was successful. This is not the preferred method any longer, but I wanted you to know if was an option.
try {
var myType = (MyModel)param; // cast happens here
// do something with myType
}
catch{
// cast failed
}
Another way is to use the as operator. This is a much better way to do this because no exception is thrown if the cast fails, you just get null in the variable.
var myType = param as MyModel;
if (myType != null) { // you have what you need.
...
}
Another technique is the is operator (another good way). This works similar to as, but returns a Boolean rather than the object, or null, and you can inline it in an if statement to do the cast, and assign to a variable all in one line of code.
if (param is MyModel myType){
// do something with myType
}
If you do add a base class to your models, you can use that type rather than the class name in the examples above. If you want, you can forego the base class and use a marker interface (an interface with no properties, or functions declared in it), and check for that type.
public interface IModel {}
public class MyModel : IModel {
...
}
if (param is IModel myType){
// do something with myType
}
BTW, changing the folder name in the project didn't make any difference because C# works based on namespaces, and not folder structure, for most application types. As long as the folder and class files are included in the project, and the namespace is referenced, all is good.
Hope you find this information useful!
So somebody asked me the question:
When would I return View() and when would I return PartialView()?
My immdiate reaction was, if it's a patial use PartialView(). Then I realised that I have quite often returned View() for a partial view with no, apparent, detremental effects?! So what's the point in the return PartialView() call?
I found this question What's the difference between “return View()” and “return PartialView()”. This appears to be particular to MVC2. i.e. talks about .aspx and .ascx control extensions. Using Razor all our views are .cshtml whether they are partial or not.
Which got my thinking is the PartialView() just a hangover from MVC2 and not really relevant in MVC3+ (When using Razor anyway)? Or am I missing some crucial feature of PartialView()?
tl;dr: PartialView() does not use a layout for the view being returned.
You can set a default layout file within _ViewStart.cshtml (located in the Views folder) which will then be used by all views. By doing that, you avoid having to set the Layout property within each view. PartialView() will not include that layout file or any other.
If you want to return a partial view, e.g. in a child action called using #Html.Action(action, controller), use PartialView. If you want to return a "full" view including the layout, use View().
MSDN Reference:
If you contrast the MSDN definition for ViewResult() Object with the MSDN definition for PartialViewResult() Object
you find the only difference is that ViewResult has an extra property:
public string MasterName { get; set; }
Otherwise, both Objects inherit from ViewResultBase and seem to inherit all other properties and methods from the base class.
Unfortunately, the implementation of the abstract method ExecuteResult() is not published, but I have no doubt it uses the MasterName field to find and render the Master Layer.
Our shared experience:
Just like you, I have returned partial views =using View(). I don't recommend it. But the apparent difference isn't big.
It does seem a touch wasteful to have an extra object just for MasterName, but the more important difference is probably the implementation of ExecuteResult().
When you choose View() method and create a ViewResult Object rather than using PartialView() to create a PartialViewResult Object, you are being less efficient; your application is doing the extra work of checking if your MasterName field is assigned.
I'd like to be able to pass a string into my partial view from the calling View - this string will be different depending on the view from which the partial view is rendered. Something like this:
#{ Html.RenderPartial("PartialViews/_BreadcrumbsPartial", "New Item");}
Or
#{ Html.RenderPartial("PartialViews/_BreadcrumbsPartial", Model.Name);}
How can I access this second parameter from within the partial view, since I haven't labeled that parameter? I'd like to avoid passing the whole model in if possible, and just reference that string directly.
Your Partial Must bind to a string
example, at top place this:
#model string
To access the value in your partial, use #Model in place of string param
You could use TempData (or possibly ViewData) which should be accessible in subsequent views. However, I believe you can also pass variables directly, maybe via query string.
Please see this question as well asp.net mvc parameter from page to a partial view
Using ASP.NET MVC 3 I would like to render different "templates" (i.e. partial views or whatever you want to call them) to my views based upon the type of the view model (or a property on the view model) supplied at runtime.
I understand the out-of-the-box ASP.NET MVC functionality enables the addition of a UIHint attribute to a property or field on the viewmodel supplied to the view, but as far as I can tell this doesn't meet my needs as I won't know the template required until runtime.
AFAICT ASP.NET doesn't support generic viewmodels of type T either, so my idea is to take the ASP.NET MVC3 source code and write my own DisplayFor method that accepts a viewmodel instance (specified by it's abstract base type in the view), which resolves the actual type at runtime and uses this to find the template name by convention.
Does this sound feasible/worthwhile?
The view would look thus (note specification of base type, a concrete instance would be supplied at runtime):
#model MyViewModelBase
#{ DisplayFor(Model); }
Viewmodel:
public class MyMagicalViewModel : MyViewModelBase {}
Invocation of this view would look thus:
...
return View("MyView", MyMagicalViewModel);
...
...and this would return html corresponding to the MyMagicalViewModelPartialView.cshtml
Have you looked into Html.EditorFor?
Im starting with MVC2 and i have a simple question:
If i have a typed view with a form inside, and this textbox created with lambda expressions:
<%: Html.TextBoxFor(e => e.Name)%>
When i submit this form the default model binder take the request form, takes the model typed to the view, serialize the data posted (as a this model) and pass it to an action of my controller.
To try to explain myself better, lets imagine that i have a url like localhost/edittestmodel/ID/1 and i have in my controller action the following code:
public ActionResult Edit(int id)
{
TestModel testmodel=new TestModel();
testmodel.Name="texttorenderintotextbox";
//whats the class that place the testmodel properties into the view?
return View(testmodel);
}
What's the responsable class for place the Name property of my testmodel object into the textbox
<%: Html.TextBoxFor(e => e.Name)%>
Thanks in advance.
Best Regards.
Jose.
It's the TextBoxFor helper method that's responsible for generating the input field from the lambda expression.
View's don't have anything to do in POST request and model binding
When you have strong type views, model type is barely used to have the simplicity of code intellisense in view's code (so you can use lambda expressions like in your example).
But when you POST data back, nothing gets checked against the view. It gets checked against controller action parameters though. And if there's a parameter with a certain custom model binder type, that particular model binder is used to process incoming data.
But to answer your question: TextBoxFor checks your strong type view's model and generates particular textbox with correct name attribute. So data from it will be posted back under the correct form field name.
To go even deeper. It's the view engine that parses view's ASPX code and runs all server side scripts including Html.TextBoxFor() call.