8000 Comparing e88f8d63b134...f3555640d3b0 · dotnet/aspnetcore · GitHub
[go: up one dir, main page]

Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dotnet/aspnetcore
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e88f8d63b134
Choose a base ref
...
head repository: dotnet/aspnetcore
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f3555640d3b0
Choose a head ref
  • 4 commits
  • 77 files changed
  • 5 contributors

Commits on Mar 13, 2025

  1. Add onboarding doc for new OSes (#60919)

    * Add onboarding doc for new OSes
    
    * Update docs/OnboardingNewOS.md
    
    Co-authored-by: Rich Lander <rlander@microsoft.com>
    
    ---------
    
    Co-authored-by: Rich Lander <rlander@microsoft.com>
    wtgodbe and richlander authored Mar 13, 2025
    Configuration menu
    Copy the full SHA
    2b7f69b View commit details
    Browse the repository at this point in the history
  2. Fix ASP.NET Core module installer upgrade issues (#60769)

    * Added correct version numbers to ANCM pure forwarders (#60764)
    * Revised component/file relationship (#60764)
    lextm authored Mar 13, 2025
    Configuration menu
    Copy the full SHA
    a848bfa View commit details
    Browse the repository at this point in the history
  3. [Blazor] Support for declaratively persisting component and services …

    …state (#60634)
    
    # Adds a declarative model for persistent component and services state
    
    This PR augments the persistent component state feature with a declarative model that allows the developer to place an attribute on components and services properties to indicate that they should be persisted during prerendering so that it is accessible when the application becomes interactive.
    
    ## Scenarios
    
    ### Serializing state for a component
    
    ```razor
    @page "/counter"
    
    <h1>Counter</h1>
    
    <p>Current count: @CurrentCount</p>
    
    <button class="btn btn-primary" @OnClick="IncrementCount">Click me</button>
    
    @code {
        [SupplyParameterFromPersistentComponentState]
        private int CurrentCount { get; set; }
    
        private void IncrementCount()
        {
            CurrentCount++;
        }
    }
    ```
    * Properties annotated with `[SupplyParameterFromPersistentComponentState]` will be serialized and deserialized during prerendering.
    
    ### Serializing state for multiple components of the same type
    
    **ParentComponent.razor**
    ```razor
    @page "/parent"
    
    @foreach (var element in elements)
    {
        <ChildComponent @key="element.Name" />
    }
    ```
    
    **ChildComponent.razor**
    ```razor
    <div>
        <p>Current count: @Element.CurrentCount</p>
        <button class="btn btn-primary" @OnClick="IncrementCount">Click me</button>
    </div>
    
    @code {
        [SupplyParameterFromPersistentComponentState]
        public State Element { get; set; }
    
        private void IncrementCount()
        {
            Element.CurrentCount++;
        }
    
        protected override void OnInitialized()
        {
            Element ??= new State();
        }
    
        private class State
        {
            public int CurrentCount { get; set; }
        }
    }
    ```
    * Properties annotated with `[SupplyParameterFromPersistentComponentState]` will be serialized and deserialized during prerendering.
    * The `@key` directive is used to ensure that the state is correctly associated with the component instance.
    * The `Element` property is initialized in the `OnInitialized` method to avoid null reference exceptions similarly to how we do it for
      query parameters and form data.
    
    ### Serializing state for a service
    
    **CounterService.cs**
    ```csharp
    public class CounterService
    {
        [SupplyParameterFromPersistentComponentState]
        public int CurrentCount { get; set; }
    
        public void IncrementCount()
        {
            CurrentCount++;
        }
    }
    ```
    
    **Program.cs**
    ```
    builder.Services.AddRazorComponents().RegisterPersistentService<CounterService>(RenderMode.InteractiveAuto);
    ```
    * Properties annotated with `[SupplyParameterFromPersistentComponentState]` will be serialized during prerendering and deserialized when the application becomes interactive.
    * The `AddPersistentService` method is used to register the service for persistence.
    * The render mode is required as can't be inferred from the service type.
      * `RenderMode.Server` - The service will be available for interactive server mode.
      * `RenderMode.Webassembly` - The service will be available for interactive webassembly mode.
      * `RenderMode.InteractiveAuto` - The service will be available for both interactive server and webassembly modes if a component renders in any of those modes.
    * The service will be resolved during interactive mode initialization and the properties annotated with `[SupplyParameterFromPersistentComponentState]` will be deserialized.
    
    ## Implementation details
    
    ### Key Computation
    
    #### For components
    We need to generate a unique key for each property that needs to be persisted. For components, this key is computed based on:
    
    - The parent component type
    - The component type
    - The property name
    - The `@key` directive if present and serializable (e.g., `Guid`, `DateOnly`, `TimeOnly`, and primitive types)
    
    The key computation ensures that even if multiple instances of the same component are present on the page (for example, in a loop),
    each instance's state can be uniquely identified and persisted.
    
    The key computation algorithm only takes into account a small subset of a component hierarchy for performance reasons.
    This limits the ability to persist state on recursive component hierarchies.
    Our recommendation for those scenarios is to persist the state at the top level of the hierarchy.
    
    #### For services
    Only persisting scoped services is supported. We need to generate a unique key for each property that needs to be persisted.
    The key for services is derived from:
    - The type used to register the persistent service
      - Assembly
      - Full type name
      - Property name
    
    Properties to be serialized are identified from the actual service instance.
    - This approach allows marking an abstraction as a persistent service.
    - Enables actual implementations to be internal or different types.
    - Supports shared code in different assemblies.
    - Each instance must expose the same properties.
    
    ### Serialization and Deserialization
    
    By default properties are serialized using the System.Te
    9850
    xt.Json serializer with default settings.
    Note that this method is not trimmer safe and requires the user to ensure that the types used are preserved through some other means. 
    This is consistent with our usage of System.Text.Json across other areas of the product, like root component parameters or JSInterop.
    javiercn authored Mar 13, 2025
    Configuration menu
    Copy the full SHA
    90cc8cd View commit details
    Browse the repository at this point in the history

Commits on Mar 14, 2025

  1. Configuration menu
    Copy the full SHA
    f355564 View commit details
    Browse the repository at this point in the history
Loading
0