[wip] Update Razor SDK and resolve issues

I'm still chasing one more issue.
This commit is contained in:
Ryan Nowak 2019-02-19 18:10:17 -08:00
parent 6d8c8f8c64
commit 616a4a36f5
11 changed files with 760 additions and 135 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by automation to update Versions.props and may be used for other purposes, such as
@ -9,21 +9,21 @@
-->
<Dependencies>
<ProductDependencies>
<Dependency Name="Microsoft.AspNetCore.Razor.Language" Version="3.0.0-preview-19107-04">
<Dependency Name="Microsoft.AspNetCore.Razor.Language" Version="3.0.0-preview3.19119.5">
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
<Sha>408b123a6454841884c1d840fb853eec8de12c10</Sha>
<Sha>182b2c81a5a3c2d5219cf20205e49dbe86823e18</Sha>
</Dependency>
<Dependency Name="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="3.0.0-preview-19107-04">
<Dependency Name="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="3.0.0-preview3.19119.5">
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
<Sha>408b123a6454841884c1d840fb853eec8de12c10</Sha>
<Sha>182b2c81a5a3c2d5219cf20205e49dbe86823e18</Sha>
</Dependency>
<Dependency Name="Microsoft.CodeAnalysis.Razor" Version="3.0.0-preview-19107-04">
<Dependency Name="Microsoft.CodeAnalysis.Razor" Version="3.0.0-preview3.19119.5">
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
<Sha>408b123a6454841884c1d840fb853eec8de12c10</Sha>
<Sha>182b2c81a5a3c2d5219cf20205e49dbe86823e18</Sha>
</Dependency>
<Dependency Name="Microsoft.NET.Sdk.Razor" Version="3.0.0-preview-19107-04">
<Dependency Name="Microsoft.NET.Sdk.Razor" Version="3.0.0-preview3.19119.5">
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
<Sha>408b123a6454841884c1d840fb853eec8de12c10</Sha>
<Sha>182b2c81a5a3c2d5219cf20205e49dbe86823e18</Sha>
</Dependency>
<Dependency Name="dotnet-ef" Version="3.0.0-preview.19080.1">
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>

View File

@ -1,4 +1,4 @@

<!--
This file defines the versions of external dependencies used by ASP.NET Core.
@ -112,10 +112,10 @@
<MicrosoftEntityFrameworkCoreToolsPackageVersion>3.0.0-preview.19080.1</MicrosoftEntityFrameworkCoreToolsPackageVersion>
<MicrosoftEntityFrameworkCorePackageVersion>3.0.0-preview.19080.1</MicrosoftEntityFrameworkCorePackageVersion>
<!-- Packages from aspnet/AspNetCore-Tooling -->
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-preview-19107-04</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-preview-19107-04</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-preview-19107-04</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview-19107-04</MicrosoftNETSdkRazorPackageVersion>
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-preview3.19119.5</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-preview3.19119.5</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-preview3.19119.5</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview3.19119.5</MicrosoftNETSdkRazorPackageVersion>
</PropertyGroup>
<!--

View File

