Skip to main content
Home  › ... Razor

Data List-Details

Tutorial HomeList-Details
#2 Basic List Details using Code - with separate Details-File
The samples can differ based on your Razor base class or if you're running an old version.
Selected: Strong-Typed (2sxc 17.06+) Switch to Typed (2sxc 16+) Switch to Dynamic (Razor14 or below)
Requirements
Resources

Basic List Details using Code - with separate Details-File

Very often you have a list of items, and then a details-page showing just one item. In this example, we'll just use code to do this (so no visual query) - just so you understand the principle. This example splits the list/details templates into 3 files, which is easier to manage. File 1 choses what should happen, file 2 contains the list, and file 3 the details.

@inherits Custom.Hybrid.RazorTyped


@if (MyPage.Parameters.IsEmpty("id")) {
  @Html.Partial("Coded-List.Strong.cshtml")
} else {
  @Html.Partial("Coded-Details.Strong.cshtml", new { Id = MyPage.Parameters.Int("id") })
}

Source Code of Coded-List.Strong.cshtml

@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data
<h3>List of Persons</h3>
<ul>
  @foreach (var person in App.Data.GetAll<Persons>()) {
    <li>
      <a href='@Link.To(parameters: MyPage.Parameters.Set("id", person.Id))'>
        @person.FirstName @person.LastName
      </a>
    </li>
  }
</ul>

Source Code of Coded-Details.Strong.cshtml

@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data
@{
  // the ID is already given by the caller, so we just get that
  var id = MyModel.Int("Id");

  // find the person with this Id using LINQ
  var person = App.Data.GetOne<Persons>(id);
}
@person.Picture("Mugshot", settings: "Square", width: 50, imgClass: "float-left", imgAttributes: new {
  style = "border-radius: 50%"
})
<h3>Details of @person.FirstName @person.LastName</h3>
<a href='@Link.To(parameters: MyPage.Parameters.Remove("id"))'>back to list</a>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

 

#2 Basic List Details using Code - with separate Details-File