Razor Sub-Components Differences in APIs
2sxc has changed a lot over time. So you'll find old code snippets and new ones, and it helps to see which one is being used. Sometimes you'll also want to convert old code to new code, and this page should help you with that.
This is about how a Razor can call other Razor files, and pass parameters to them.
They may be called Razor Components, Partial Views, Sub-Components, Child Components or Child Razor. In this document we'll just call them Components.
Calling Components
For clean code, you'll often want to call sub-components from your main razor file. Here's a simple example:
@* without parameters *@
@Html.Partial("file.cshtml")
@* with parameters *@
@Html.Partial("file.cshtml", new { Sort = "asc" })
The exact mechanisms and commands can change based on the version of 2sxc you're using.
Without Parameters - all APIs
This is identical for all versions of 2sxc:
Calling Razor - eg. Default.cshtml
:
<h1>some title</h1>
@Html.Partial("Part Footer.cshtml")
Called Razor - eg. Part Footer.cshtml
:
<footer>
<p>some footer</p>
</footer>
With Parameters - Dynamic
This applies to Razor12
, Razor14
.
It uses the DynamicModel
to pass parameters.
All parameters are typed as dynamic
when received, so you can pass anything.
Calling Razor - eg. Default.cshtml
:
@inherits Custom.Hybrid.Razor12
@{
// create a list of dynamic entities
var products = AsDynamic(App.Data["Products"]);
}
<h1>Products</h1>
@foreach (var product in products) {
@Html.Partial("Part Product.cshtml", new { Title = "hello", Product = product })
}
Called Razor - eg. Part Product.cshtml
:
@inherits Custom.Hybrid.Razor12
@{
var title = DynamicModel.Title;
var product = DynamicModel.Product;
}
<h2>@title</h2>
<div class="product">
<strong>@product.Name</strong>
<p>@product.Description</p>
</div>
With Parameters - Typed
This applies to RazorTyped
(v16+) and AppRazor
(v17.03+).
It uses the MyModel
to pass parameters.
All parameters are typed as ITypedModel
when received, so you can pass anything.
Calling Razor - eg. Default.cshtml
:
@inherits Custom.Hybrid.RazorTyped
@{
// Create items list of Products
var products = AsItems(App.Data.GetStream("Products"));
}
<h1>Products</h1>
@foreach (var product in products) {
@Html.Partial("Part Product.cshtml", new { Title = "hello", Product = product })
}
Called Razor - eg. Part Product.cshtml
:
@inherits Custom.Hybrid.RazorTyped
@{
var title = MyModel.String("Title");
var product = MyModel.Item("Product");
}
<h2>@title</h2>
<div class="product">
<strong>@product.String("Name")</strong>
<p>@product.Html("Description")</p>
</div>
With Parameters - Strong Typed
This applies to v17.03+ with RazorTyped<TModel>
and AppRazor<TModel>
.
It uses the Model
to pass parameters.
All parameters are typed as specified in TModel
.
Helper Class - eg. AppCode/Razor/ProductViewModel.cs
:
public class ProductViewModel {
public string Title { get; set; }
public Product Product { get; set; }
}
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Razor
@{
// Create items list of Products
var products = App.Data.GetAll<AppCode.Data.Product>();
}
<h1>Products</h1>
@foreach (var product in products) {
@Html.Partial("Part Product.cshtml", new ProductViewModel { Title = "hello", Product = product })
}
Called Razor - eg. Part Product.cshtml
:
@inherits Custom.Hybrid.RazorTyped<ProductViewModel>
@using AppCode.Razor
<h2>@Model.Title</h2>
<div class="product">
<strong>@MyModel.Product.String("Name")</strong>
<p>@MyModel.Product.Html("Description")</p>
</div>
Calling Components - Side-By-Side Comparison
This is how you call sub-razor files or get helper C# classes:
Dynamic | Typed | Strong Typed |
---|---|---|
@Html.Partial("file.cshtml) |
@Html.Partial("file.cshtml) |
@Html.Partial("file.cshtml) |
@Html.Partial("file.cshtml, new { Sort = "asc" }) |
@Html.Partial("file.cshtml, new { Sort = "asc" }) |
@Html.Partial("file.cshtml, new { Sort = "asc" }) @Html.Partial("file.cshtml, new SomeModel { Sort = "asc" }) |
Receive Model Data from Child Razor - Side-By-Side Comparison
When a razor is called using Html.Partial(..., new { ... })
it passes parameters to the child razor.
These can be picked up in the child as follows:
Dynamic | Typed | Strong Typed |
---|---|---|
DynamicModel ( dynamic ) |
MyModel (ITypedModel) |
MyModel (ITypedModel) Model ( custom type ) |
var name = DynamicModel.Name ( dynamic ) |
var name = MyModel.String("Name") ( string ) |
var name = MyModel.String("Name") ( string ) var name = Model.Name ( string ) |
var birthday = DynamicModel.Birthday ( dynamic ) |
var birthday = MyModel.DateTime("Birthday") ( DateTime ) |
var birthday = MyModel.DateTime("Birthday") ( DateTime ) var birthday = Model.Birthday ( DateTime ) |
MyModel
has many more methods to ensure you can pass type-safe data to the child.
See MyModel
Model
is always typed the way it's specified in the inherits, eg.
@inherits Custom.Hybrid.RazorTyped
will not have aModel
property@inherits Custom.Hybrid.RazorTyped<ProductViewModel>
will haveModel
asProductViewModel
@inherits Custom.Hybrid.RazorTyped<string>
will haveModel
asstring