@ -91,7 +91,7 @@ namespace Test
frames,
frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0),
frame => AssertFrame.Attribute(frame, "Value", 42, 1),
frame => AssertFrame.Attribute(frame, "ValueChanged", typeof(Action<UIEventArgs>), 2));
frame => AssertFrame.Attribute(frame, "ValueChanged", typeof(EventCallback<UIChangeEventArgs>), 2));
}
[Fact]
@ -167,7 +167,7 @@ namespace Test
frames,
frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0),
frame => AssertFrame.Attribute(frame, "Value", 42, 1),
frame => AssertFrame.Attribute(frame, "OnChanged", typeof(Action<UIEventArgs>), 2));
frame => AssertFrame.Attribute(frame, "OnChanged", typeof(EventCallback<UIChangeEventArgs>), 2));
}
[Fact]
@ -201,7 +201,7 @@ namespace Test
frames,
frame => AssertFrame.Element(frame, "div", 3, 0),
frame => AssertFrame.Attribute(frame, "myvalue", "hi", 1),
frame => AssertFrame.Attribute(frame, "myevent", typeof(Action<UIEventArgs>), 2));
frame => AssertFrame.Attribute(frame, "myevent", typeof(EventCallback), 2));
}
[Fact]
@ -235,7 +235,7 @@ namespace Test
frames,
frame => AssertFrame.Element(frame, "div", 3, 0),
frame => AssertFrame.Attribute(frame, "myvalue", "hi", 1),
frame => AssertFrame.Attribute(frame, "myevent", typeof(Action<UIEventArgs>), 2));
frame => AssertFrame.Attribute(frame, "myevent", typeof(EventCallback), 2));
}
[Fact]
@ -292,7 +292,7 @@ namespace Test
frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
frame => AssertFrame.Attribute(frame, "value", "42", 1),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 2));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 2));
}
[Fact]
@ -315,7 +315,7 @@ namespace Test
frame => AssertFrame.Element(frame, "input", 4, 0),
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd/yyyy"), 2),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 3));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3));
}
[Fact]
@ -340,7 +340,7 @@ namespace Test
frame => AssertFrame.Element(frame, "input", 4, 0),
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd/yyyy"), 2),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 3));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3));
}
[Fact]
@ -363,7 +363,7 @@ namespace Test
frame => AssertFrame.Element(frame, "input", 4, 0),
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "value", "42", 2),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 3));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3));
}
[Fact]
@ -385,7 +385,7 @@ namespace Test
frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
frame => AssertFrame.Attribute(frame, "type", "checkbox", 1),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 3));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3));
}
[Fact]
@ -408,7 +408,7 @@ namespace Test
frame => AssertFrame.Element(frame, "input", 4, 0),
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "value", "42", 2),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 3));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3));
}
[Fact]
@ -431,7 +431,7 @@ namespace Test
frame => AssertFrame.Element(frame, "input", 4, 0),
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd"), 2),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 3));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3));
}
[Fact] // Additional coverage of OrphanTagHelperLoweringPass
@ -455,7 +455,7 @@ namespace Test
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "visible", 2),
frame => AssertFrame.Attribute(frame, "value", "42", 3),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 4));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 4));
}
[Fact] // See https://github.com/aspnet/Blazor/issues/703
@ -482,7 +482,7 @@ namespace Test
frame => AssertFrame.Attribute(frame, "type", "text", 1),
frame => AssertFrame.Attribute(frame, "visible", 2),
frame => AssertFrame.Attribute(frame, "value", "42", 3),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 4));
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 4));
}
[Fact] // Additional coverage of OrphanTagHelperLoweringPass
@ -506,7 +506,7 @@ namespace Test
frames,
frame => AssertFrame.Element(frame, "div", 7, 0),
frame => AssertFrame.Attribute(frame, "value", "42", 1),
frame => AssertFrame.Attribute(frame, "onchange", typeof(Action<UIEventArgs>), 2),
frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 2),
frame => AssertFrame.Whitespace(frame, 3),
frame => AssertFrame.Element(frame, "span", 2, 4),
frame => AssertFrame.Text(frame, "42", 5),

View File

