# Views

## Layouts

Most web apps have a common layout that provides the user with a consistent experience as they navigate from page to page. The layout typically includes common user interface elements such as the app header, navigation or menu elements, and footer.

{% embed url="<https://learn.microsoft.com/en-us/aspnet/core/mvc/views/layout/_static/page-layout.png?view=aspnetcore-7.0>" %}

Common HTML structures such as scripts and stylesheets are also frequently used by many pages within an app. All of these shared elements may be defined in a `_Layout.cshtml` file, which can then be referenced by any view used within the app. Layouts reduce duplicate code in views.

## Partial View&#x20;

A partial view is a **Razor** markup file (`.cshtml`) without an `@page` directive that renders HTML output *within* another markup file's rendered output.

Partial views are an effective way to:

* Break up large markup files into smaller components.

  In a large, complex markup file composed of several logical pieces, there's an advantage to working with each piece isolated into a partial view. The code in the markup file is manageable because the markup only contains the overall page structure and references to partial views.
* Reduce the duplication of common markup content across markup files.

  When the same markup elements are used across markup files, a partial view removes the duplication of markup content into one partial view file. When the markup is changed in the partial view, it updates the rendered output of the markup files that use the partial view.

#### Use a partial view in a markup file <a href="#use-a-partial-view-in-a-markup-file" id="use-a-partial-view-in-a-markup-file"></a>

* #### Partial Tag Helper <a href="#partial-tag-helper" id="partial-tag-helper"></a>

```cshtml
<partial name="~/Views/Folder/_PartialName.cshtml" />    // app-root
<partial name="/Views/Folder/_PartialName.cshtml" />    // app-root
<partial name="../Account/_PartialName.cshtml" />        // relative path
```

* #### Asynchronous HTML Helper <a href="#asynchronous-html-helper" id="asynchronous-html-helper"></a>

```cshtml
@await Html.PartialAsync("~/Views/Folder/_PartialName.cshtml")
@await Html.PartialAsync("/Views/Folder/_PartialName.cshtml")
@{
    await Html.RenderPartialAsync("_AuthorPartial");
}
```

{% hint style="info" %}
Partial views shouldn't be used to maintain common layout elements. Common layout elements should be specified in `_Layout.cshtml` files.

Don't use a partial view where complex rendering logic or code execution is required to render the markup. Instead of a partial view, use a view component.
{% endhint %}

## pass data to views

* strongly typed data - ViewModel
* weekly typed data - `ViewData` (`ViewDataAttribute`), `ViewBag`

### strongly typed data

* pass an instance of the viewmodel type to the view from the action which allows the view to take advantage of *strong* type checking.

{% tabs %}
{% tab title="Controller" %}

```csharp
public IActionResult Contact()
{
    ViewData["Message"] = "Your contact page.";

    var viewModel = new Address()
    {
        Name = "Microsoft",
        Street = "One Microsoft Way",
        City = "Redmond",
        State = "WA",
        PostalCode = "98052-6399"
    };

    return View(viewModel);
}
```

{% endtab %}

{% tab title="View" %}

```cshtml
@model WebApplication1.ViewModels.Address

<h2>Contact</h2>
<address>
    @Model.Street<br>
    @Model.City, @Model.State @Model.PostalCode<br>
    <abbr title="Phone">P:</abbr> 425.555.0100
</address>
```

{% endtab %}

{% tab title="ViewModel" %}

```csharp
namespace WebApplication1.ViewModels
{
    public class Address
    {
        public string Name { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string PostalCode { get; set; }
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Usually, ViewModels are Plain Old CLR Object (POCO) classes with little or no behavior (methods) defined.
{% endhint %}

### weekly typed data

#### `ViewData`

* `ViewData` is a `ViewDataDictionary` object accessed through `string` keys.&#x20;
* You can use `ViewData` to pass data from controllers to **views** and **within views**, including **partial views** and **layouts**.

{% tabs %}
{% tab title="Controller" %}

```csharp
public IActionResult SomeAction()
{
    ViewData["Greeting"] = "Hello";
    ViewData["Address"]  = new Address()
    {
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    };

    return View();
}
```

{% endtab %}

{% tab title="View" %}

```cshtml
@{
    // Since Address isn't a string, it requires a cast.
    var address = ViewData["Address"] as Address;
}

@ViewData["Greeting"] World!

<address>
    @address.Name<br>
    @address.Street<br>
    @address.City, @address.State @address.PostalCode
</address>
```

{% endtab %}
{% endtabs %}

#### `[ViewData]` attribute

* Another approach that uses the `ViewDataDictionary` is `ViewDataAttribute`.&#x20;
* Properties on controllers or Razor Page models marked with the `[ViewData]` attribute have their values stored and loaded from the dictionary.

{% tabs %}
{% tab title="Controller" %}

```csharp
public class HomeController : Controller
{
    [ViewData]
    public string Title { get; set; }

    public IActionResult About()
    {
        Title = "About Us";
        ViewData["Message"] = "Your application description page.";

        return View();
    }
}
```

{% endtab %}

{% tab title="View" %}

```cshtml
<!DOCTYPE html>
<html lang="en">
<head>
    <title>@ViewData["Title"] - WebApplication</title>
    ...
```

{% endtab %}
{% endtabs %}

#### `ViewBag`

* The `ViewBag` property is a wrapper around `ViewData` that provides dynamic properties for the underlying `ViewData` collection using dot notation.
* `ViewBag` can be more convenient to work with, since it doesn't require casting.
* Simpler to check for null values. Example: `@ViewBag.Person?.Name`

{% tabs %}
{% tab title="Controller" %}

```csharp
public IActionResult SomeAction()
{
    ViewBag.Greeting = "Hello";
    ViewBag.Address  = new Address()
    {
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    };

    return View();
}
```

{% endtab %}

{% tab title="Views" %}

```cshtml
@ViewBag.Greeting World!

<address>
    @ViewBag.Address.Name<br>
    @ViewBag.Address.Street<br>
    @ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode
</address>
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
*Strong typing* (or *strongly typed*) means that every variable and constant has an explicitly defined type (for example, `string`, `int`, or `DateTime`).&#x20;

Unlike strong types, *weak types* (or *loose types*) means that you don't explicitly declare the type of data you're using.
{% endhint %}
