ASP.NET 6 Razor Pages, JavaScript, Post Data to Code-behind

AD 1 Reputation point
2022-09-22T10:30:05.85+00:00

Sorry about the long post. My background: I am relatively new to the HTML/Javascript world and have basic knowledge of ASP.NET Razor Pages but no real experience using it.

Problem statement: Consume a (HTML) Web Component containing a form having input text boxes from ASP.NET 6 Razor pages/views so as to make available in the Razor Pages code behind, the values entered into the text boxes of the form.

I tried putting together a working example (PoC) as follows:

Visual Studio 2022 Solution: Created using Microsoft's guidelines from here

In my working PoC I have the following:

A Razor page that consumes a web component (called "my-component"): Added a new Razor Page which I used as my test page, called TestMyComp, which resulted in 2 files getting created: TestMyComp.cshtml and TestMyComp.cshtml.cs.

TestMyComp.cshtml:

@page  
@Html.AntiForgeryToken()  
@model RazorWebApp.Pages.TestMyCompModel  
  
<h2>Test My Web Component!</h2>  
  
<form method="post" id="myform">  
    <my-component id="myco"></my-component>  
    <script src="../js/mycomponent.js"></script>  
  
    <input hidden asp-for="BoundCredentialsModel!.UserName" id="myUsername"/>  
    <input hidden asp-for="BoundCredentialsModel!.Password" id="myPass"/>  
</form>  
  
@section Scripts  
{  
    <script type="text/javascript" language="javascript">  
  
        const mycomp = document.getElementById('myco');  
        mycomp.addEventListener('mycomp-submit', (e) => loginButtonClickedHandler(e));  
  
  
        function loginButtonClickedHandler(e) {  
            var username = e.detail.username;  
            var pass = e.detail.password;  
  
            document.getElementById('myUsername').value = username;  
            document.getElementById('myPass').value = pass;  
            document.getElementById('myform').submit();  
  
        }  
    </script>  
}  

(Snipped) TestMyComp.cshtml.cs:

    public void OnGet()  
    {  
    }  
  
    [BindProperty]  
    public Credentials? BoundCredentialsModel { get; set; }  
  
    public IActionResult OnPost()  
    {  
        if (!ModelState.IsValid)  
        {  
            return new JsonResult(".Error.");  
        }  
  
        return new JsonResult("Received in server: UserName = " + BoundCredentialsModel?.UserName +   
``", pass = " + BoundCredentialsModel?.Password);  
    }  

The Web Component contains a form with a few input text boxes and a submit button - in my PoC I have a username & a password input box and a submit button. After the username and password are entered I would like their values to be available in my code behind, i.e. in TestMyComp.cshtml.cs.

For this I made use of Razor's [BindProperty] on the code behind. Following is my flow:

  1. User enters username and password and presses the Submit button. This is happening in the web component.
  2. Web component fires an event after the Submit button is pressed
  3. In my Razor page i.e. TestMyComp.cshtml, where I have hosted the web component in a form, I am subscribed to the aforementioned event, so I receive it along with a payload that contains the username/password keyed in by the user.
  4. In TestMyComp.cshtml I also have 2 hidden input boxes, one each for username and password. In the event handler for the event, where the event's payload contains the username and password, I programmatically fill in the values of these two hidden boxes (this is the code behind's bound property) and also programmatically call submit on the form.

If it helps, here is a diagram with approximations to illustrate the flow: diagram243836-screenshot-2022-09-22-153609.png

This makes the username and password values available to me in the code behind (in the OnPost method). My question is, as far as the Razor (.cshtml and .cshtml.cs) code is concerned, have I done it right? Is there any better way of achieving this (i.e. is there a better solution)?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,187 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 56,686 Reputation points
    2022-09-23T16:24:21.38+00:00

    your web components are javascript controls. that render the html and fire javascript events.

    you need the designers of the components to answer these questions:

    • does it generate a <form>, if so it can not be nested in another form
    • does it support inclusion in a <form>. does it have any named inputs that would be included in the form post. if so these should be defined in the support docs.
    • does it have a hide / destroy support (client re-render)

    if the component supports form posts, then you should map the names to the page model, and just do a form.submit() on the event.

    0 comments No comments

  2. AD 1 Reputation point
    2022-09-28T06:12:09.717+00:00
    0 comments No comments