Razor Pages POST Multiple Forms w/ Model Binding - c#

I have multiple forms on a single razor page that I want to be POSTed after one button is clicked. I tried using a javascript function that would .submit() both forms (put in the onclick= of the button), but only one form's values were actually passed to the OnPost() method serverside. Here's the relevant code from the .cshtml and the .cs files:
StudentMain.cshtml
<!--first form-->
<form class="login100-form" method="post">
<span class="login100-form-title" style="padding-bottom: 38px">
Student Information
</span>
<div class="wrap-input100">
<input class="input100 has-val" type="text" name="name" value='#ViewData["name"]' readonly/>
<span class="focus-input100" data-placeholder="Student Name"></span>
</div>
...more divs/inputs as above
</form>
<!--second form-->
<form class="login100-form" method="post">
<div class="wrap-input100">
<select class="input100 select" name="eduplan" selectedval='#ViewData["eduplan"]'>
<option disabled selected value style="display:none"/>
<option>High School Diploma</option>
<option>Technical Training</option>
<option>Associate Degree</option>
<option>Bachelor's Degree</option>
<option>Advanced Degree</option>
<option>Military</option>
<option>Other</option>
</select>
<span class="focus-input100" data-placeholder="Education Plan"></span>
</div>
...more divs/selects as above
<div class="container-login100-form-btn">
<div class="wrap-login100-form-btn">
<div class="login100-form-bgbtn"></div>
<button class="login100-form-btn" type="submit">
Save
</button>
</div>
</div>
</form>
StudentMain.cshtml.cs
public class StudentMain : PageModel
{
public void OnPost(string eduplan, string college, string major, string careerpath, string ethnicity, string gender, string ncaa, string firstgen, string onlineinterest)
{
Database.SaveStudentData(eduplan, college, major, careerpath, ethnicity, gender, ncaa, firstgen, onlineinterest);
}
}
So, what's the best way to go about doing this? How can I make sure that the values from both forms are passed to the OnPost() method simultaneously? Do I need to use AJAX in some capacity? Any help is appreciated.

You can use different methods for different form POSTs by specifying the method's name as the value for the asp-page-handler tag helper on each form. More information can be found on this Youtube Video
UPDATE
For example, you have two POST methods in your Model class, namely: OnPostAdd and OnPostSubtract, the different forms to post to the different methods would look like this:
<form method="post" asp-page-handler="Add">
<button type="submit">Add</button>
</form>
<form method="post" asp-page-handler="Subtract">
<button type="submit">Subtract</button>
</form>
PS: It doesn't matter whether your method is named OnPostAdd or OnPostAddAsync, ASP.NET Core still expects your handler name to be Add as it automatically resolves prefixes like OnPost, OnGet etc, and suffixes like Async

Related

ASP.NET - Read Component Parameter In Razor View

I have an existing ASP.NET app that uses one Razor component throughout. Unfortunately, this component does not have a model associated with it. I'm in a scenario where I need to add one parameter. At this time, I have the following in the component host view:
#await Component.InvokeAsync("MyTextField", new { Align = "Left" })
The component Razor code currently looks like this:
MyTextField.cshtml
<div class="text-right">
<form asp-action="ReadItem" asp-controller="Inventory" method="get" id="inventory-form">
<input id="inputField" class="input-text" type="text" />
<button class="submit-button" type="submit">Submit</button>
</form>
</div>
Currently, the component renders. However, I want to get the value of the Align parameter, if it exists, in the MyTextField.cshtml view. Is there a way for me to get a parameter value there? If so, how?
Thanks
You can do that in this way:
#await Component.InvokeAsync("MyTextField", new User{ Align = "Left" })
and in View (cshtml file):
#using UserNamespace
#model User
<div class="text-right">
<form asp-action="ReadItem" asp-controller="Inventory" method="get" id="inventory-form">
<input id="inputField" class="input-text" type="text" value="#Model.Align" />
<button class="submit-button" type="submit">Submit</button>
</form>
</div>

Saving a search string to use in other cshtml pages in ASP.NET Core Web Application