@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var renderer = new TestRenderer();
// Assert
Action<UIEventArgs> setter = null;
EventCallback setter = default;
var frames = GetRenderTree(renderer, component);
Assert.Collection(frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
@ -373,11 +373,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame =>
{
AssertFrame.Attribute(frame, "onchange", 2);
setter = Assert.IsType<Action<UIEventArgs>>(frame.AttributeValue);
setter = Assert.IsType<EventCallback>(frame.AttributeValue);
});
// Trigger the change event to show it updates the property
await renderer.Invoke(() => setter(new UIChangeEventArgs { Value = "Modified value", }));
//
// This should always complete synchronously.
var task = renderer.InvokeAsync(() => setter.InvokeAsync(new UIChangeEventArgs { Value = "Modified value", }));
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
await task;
Assert.Equal("Modified value", myValueProperty.GetValue(component));
}
@ -395,7 +400,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var renderer = new TestRenderer();
// Assert
Action<UIEventArgs> setter = null;
EventCallback setter = default;
var frames = GetRenderTree(renderer, component);
Assert.Collection(frames,
frame => AssertFrame.Element(frame, "textarea", 3, 0),
@ -403,11 +408,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame =>
{
AssertFrame.Attribute(frame, "onchange", 2);
setter = Assert.IsType<Action<UIEventArgs>>(frame.AttributeValue);
setter = Assert.IsType<EventCallback>(frame.AttributeValue);
});
// Trigger the change event to show it updates the property
await renderer.Invoke(() => setter(new UIChangeEventArgs() { Value = "Modified value", }));
//
// This should always complete synchronously.
var task = renderer.InvokeAsync(() => setter.InvokeAsync(new UIChangeEventArgs { Value = "Modified value", }));
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
await task;
Assert.Equal("Modified value", myValueProperty.GetValue(component));
}
@ -425,7 +435,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var renderer = new TestRenderer();
// Assert
Action<UIEventArgs> setter = null;
EventCallback setter = default;
var frames = GetRenderTree(renderer, component);
Assert.Collection(frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
@ -433,12 +443,18 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame =>
{
AssertFrame.Attribute(frame, "onchange", 2);
setter = Assert.IsType<Action<UIEventArgs>>(frame.AttributeValue);
setter = Assert.IsType<EventCallback>(frame.AttributeValue);
});
// Trigger the change event to show it updates the property
// Trigger the change event to show it updates the property
//
// This should always complete synchronously.
var newDateValue = new DateTime(2018, 3, 5, 4, 5, 6);
await renderer.Invoke(() => setter(new UIChangeEventArgs() { Value = newDateValue.ToString(), }));
var task = renderer.InvokeAsync(() => setter.InvokeAsync(new UIChangeEventArgs { Value = newDateValue.ToString(), }));
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
await task;
Assert.Equal(newDateValue, myDateProperty.GetValue(component));
}
@ -457,7 +473,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var renderer = new TestRenderer();
// Assert
Action<UIEventArgs> setter = null;
EventCallback setter = default;
var frames = GetRenderTree(renderer, component);
Assert.Collection(frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
@ -465,11 +481,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame =>
{
AssertFrame.Attribute(frame, "onchange", 2);
setter = Assert.IsType<Action<UIEventArgs>>(frame.AttributeValue);
setter = Assert.IsType<EventCallback>(frame.AttributeValue);
});
// Trigger the change event to show it updates the property
await renderer.Invoke(() => setter(new UIChangeEventArgs() { Value = new DateTime(2018, 3, 5).ToString(testDateFormat), }));
//
// This should always complete synchronously.
var task = renderer.InvokeAsync(() => setter.InvokeAsync(new UIChangeEventArgs { Value = new DateTime(2018, 3, 5).ToString(testDateFormat), }));
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
await task;
Assert.Equal(new DateTime(2018, 3, 5), myDateProperty.GetValue(component));
}
@ -540,18 +561,22 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var frames = GetRenderTree(renderer, component);
// Assert
Assert.Collection(frames,
Action<UIMouseEventArgs> func = default; // Since this is a method group, we don't need to create an EventCallback
Assert.Collection(
frames,
frame => AssertFrame.Element(frame, "button", 2, 0),
frame =>
{
AssertFrame.Attribute(frame, "onclick", 1);
var func = Assert.IsType<Action<UIMouseEventArgs>>(frame.AttributeValue);
func = Assert.IsType<Action<UIMouseEventArgs>>(frame.AttributeValue);
Assert.False((bool)clicked.GetValue(component));
func(new UIMouseEventArgs());
Assert.True((bool)clicked.GetValue(component));
});
func.Invoke(new UIMouseEventArgs());
Assert.True((bool)clicked.GetValue(component));
}
[Fact]
@ -568,7 +593,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var renderer = new TestRenderer();
// Assert
Action<UIEventArgs> setter = null;
EventCallback setter = default;
var frames = GetRenderTree(renderer, component);
Assert.Collection(frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
@ -576,11 +601,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame =>
{
AssertFrame.Attribute(frame, "onchange", 2);
setter = Assert.IsType<Action<UIEventArgs>>(frame.AttributeValue);
setter = Assert.IsType<EventCallback>(frame.AttributeValue);
});
// Trigger the change event to show it updates the property
await renderer.Invoke(() => setter(new UIChangeEventArgs() { Value = false, }));
//
// This should always complete synchronously.
var task = renderer.InvokeAsync(() => setter.InvokeAsync(new UIChangeEventArgs() { Value = false, }));
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
await task;
Assert.False((bool)myValueProperty.GetValue(component));
}
@ -599,7 +629,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
var renderer = new TestRenderer();
// Assert
Action<UIEventArgs> setter = null;
EventCallback setter = default;
var frames = GetRenderTree(renderer, component);
Assert.Collection(frames,
frame => AssertFrame.Element(frame, "input", 3, 0),
@ -607,11 +637,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
frame =>
{
AssertFrame.Attribute(frame, "onchange", 2);
setter = Assert.IsType<Action<UIEventArgs>>(frame.AttributeValue);
setter = Assert.IsType<EventCallback>(frame.AttributeValue);
});
// Trigger the change event to show it updates the property
await renderer.Invoke(() => setter(new UIChangeEventArgs() { Value = MyEnum.SecondValue.ToString(), }));
//
// This should always complete synchronously.
var task = renderer.InvokeAsync(() => setter.InvokeAsync(new UIChangeEventArgs { Value = MyEnum.SecondValue.ToString(), }));
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
await task;
Assert.Equal(MyEnum.SecondValue, (MyEnum)myValueProperty.GetValue(component));
}

