Setting up the foundations of the Medium Detail page
Following the same patterns as before, create a new Razor Component page called "MediumDetail", which will then have these new concepts added on to it:
-
On your page-directive, add a route-parameter behind the original page route to "/Media", like the example below. Route Parameters allow information to be passed to a page Razor Component through the browser URL.
- @page “/BrowseByMedium/{MediumId:int}”
- The pattern is, in braces, the Parameter property you want to be populated, with the primitive data type behind it separated by a colon.
- In your Viewmodel class, you'll then want to add a public Int property of MediumId.
-
Above that property, add the [Parameter] attribute from the Microsoft.AspNetCore.Components namespace.
- This will allow your property recieve the value from your Route Parameter, and is also used for non-page components to establish their parameters exposed in their Tag.
- With that, you will also need a public property of your Medium DTO to hold the Medium we will retrieve from the API in the next steps.
- However, the Medium itself does not directly relate to your Artwork - These are insted related through a second table, ArtworkMediumXrefs. Like you had created an IList of Media in the previous page's ViewModel, create one to hold instances of the ArtworkMediumXref DTO.
- Lastly, the intent of this page is to list Artwork from your selected Media - Add an IList of your Artwork DTO to wrap up your Properties.
Advanced use of WebApiDataService
Now, to take your provided Route Parameter from the URL to get a specific list of artwork tied to it, we will need to make multiple calls to our API and use Filters to prune the list sent over the network down to just the bits and pieces we want.
-
Unlike with the previous page, we will be using a different override method called OnParametersSetAsync, called when the Blazor rendering engine populates a Parameter decorated property, such as the MediumId.
- protected async override Task OnParametersSetAsync()
-
Within, create a variable called "mediumResult", and call GetMediumAsync, passing in your MediumId:
- var mediumResult = await WebApiDataServiceAS.GetMediumAsync(MediumId);
- Then, in an if block after that, check your mediumResult object's IsSuccessStatusCode member - If this is True, set Medium to the Data member of the mediumResult object.
- Now, we'll start building out the Filter to retrieve the Medium to Art crossreferences from - Create a new List of IFilterCriterion (MSC.ArtistSite.Shared.Dataservice namespace) called FilterCriteria
-
Within, create a new FilterCriterion, which will ask for three parameters:
- The name of the column you wish to filter against - Which should match between your DTO and Schema: nameof(ArtworkMediumXref.MediumId) - The value that relates a row of the XRef table to a piece of Artwork.
- The Criterion Condition (Enums.CriterionCondition, in the MSC.ArtistSite.Shared.Constants namespace) that you wish to filter using: Enums.CriterionCondition.IsEqualTo
- The value you want to compare-against in your filter: MediumId
- The FilterCriterion should look like this: new FilterCriterion(nameof(ArtworkMediumXref.MediumId), Enums.CriterionCondition.IsEqualTo, MediumId)
- Following the same "Result" pattern as with the Medium before, await a call to WebApiDataServiceAS.GetArtworkMediumXrefsAsync, passing in your list of IFilterCriterion you just created as the parameter.
-
The returned result is slightly more complex than with the Medium before however, being a result of IPageData of a List of ArtworkMediumXref - When setting the ArtworkMediumXrefs, you will need to dig a layer deeper, adding a second .Data on to your accessor
- ArtworkMediumXrefs = result.Data.Data;
-
Once your ArtworkMediumXrefs are populated, we can then use them to build a filter value that we will use to narrow down our search for Artwork:
- Break your Artwork IDs from your ArtworkMediumXrefs into a list - var artworkIds = ArtworkMediumXrefs.Select(x => x.ArtworkId).ToList();
- Using that list, build a string, delimiting your list of Artwork IDs with Vertical Slashes - "|" - string artworkIdQuery = string.Join('|', artworkIds);
-
Like with retrieving the XRefs before, create a list of FilterCriterion that will hold the filter, which will be slightly different this time:
- The field you will want to filter against is nameof(Artwork.ArtworkId) - The integer ID of the artwork from your XRef
- The Criterion Condition this time will be IsContainedIn - This will filter the returned results down to only ones that have a value which is contained inside a vertical-slash delimited list provided.
- Finally, the value of your filter will be the list of vertical-slash delimited ArtworkIds you created in the previous step.
- As before, make a result variable that is set to await your call to the WebApiDataService, which this time will be to the method GetArtworksAsync, passing in your list of filters, and consuming it following the same pattern as before.
- Note that in our example project, the above logic described is broken out into their own async Task methods - For brevity's sake, we have created them in the OnParametersSetAsync directly. You may wish to break these out into encapsulated methods as well in your use-cases.
Building the Medium Detail page markup
Finally, with our data retrieved from the API, we can consume it on our page, as we did with the List of Media before it.
- Below your page and inheritance directives, open with a LoadingMask component, waiting for the Medium to be populated.
- With you Medium populated, make a header that consumes your Medium's name - @Medium.Name, if you called the property Medium.
-
Below that, create a second LoadingMask tag, which will wait for your Artwork property, which you will then iterate through to create a List or suitable Grid equivalent.
Members of Artwork that you might want to make use of in these iterations include:
- IconUri - The URI pointing to the icon-size version of the artwork.
- ImageUri - The URI pointing to the full-size version of the artwork, typically for its own dedicated page.
- Name - The name of the artwork.
- Artist - This will require more advanced setup, pertaining to an optional parameter for a Enums.RelatedEntitiesType enum in your WebApiDataService Get methods, which we will cover in a later section. In the ArtistSite sample project, you can find these examples:
- For using the Enum parameter, Line 44 of ArtworkDetail.razor.cs, or search "P7E1" (without quotes) in the Sample Solution
- For setting up the logic to make use of this parameter, the implementation of ApplyRelatedEntitiesType starting on Line 30 of ASRepositoryCustom.cs in the Repositories folder of the .Repository project, or search "P7E2".
-
Back in the List Mediums page, convert your references to your Medium names and any customizations you made to become Anchors (or other Link components you may have, such as MudBlazor's Link, which is included) linking to your new Medium Detail page, passing in the ID of the medium in place of the Route Parameter.
-
var mediumHref = $"/Media/{medium.MediumId}";
<li><a href="@mediumHref">@medium.Name</a></li>
-
var mediumHref = $"/Media/{medium.MediumId}";