I am trying to save input (an address) from an html form in order to use in other cshtml pages in my asp.net core web application. I am also using Razor as a template language. I have a web application in which the user will enter an address on one page and then on another page I want to use that input and place it into an api call. My html form is below.
<form method="post" action="/Features">
<p>
Address: <input type="text" name="searchString"/>
<input type="submit" value="Search" />
</p>
</form>
I have previously used sessions but it was for an asp.net project using web forms (I believe) and am not sure if this is the route I should go. The address being entered doesn't need to be kept secure. Thanks for any help.
You have two options here:
Submit the form to your page, store the address in TempData then redirect to the second page where you would use your submitted value (Here you use the Post/Redirect/Get pattern in order to avoid your form being submitted again by mistake via a page reload).
Submit the form directly to the second page.
Going with the first option is recommended.
Page:
<form method="post" asp-page-handler="Features">
<p>
Address: <input type="text" name="searchString"/>
<input type="submit" value="Search" />
</p>
</form>
Handler:
public IActionResult OnPostFeatures(string searchString)
{
TempData["Key"] = searchString;
return RedirectToPage("/SecondPage");
}
Then on your second page you get the searchString in the same way via:
string value = TempData["Key"] as string;
As i said you can also submit your form to the second page where you can do what ever you want with your value. Just be careful of multiple submissions.
Here is a demo to use TempData in Razor page:
cshtml:
<form method="post" asp-page-handler="Features">
<p>
Address: <input type="text" name="searchString"/>
<input type="submit" value="Search" />
</p>
</form>
cshtml.cs:
public IActionResult OnPostFeatures(string searchString) {
TempData["searchString"] = searchString;
xxxxxxx
}
Other Page you want to use searchString:
string searchString=TempData["searchString"];
//TempData.Keep(); can help you keep the value,and you can still use the searchString value in other place
TempData.Keep();
or you can use
string searchString=TempData.Peek("searchString");
So that you can still keep the searchString value

Radio Button Toggle call C# Function

