-1

I am new to ASP mvc framework and C#. The following code below is auto generated by visual studio. I am very confused with the model object. I think(correct me if i'm wrong) it must be from the control class which implemented the View(object model) method. Does the '@model IEnumerable' cast the model object as a enumerator? I know some programming languages which does that. Also, when i rename the model to something else, i get an error which states context not found and the aModel => aModal.Name gets an error. Furthermore, the @model IEnumerable<ExploreCalifornia.Models.Tour> does not look like it is sequential (what i mean is that it does not need to be on top). If i remove the @model IEnumerable<ExploreCalifornia.Models.Tour> i get errors for the aModal => modal.Name. However, when i put @model IEnumerable<ExploreCalifornia.Models.Tour> anywhere (even on the last line), the errors are fixed. I don't even understand why must they use the lambda operator. I feel like c# is questioning my very basic logic of programming, (no need of defining objects, not sequential, etc.)

@model IEnumerable<ExploreCalifornia.Models.Tour> @*Renaming or removing this will cause an error*@

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(aModal => aModal.Name)   @*an error is caused when removing the top line code*@
        </th>
        <th>
            @Html.DisplayNameFor(aModal => aModal.Description) @*here too.*@
        </th>
    </tr>
</table>

@*Putting the top line code here fixes the errors for some reason? Shouldnt it be sequential?*@

Lastly, as you can see, the Html.DisplayNameFor(aModal => aModal.Name) has an expression using lambda operator. I don't really get why they do it like that. Why cant they directly use the string found in aModal.Name. If you look at the method signature below, you need at least 2 arguments, but the method implemented has only 1 argument. What is going on here too?

public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression);
public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<IEnumerable<TModel>> html, Expression<Func<TModel, TValue>> expression);
Nkosi
  • 235,767
  • 35
  • 427
  • 472
user859385
  • 607
  • 1
  • 6
  • 23
  • Show the controller action associated with this view – Nkosi Feb 04 '17 at 14:17
  • the `@model` let's the view know what type of model to expect. it allows for strongly typed expressions when composing your view – Nkosi Feb 04 '17 at 14:18
  • You are asking three questions, you might want to open a separate question for each one. If you do so, I can answer it. I was answering all of your three questions here, but unfortunately @CodeCaster marked it as duplicate and I wasn't able to post it, even though the duplicate is just for your first question. – Alisson Reinaldo Silva Feb 04 '17 at 14:59
  • @CodeCaster i dont understand how is this a duplicate? Please read the whole question before u make duplicate. In this question there's question regarding the sequence of the code, and regarding the method arguments – user859385 Feb 04 '17 at 15:00
  • @Alisson i have changed the question please reply thank you – user859385 Feb 04 '17 at 15:05
  • To be honest, the 'duplicate' post does not answer my previous question at all. – user859385 Feb 04 '17 at 15:06
  • I no longer can answer it, because the question is marked as duplicate, so answer's are blocked. You can ask a new question, but I would recommend being more clear, and separating them like: Why can `@model` be put anywhere inside the view and still works? Why do `DisplayNameFor` and other `@Html` methods use expressions? – Alisson Reinaldo Silva Feb 04 '17 at 15:09
  • @Alisson i will do that. Thanks. – user859385 Feb 04 '17 at 15:16
  • @Nkosi Thank you for letting me know that. – user859385 Feb 04 '17 at 15:22
  • @Alisson i hope you still have a reply – user859385 Feb 04 '17 at 15:22
  • 1
    @user859385, in future try not to make your questions too broad. Try to keep your questions more focused and to the point. – Nkosi Feb 04 '17 at 15:25
  • 1
    @CodeCaster you are right, but is it ok if I tried to explain in a different way, and also answering about his other questions? See my answer and let me know if it's ok. Thanks! – Alisson Reinaldo Silva Feb 04 '17 at 15:34

2 Answers2

1

1. So what does the @model do?

According to a ScottGu's Blog post, he mentions:

The @model directive provides a cleaner and more concise way to reference strongly-typed models from view files.

About your IEnumerable question, there isn't any convertions. You can either have @model IEnumerable<ExploreCalifornia.Models.Tour> or @model ExploreCalifornia.Models.Tour and they are two different things, as you may expect. The first one is an IEnumerable of your Tour model, which means in your actions you would return something like this:

public ActionResult Index()
{
    List<Tour> myTours = GetTours();
    return View(myTours); // return a List of Tour, for example
}

...but you could return an array, or any other type which implements IEnumerable of Tour.

The second one is a single model Tour, so you would pass a Tour instead of an IEnumerable<Tour>.

So if your @model is a single Tour, the expression parameter of DisplayNameFor would be an Expression<Func<Tour, TValue>> where TValue is the type of the property used in the expression, in your case, I'd guess name is a string.

2. Why can @model be declared in any place of my view?

@model is just a directive to define a type, to let Razor knows the strong type of your model. That line of code doesn't execute anything at all, razor will interpret your file and compile the resulting html. It's like declaring a class, you could have one single file containing multiple classes, and you could do something like this:

public class TopClass
{
    public BottomClass SomeClass { get; set; } // using class declared later...
}

public class BottomClass
{
}

So the order when it comes to just declaring the types doesn't matter at all.

3. Why does Html.DisplayNameFor uses an expression?

In short, because an Expression allows the method to inspect types without needing to have an actual instance. Let's suppose you have a create action like this:

public ActionResult Create()
{
    return View(); // returning no models at all....
}

You could still use @Html in your view to create inputs and labels without even having an instance of your model passed to the view, take note in the example above we didn't pass anything to View().

This works because the @Html methods use Expressions, which allows them to scan the expression tree, detect DataAnnotations of your properties to build properly inputs. In case the @model is supplied with an instance, it will use the values of that model, this is what usually occurs with edit actions, where you pass the existing model for the view.

Take a read about expression trees here.

About DisplayNameFor having two parameters and working with you just providing one, it's because it's an extension method, so the first parameter is actually a reference to the instance of the object which is calling that method. In this case, the HtmlHelper<TModel> which is the @Html you are using.

Alisson Reinaldo Silva
  • 10,009
  • 5
  • 65
  • 83
  • Thank you for the comprehensive explanation. The link you gave for the expression trees was of good help too. – user859385 Feb 04 '17 at 15:36
-2

Basically its a structure which stores multiple values like linkedList. Its ancestors of Array, List, ArrayList, Hashtable etc. You can run your linq queries or sending params with this structure.

You can look it up. https://www.dotnetperls.com/ienumerable

Berkin
  • 1,565
  • 5
  • 22
  • 48