Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions src/Components/Endpoints/src/FormMapping/PrefixResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,38 @@ public int Compare(FormKey x, FormKey y)
{
separatorX = x.Value.Span[currentXPos..].IndexOfAny('.', '[');
separatorY = y.Value.Span[currentYPos..].IndexOfAny('.', '[');
int compare;

if (separatorX == -1 && separatorY == -1)
{
// no more segments, compare the remaining substrings
// Both x and y have no more segments, compare the remaining segments
return MemoryExtensions.CompareTo(x.Value.Span[currentXPos..], y.Value.Span[currentYPos..], StringComparison.Ordinal);
}
else if (separatorX == -1)
{
// x has no more segments, but y does, so x is less than y
return -1;
// x has no more segments, y has remaining segments
compare = MemoryExtensions.CompareTo(x.Value.Span[currentXPos..], y.Value.Span[currentYPos..][..separatorY], StringComparison.Ordinal);
if (compare == 0 && !checkPrefix)
{
return -1;
}
return compare;
}
else if (separatorY == -1)
{
if (!checkPrefix)
// y has no more segments, x has remaining segments
compare = MemoryExtensions.CompareTo(x.Value.Span[currentXPos..][..separatorX], y.Value.Span[currentYPos..], StringComparison.Ordinal);
if (compare == 0 && !checkPrefix)
{
// We are just sorting, so x is greater than y because it has more segments.
return 1;
}

var match = MemoryExtensions.CompareTo(
x.Value.Span[currentXPos..][..separatorX],
y.Value.Span[currentYPos..], StringComparison.Ordinal);

return match;
return compare;
}

// both have segments, compare the segments
var segmentX = x.Value.Span[currentXPos..][..separatorX];
var segmentY = y.Value.Span[currentYPos..][..separatorY];
var compareResult = MemoryExtensions.CompareTo(segmentX, segmentY, StringComparison.Ordinal);
if (compareResult != 0)
compare = MemoryExtensions.CompareTo(x.Value.Span[currentXPos..][..separatorX], y.Value.Span[currentYPos..][..separatorY], StringComparison.Ordinal);
if (compare != 0)
{
return compareResult;
return compare;
}

currentXPos += separatorX + 1;
Expand Down
34 changes: 34 additions & 0 deletions src/Components/Endpoints/test/Binding/PrefixResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,40 @@ public void ContainsPrefix_HasEntries_NoMatch(string prefix)
Assert.False(result);
}

[Theory]
[InlineData("Model")]
[InlineData("Model.Model")]
[InlineData("Model[0].Model")]
public void ContainsPrefix_HasEntries(string prefix)
{
// Arrange - Simulating the exact scenario from debugging
var keys = new string[] { "__RequestVerificationToken", "_handler", "Model.Name", "Model.Model.Name", "Model[0].Model.Name", "Model[0].Name" };
var container = new PrefixResolver(GetKeys(keys), keys.Length);

// Act
var result = container.HasPrefix(prefix.AsMemory());

// Assert
Assert.True(result);
}

[Theory]
[InlineData("Model")]
[InlineData("Model.Model")]
[InlineData("Model[0].Model")]
public void ContainsPrefix_DoesNotHaveEntries(string prefix)
{
// Arrange - Simulating the exact scenario from debugging
var keys = new string[] { "__RequestVerificationToken", "_handler" };
var container = new PrefixResolver(GetKeys(keys), keys.Length);

// Act
var result = container.HasPrefix(prefix.AsMemory());

// Assert
Assert.False(result);
}

[Theory]
[InlineData("a")]
[InlineData("b")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,16 @@ void AssertUiState(string expectedStringValue, bool expectedBoolValue)
}
}

[Fact]
public void EditFormRecursiveBinding()
{
GoTo("forms/recursive-edit-form");
Browser.Equal("", () => Browser.Exists(By.Id("result-form")).Text);
Browser.Exists(By.Id("text-input")).SendKeys("John");
Browser.Exists(By.Id("submit-button")).Click();
Browser.Equal("John", () => Browser.Exists(By.Id("result-form")).Text);
}

[Fact]
public void RadioButtonGetsResetAfterSubmittingEnhancedForm()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@page "/forms/recursive-edit-form"
@using Microsoft.AspNetCore.Components.Forms

<PageTitle>Home</PageTitle>

<EditForm EditContext="FormContext" OnSubmit="Submit" FormName="RequestForm">
<InputText id="text-input" @bind-Value="Model!.Name" />
<button type="submit" id="submit-button">Submit</button>
</EditForm>

<p id="result-form">@ModelName</p>

@code {
string ModelName;

[SupplyParameterFromForm(FormName = "RequestForm")]
private MyModel? Model { get; set; }

private EditContext FormContext = null!;

public class MyModel
{
public string? Name { get; set; }

public MyModel? Parent { get; set; }
}

protected override void OnInitialized()
{
if (Model == null)
{
Model = new();
}

FormContext = new EditContext(Model);
}

private void Submit()
{
ModelName = Model?.Name ?? string.Empty;
}
}
Loading