Search code examples
c#asp.net-corerazor-pages

InvalidOperationException. Cannot bind complex type. Asp.net core 6


I'm trying to pass ICallbackSuccess to Razor Page's OnGet

public async Task OnGetAsync(string phoneNumber, string? returnUrl, ISuccessCallback callback)

This is interface:

public interface ISuccessCallback
{
    Task CallAsync(AppUser user, SignInManager<AppUser> signInManager);
}

These are implementations:

public class SaveAccountChangesCallback : ISuccessCallback
{
    public async Task CallAsync(AppUser user, SignInManager<AppUser> signInManager)
    {
        await signInManager.RefreshSignInAsync(user);
    }
}
public class SignInCallback : ISuccessCallback
{
    public async Task CallAsync(AppUser user, SignInManager<AppUser> signInManager)
    {
        var result = await signInManager.UserManager.CreateAsync(user);
        if (!result.Succeeded)
        {
            var error = "";
            var errors = result.Errors.ToList();
            for (var i = 0; i < errors.Count; i++)
            {
                error += $"{i + 1}: {errors[i].Description}\n";
            }

            throw new Exception($"Can't create new user: \n{error}");
        }

        await signInManager.SignInAsync(user, false);
    }
}

These are call sites:

return RedirectToPage("VerifyCode", new
{
    phoneNumber = Input.PhoneNumber,
    returnUrl = ReturnUrl,
    callback = new SignInCallback()
});
return RedirectToPage("../VerifyCode", new
{
    phoneNumber = Input.PhoneNumber,
    returnUrl = HttpContext.Request.GetEncodedUrl(),
    callback = new SaveAccountChangesCallback()
});

The full text of error message:

InvalidOperationException: Could not create an instance of type 'Web.Areas.Identity.Pages.Account.Logic.VerifyCode.ISuccessCallback'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Record types must have a single primary constructor. Alternatively, give the 'callback' parameter a non-null default value.

Solution

  • I have memorized value of callback in the property, declaration of which is the problem:

    [BindProperty] public ISuccessCallback Callback { get; private set; }. Need to remove private for set and everything is done.