View File

@ -44,11 +44,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore(receiver, callback);
}
@ -66,11 +61,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore(receiver, callback);
}
@ -88,11 +78,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore(receiver, callback);
}
@ -110,11 +95,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore(receiver, callback);
}
@ -135,6 +115,23 @@ namespace Microsoft.AspNetCore.Components
return callback;
}
/// <summary>
/// Returns the provided <paramref name="callback"/>. For internal framework use only.
/// </summary>
/// <param name="receiver"></param>
/// <param name="callback"></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public EventCallback<T> Create<T>(object receiver, EventCallback callback)
{
if (receiver == null)
{
throw new ArgumentNullException(nameof(receiver));
}
return new EventCallback<T>(callback.Receiver, callback.Delegate);
}
/// <summary>
/// Returns the provided <paramref name="callback"/>. For internal framework use only.
/// </summary>
@ -166,11 +163,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore<T>(receiver, callback);
}
@ -188,11 +180,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore<T>(receiver, callback);
}
@ -210,11 +197,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore<T>(receiver, callback);
}
@ -232,11 +214,6 @@ namespace Microsoft.AspNetCore.Components
throw new ArgumentNullException(nameof(receiver));
}
if (callback == null)
{
throw new ArgumentNullException(nameof(callback));
}
return CreateCore<T>(receiver, callback);
}
@ -270,22 +247,12 @@ namespace Microsoft.AspNetCore.Components
private EventCallback CreateCore(object receiver, MulticastDelegate callback)
{
if (!object.ReferenceEquals(receiver, callback.Target) && receiver is IHandleEvent handler)
{
return new EventCallback(handler, callback);
}
return new EventCallback(callback.Target as IHandleEvent, callback);
return new EventCallback(callback?.Target as IHandleEvent ?? receiver as IHandleEvent, callback);
}
private EventCallback<T> CreateCore<T>(object receiver, MulticastDelegate callback)
{
if (!object.ReferenceEquals(receiver, callback.Target) && receiver is IHandleEvent handler)
{
return new EventCallback<T>(handler, callback);
}
return new EventCallback<T>(callback.Target as IHandleEvent, callback);
return new EventCallback<T>(callback?.Target as IHandleEvent ?? receiver as IHandleEvent, callback);
}
}
}

View File

@ -2,10 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Forms;
namespace Microsoft.AspNetCore.Components
{
/// <summary>
/// Used by generated code produced by the Blazor code generator. Not intended or supported
/// Used by generated code produced by the Components code generator. Not intended or supported
/// for use in application code.
/// </summary>
public static class RuntimeHelpers
@ -17,5 +21,502 @@ namespace Microsoft.AspNetCore.Components
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(T value) => value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<EditContext> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<EditContext, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIChangeEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIChangeEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIClipboardEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIClipboardEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIDataTransferItem> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIDataTransferItem, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIDragEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIDragEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIErrorEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIErrorEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIFocusEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIFocusEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIKeyboardEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIKeyboardEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIMouseEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIMouseEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIPointerEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIPointerEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIProgressEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIProgressEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UITouchEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UITouchEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<UIWheelEventArgs> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<UIWheelEventArgs, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<int> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<int, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<int?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<int?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<long> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<long, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<long?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<long?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<decimal> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<decimal, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<decimal?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<decimal?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<float> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<float, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<float?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<float?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<double> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<double, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<double?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<double?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<DateTime> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<DateTime, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<DateTime?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<DateTime?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<bool> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<bool, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<bool?> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<bool?, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<string> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<string, Task> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Action<object> value) => (T)(object)value;
/// <summary>
/// Not intended for use by application code.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T TypeCheck<T>(Func<object, Task> value) => (T)(object)value;
}
}