i build this application:
CRUD Application with ASP.NET Core 3.0 & Entity Framework 3.0 Using Visual Studio 2019
Now i found a nice toggle(https://codepen.io/shaneheyns/pen/OPWGry):
i will only have the toggle like this code:
<div class="pricing-switcher">
<p class="fieldset">
<input type="radio" name="duration-1" value="monthly" id="monthly-1" checked>
<label for="monthly-1">Monthly</label>
<input type="radio" name="duration-1" value="yearly" id="yearly-1">
<label for="yearly-1">Yearly</label>
<span class="switch"></span>
</p>
</div>
everything works(i copied the .css style), but how can i execute a C# function if monthly is checked?
i searched a lot and tried alot but nothing worked.
the only things is a extra submit button.
but i will something like an Onchange event or something that called a C# Function in my Controller.
if i have a button i would code it like this:
<a asp-action="monthly">Test!!</a>
Can somebody please help me?
Thank you!
now i updated my Code like this:
#using (Html.BeginForm("test1", "Test"))
{
<div class="pricing-switcher">
<p class="fieldset">
<input type="radio" name="Isactive" value="test1" id="monthly-1"checked>
<label for="monthly-1">monthly</label>
<input type="radio" name="test1" value="test2" id="yearly-1">
<label for="yearly-1">yearly</label>
<span class="switch"></span>
</p>
</div>
and the .js Code:
$(document).ready(function () {
$("input[name='Isactive']").change(function () {
$(this).closest("form").submit();
});
});
now the function in Controller is like this:
public void Isactive()
{
Debug.WriteLine("test");
}
The Function was called thanks! But 2 problems:
The switch does not toggle
On click the site will redirect to IsActive the browserlink is https://localhost:44311/Test/Isactive
How to fix these?
Sorry i know C#, but html/js/css are new to me
The switch does not toggle
For the first question, You should keep the name of two radio button the same.
<div class="pricing-switcher">
<p class="fieldset">
<input type="radio" name="duration-1" value="test1" id="monthly-1"checked>
<label for="monthly-1">monthly</label>
<input type="radio" name="duration-1" value="test2" id="yearly-1">
<label for="yearly-1">yearly</label>
<span class="switch"></span>
</p>
</div>
On click the site will redirect to IsActive the browserlink is https://localhost:44311/Test/Isactive
For the second question, This is the default behavior for form submission, the form points to this url. If you want to stay at the current page, you can submit the form with ajax.

Passing parameter to Controller from view with tag helpers not working on a submit

I'm using ASP.NET Core 2.2.
I'm trying to pass an ID (Guid) from my view to my controller Index using a submit button decorated with asp tag helpers like below:
<input type="submit" value="Go" asp-controller="MyController" asp-action="Index" asp-route-id="#Model.Id" />
My controller action method looks like this:
public IActionResult Index(Guid id)
{
return View();
}
The id is always coming through as Guid.Empty when the submit button is clicked.
I've switched over to using an anchor tag with the same tag helper values and the id comes through populated correctly:
<a asp-controller="MyController" asp-action="Index" asp-route-id="#Model.Id">Go</a>
I can get around this by styling an anchor to look like a button, but for the sake of understanding, can someone explain why an anchor would work in this situation but a submit button will not?
UPDATED (with generated HTML)
HTML with submit
<form>
<div class="d-flex">
<input type="submit" value="Go" formaction="" />
</div>
</form>
HTML with anchor
<form>
<div class="d-flex">
Go
</div>
</form>
put the asp-route-id="..." in the form tag, not in the button.

Form post to another page

I am fairly new to C# and asp.net and am having trouble showing something submitted in a form. The form element is a tag. The drop-down info is pulled from a data base and displays correctly. It's just getting it to post to another page after the form is submitted is where I am having the problem. Any help would be appreciated.
Contact.aspx:
<form action="Default.aspx" method="post" data-transition="pop">
<div data-role="fieldcontain">
<label for="topEmails">Business Entity ID:</label>
<select name="topEmails" id="topEmails" data-native-menu="false"
runat="server">
</select>
</div>
<input type="submit" data-iconpos="right" data-inline="true"
data-icon="plus" name="sendMessage" id="sendMessage" value="Send Info">
</form>
Contact.aspx.cs:
AdventureWorks2012DataContext db = new AdventureWorks2012DataContext();
var emails = (from b in db.EmailAddresses
select new { b.EmailAddressID, b.BusinessEntityID }).Take(20);
topEmails.DataTextField = "BusinessEntityID";
topEmails.DataValueField = "BusinessEntityID";
topEmails.DataSource = emails;
topEmails.DataBind();
Default.aspx.cs:
FormSuccessBID.InnerHtml = "Business Entity ID: " + Request.Form["topEmails"] + "";
Any ideas why this wouldn't be working?
Update:
Contact.aspx:
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<h2 style="text-align: center;">Contact Kyle</h2>
<form action="Default.aspx" method="post" data-transition="pop">
<div data-role="fieldcontain">
<label for="userFName">First Name:</label>
<input type="text" name="firstName" id="uFName">
</div>
<div data-role="fieldcontain">
<label for="userLName">Last Name :</label>
<input type="text" name="lastName" id="uLName">
</div>
<div data-role="fieldcontain">
<label for="productsCategories">Products:</label>
<select name="productCategories" id="productCategories" data-native-menu="false" runat="server"></select>
</div>
<div data-role="fieldcontain">
<label for="topEmails">Business Entity ID:</label>
<select name="topEmails" id="topEmails" data-native-menu="false" runat="server"></select>
</div>
<input type="submit" data-iconpos="right" data-inline="true" data-icon="plus" name="sendMessage" id="sendMessage" value="Send Info">
</form>
</asp:Content>
You're missing "runat='server'" in your form definition.
In ASP.NET you're also allowed one form per page. Not sure from what you're posted if you're trying to put multiple forms on there, but if you are, it's not going to work.
I think all you need to do to accomplish what you want is have an ASP.NET button on the page, with the postbackURL set to the page you want to go to. (Of course, you need to do this in a server-side form)
I think you're mixing ASP.NET methods with other, different technologies. (From the look of it, you probably used classic ASP or PHP perhaps?)
If you can't use .NET for whatever reason, the ID/name of the field is not going to be what you're expecting. You need to inspect the form post and find its value - something along the lines of "clt00_somethingelse_topEmails". (Again, this is going to be a heck of a lot easier if you use the .NET way of doing things, but you may have a requirement not to)

Categories

Resources