View File

@ -58,8 +58,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -80,6 +80,21 @@ namespace Microsoft.AspNetCore.Components
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_Action_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create(component, (Action)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_ActionT_AlreadyBoundToReceiver()
{
@ -110,8 +125,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -132,6 +147,21 @@ namespace Microsoft.AspNetCore.Components
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_ActionT_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create(component, (Action<string>)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_FuncTask_AlreadyBoundToReceiver()
{
@ -162,8 +192,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -200,6 +230,21 @@ namespace Microsoft.AspNetCore.Components
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_FuncTask_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create(component, (Func<Task>)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_FuncTTask_DifferentReceiver()
{
@ -214,8 +259,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -236,6 +281,21 @@ namespace Microsoft.AspNetCore.Components
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void Create_FuncTTask_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create(component, (Func<string, Task>)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_String_ReturnsInput()
{
@ -299,8 +359,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -321,6 +381,21 @@ namespace Microsoft.AspNetCore.Components
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_Action_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create<string>(component, (Action)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_ActionT_AlreadyBoundToReceiver()
{
@ -351,7 +426,22 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_ActionT_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create<string>(component, (Action<string>)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
@ -403,8 +493,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -425,6 +515,21 @@ namespace Microsoft.AspNetCore.Components
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_FuncTask_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create<string>(component, (Func<Task>)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_FuncTTask_AlreadyBoundToReceiver()
{
@ -455,8 +560,8 @@ namespace Microsoft.AspNetCore.Components
// Assert
Assert.Same(@delegate, callback.Delegate);
Assert.Same(anotherComponent, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
Assert.Same(component, callback.Receiver);
Assert.False(callback.RequiresExplicitReceiver);
}
[Fact]
@ -477,6 +582,21 @@ namespace Microsoft.AspNetCore.Components
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateT_FuncTTask_Null()
{
// Arrange
var component = new EventComponent();
// Act
var callback = EventCallback.Factory.Create<string>(component, (Func<string, Task>)null);
// Assert
Assert.Null(callback.Delegate);
Assert.Same(component, callback.Receiver);
Assert.True(callback.RequiresExplicitReceiver);
}
[Fact]
public void CreateInferred_ActionT()
{

View File

@ -11,6 +11,8 @@
<p>
@(nameof(CascadingValueReceiveFixedByInterface)) render count:
<strong id="receive-by-interface-num-renders">@numRenders</strong>
@* Prevent rerendering this component when the button is clicked. *@
<button id="decrement-count" onclick=@Ancestor.DecrementCount>Decrement</button>
</p>

View File

@ -10,29 +10,29 @@
</div>
<div id="capturing_lambda">
<h3>Passing Capturing Lambda to Button</h3>
<InnerButton OnClick="@EventCallback.Factory.Create(this, () => { GC.KeepAlive(this); })" Text="Capturing Lambda" />
<InnerButton OnClick="@(() => { GC.KeepAlive(this); })" Text="Capturing Lambda" />
</div>
<div id="unbound_lambda">
<h3>Passing Unbound Lambda to Button</h3>
<InnerButton OnClick="@EventCallback.Factory.Create(this, () => { })" Text="Unbound Lambda" />
<InnerButton OnClick="@(() => { })" Text="Unbound Lambda" />
</div>
<div id="unbound_lambda_nested">
<h3>Passing Unbound Lambda to Nested Button</h3>
<MiddleButton OnClick="@EventCallback.Factory.Create(this, () => { })" Text="Unbound Lambda Nested" />
<MiddleButton OnClick="@(() => { })" Text="Unbound Lambda Nested" />
</div>
<div id="unbound_lambda_strongly_typed">
<h3>Passing Capturing Lambda to Strongly Typed Button</h3>
<StronglyTypedButton OnClick="@(EventCallback.Factory.Create<UIMouseEventArgs>(this, () => { GC.KeepAlive(this); }))" Text="Unbound Lambda Strongly-Typed" />
<StronglyTypedButton OnClick="@(() => { GC.KeepAlive(this); })" Text="Unbound Lambda Strongly-Typed" />
</div>
<div id="unbound_lambda_child_content">
<h3>Passing Child Content</h3>
<TemplatedControl>
<button onclick="@EventCallback.Factory.Create(this, () => { })">Unbound Lambda Child Content</button>
<button onclick="@(() => { })">Unbound Lambda Child Content</button>
</TemplatedControl>
</div>
<div id="unbound_lambda_bind_to_component">
<h3>Passing Child Content</h3>
<ButtonComponent Count="@buttonComponentCount" CountChanged="@(EventCallback.Factory.Create<int>(this, () => { }))" Text="Unbound Lambda Bind-To-Component" />
<ButtonComponent bind-Count="buttonComponentCount" Text="Unbound Lambda Bind-To-Component" />
</div>
@functions {

View File

@ -1,7 +1,7 @@
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Components.Forms
<EditForm Model="@this" OnValidSubmit="@(EventCallback.Factory.Create<EditContext>(this, HandleValidSubmit))" OnInvalidSubmit="@(EventCallback.Factory.Create<EditContext>(this, HandleInvalidSubmit))">
<EditForm Model="@this" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">
<DataAnnotationsValidator />
<p class="user-name">

View File

@ -1,34 +1,34 @@
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Components.Forms
<EditForm Model="@person" OnValidSubmit="@(EventCallback.Factory.Create<EditContext>(this, HandleValidSubmit))">
<EditForm Model="@person" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<p class="name">
Name: <InputText bind-Value="@person.Name" ValueExpression="@(() => person.Name)" />
Name: <InputText bind-Value="@person.Name" />
</p>
<p class="email">
Email: <InputText bind-Value="@person.Email" ValueExpression="@(() => person.Email)" />
Email: <InputText bind-Value="@person.Email" />
<ValidationMessage For="@(() => person.Email)" />
</p>
<p class="age">
Age (years): <InputNumber bind-Value="@person.AgeInYears" ValueExpression="@(() => person.AgeInYears)" />
Age (years): <InputNumber bind-Value="@person.AgeInYears" />
</p>
<p class="height">
Height (optional): <InputNumber bind-Value="@person.OptionalHeight" ValueExpression="@(() => person.OptionalHeight)" />
Height (optional): <InputNumber bind-Value="@person.OptionalHeight" />
</p>
<p class="description">
Description: <InputTextArea bind-Value="@person.Description" ValueExpression="@(() => person.Description)" />
Description: <InputTextArea bind-Value="@person.Description" />
</p>
<p class="renewal-date">
Renewal date: <InputDate bind-Value="@person.RenewalDate" ValueExpression="@(() => person.RenewalDate)" />
Renewal date: <InputDate bind-Value="@person.RenewalDate" />
</p>
<p class="expiry-date">
Expiry date (optional): <InputDate bind-Value="@person.OptionalExpiryDate" ValueExpression="@(() => person.OptionalExpiryDate)" />
Expiry date (optional): <InputDate bind-Value="@person.OptionalExpiryDate" />
</p>
<p class="ticket-class">
Ticket class:
<InputSelect bind-Value="@person.TicketClass" ValueExpression="@(() => person.TicketClass)">
<InputSelect bind-Value="@person.TicketClass">
<option>(select)</option>
<option value="@TicketClass.Economy">Economy class</option>
<option value="@TicketClass.Premium">Premium class</option>
@ -36,7 +36,7 @@
</InputSelect>
</p>
<p class="accepts-terms">
Accepts terms: <InputCheckbox bind-Value="@person.AcceptsTerms" ValueExpression="@(() => person.AcceptsTerms)" />
Accepts terms: <InputCheckbox bind-Value="@person.AcceptsTerms" />
</p>
<button type="submit">Submit</button>