How to create a button that will go to a razor page when clicked ("Razor page" in dotnet core 2) - asp.net-core

I can use an anchor tag helper to go to a different razor page (from an existing razor page) e.g. this works:
<a asp-page="./EditReport" asp-route-id="#report.IntegrityReportId" class="btn fa fa-edit"></a>
How can I get a similar thing to work but using a button. I have tried:
<button type="button" asp-route-data="#report.IntegrityReportId" asp-route="EditReport">EditReport</button>
But the page never loads. I also tried using the page handler with different variations of:
<input type="button" asp-page-handler="EditReport" asp-route="#report.IntegrityReportId"/>
and associated (in the page cs file):
public ActionResult OnEditReport(int id)
{
return RedirectToPage("./EditReport", id);
}
but this method never gets called (I've also tried naming method OnPostEditReport but same problem.
If it helps, my original NON- dotnet core app worked fine with:
<button type="button" title="Edit report" class="btn btn-datatable fa fa-edit" onclick="location.href = '#Url.Action("EditReport", "Home", new {id = report.IntegrityReportID})'"></button>
Any help is appreciated.Thanks.

I managed to get the effect I needed by using the below anchor - so it looks like a button..
<a asp-page="./EditReport" asp-route-id="#report.IntegrityReportId" class="btn btn-default"><i class="fa fa-edit"></i></a>

The solution below worked for me in my ASP.NET Core 3.1 project:
<a class="btn btn-primary btn-sm" asp-page="./Edit" asp-route-id="#item.Id"><i class="fas fa-user"></i> Edit</a>
The highlighted code above is all on one line, just the way stack overflow is presenting the answer. Note I chose to display the icon before the text in the button, then I added a single chazr space before the button label 'Edit' just so the button looks a little nicer.

You can not use just a button which will redirect to an other razor page without javascript. You can use a submit button inside a form tag in order to redirect to an other razor page. The following example demonstrates how to make a GET redirect which will redirect to the About page:
<form method="get">
<button type="submit" asp-page="./About">Click me to go to the About page</button>
</form>
if you want a POST request use the following code:
<form method="post">
<button type="submit" asp-page="./About">Click me to go to the About page</button>
</form>
In both cases you can define routing values or handlers in order to cover the requirements.
I hope it helps.

I know its a year late, but you have to remove 'type="button"', also try removing '.' from asp-page="./EditReport".
BR.

This works in ASPNET Core 3.1.
<form method="get" action="/myRazorPage">
<button type="submit">Join Now</button>
</form>

using button:
<button type="button" class="btn" onclick="window.location.href = '/YourPage'">Button Title</button>

Related

#Localizer doesn't work on special case input type submit with asp-for and value

I have an button on my razor page where I submit a value to my post method.
All worked as I want to
<input type="submit" value="Resend Link" asp-for="#resendLink" class="btn btn-primary" />
in my c# I catch the value on post
public async Task<IActionResult> OnPostAsync(string resendLink)
Now I simply wanted to localize the language of the button
<input type="submit" value=#Localizer["Resend Link"] asp-for="#resendLink" class="btn btn-primary" />
Localizer does not work
It works if I use it without asp-for tag or if I declare it with button tag
<button type="submit" asp-for="#resendLink" value="ResendLink" class="btn btn-primary">#Localizer["Resend Link"]</button>
However like that it does not anymore transfer the value to my post method.
How can I localize it? and still have the transfer?
Tks for helping!
Asp.net core bind data with name attribute.As you said It works if I use it without asp-for tag or if I declare it with button tag.You can remove asp-for tag and add name attribute like this:
<input type="submit" value=#Localizer["Resend Link"] name="resendLink" class="btn btn-primary" />

ASP.NET CORE Razor Pages: How to avoid executing page handler 2nd time on page refresh?

When using method handlers to execute OnGet or OnPost methods, &handler=[action] query string gets added.
Problem is if user manually refreshes the page afterwards by hitting browser's refresh button, the same action will get executed for the 2nd time unintentionally.
What is the recommended approach to avoid this?
Problem is if user manually refreshes the page afterwards, same action
will get executed for the 2nd time.
For the browser refresh button click event, we can't prevent it. But, as a workaround, you could defined a TriggerCount property in the page model, and use a hidden field to store the value in the form, then in the handler method, get the hidden field value and based on the count to do something. Code as below:
code in the .cshtml.cs page:
public void OnPostDelete()
{
if (Request.Form["TriggerCount"].Count > 0)
{
TriggerCount = Convert.ToInt32(Request.Form["TriggerCount"]);
TriggerCount++;
}
if (TriggerCount < 2)
{
// do something.
Message = "Delete handler fired, Count:" + TriggerCount;
}
else
{
Message = "Over 2 times";
}
}
Code in the .cshtml page:
#page
#model RazorPageSample.Pages.HandlerPageModel
#{
}
<div class="row">
<div class="col-lg-1">
<form asp-page-handler="edit" method="post">
<button class="btn btn-default">Edit</button>
</form>
</div>
<div class="col-lg-1">
<form asp-page-handler="delete" method="post">
<input type="hidden" asp-for="TriggerCount" />
<button id="btndelete" disabled="#(Model.TriggerCount>=1?true:false)" class="btn btn-default">
Delete
</button>
</form>
</div>
</div>
<h3 class="clearfix">#Model.Message</h3>
the screenshot as below:

Scaffolded Identity Razor Pages Forms don't submit unless there is a route parameter

This happens on all the Scaffolded Identity Razor Pages that do not include a route parameter in the Form definition, but let's take the ForgotPassword one as an example:
Here is the form as defined on the scaffolded page:
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
When I click the submit button, nothing happens. The browser dev tools confirm nothing happens. The page does not submit to the server. (and yes, I have entered a valid email address; if I don't, then the jquery validation correctly displays the appropriate error messages.)
But I've found that if I change the form definition to include a route parameter, as follows:
<form asp-route-unusedArg="SomeValue" method="post">
then the submit button works fine, and the form is submitted to the server. (Even though the OnPostAsync method defined by the server code does not expect a parameter at all; it is defined as public async Task<IActionResult> OnPostAsync()). The way I figured this out was to compare the form definition with that of the Login form, which was working fine, and had a route parameter for returnUrl.
What is going on here? Why is the form not submitting unless I add a route parameter?

Razor Pages - Run a server side method NOT using post

In Razor pages ASP.NET Core, how do I do a basic onclick event for a button which is of type button?
Do I need to wire up an AJAX GET request to get the below "Resend Code" button to work? There is plenty of chatter about OnPost this and that.. but I don't want to post.
Can't be this hard?
<form method="post">
<div asp-validation-summary="All"></div>
<div class="form-group-item">
<label asp-for="Input.TwoFactorCode"></label>
<input asp-for="Input.TwoFactorCode" class="input" />
<span asp-validation-for="Input.TwoFactorCode"></span>
</div>
<div class="form-group-item">
<label class="margin-0" asp-for="Input.RememberMachine">
<input asp-for="Input.RememberMachine" />
#Html.DisplayNameFor(m => m.Input.RememberMachine)
</label>
</div>
<div>
<button type="button" asp-page-handler="ResendCode" class="btn btn-light">Resend Code</button>
<button type="submit" class="btn btn-secondary">Confirm</button>
</div>
</form>
As it stands, the button won't do anything. You can use JavaScript to intercept the button click and then fire a get request using AJAX (jQuery example below):
$('.btn.btn-light').on('click', function(){
$.get('?handler=ResendCode', data, function(){
...
});
});
You can try changing the button to use formmethod="get":
<button type="submit" formmethod="get" asp-page-handler="ResendCode" class="btn btn-light">Resend Code</button>
Note, this will only work for buttons that have type="submit" or type="image" (other type-values don't cause the form to submit). Also it's an HTML5 attribute.
Reference:
https://html.com/attributes/input-formmethod/
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formmethod
maybe try making your own custom handler methods other than OnPost() and OnGet()

Adding a graphic to the OpenID login button on ASP.NET MVC Sample

I'm using the VS 2012 MVC4 (razor) sample (new to pretty much all of this) and I modified the AuthConfig.cs file to allow both OpenID access for Google and Yahoo
OAuthWebSecurity.RegisterGoogleClient();
OAuthWebSecurity.RegisterYahooClient();
Sure enough, those two OpenID options are presented. I want to modify this so the button shows the appropriate logo.
Does DotNetOpenAuth have a way of returning the image path? I was thinking if it did, I could modify the ExternalLogin "page".
#foreach (AuthenticationClientData p in Model)
{
<button type="submit" name="provider" value="#p.AuthenticationClient.ProviderName" title="Log in using your #p.DisplayName account"><img src="" />#p.DisplayName </button>
}
You can do it like this (sorry it's vb.net code):
In AuthConfig RegisterAuth method create a dictionnary and Add your icon path to the desired image
Dim MsExtraData As New Dictionary(Of String, Object)
MsExtraData.Add("Icon", VirtualPathUtility.ToAbsolute("~/Images/Microsoft.png"))
' Then pass it as extraData parameter to the register client method
OAuthWebSecurity.RegisterMicrosoftClient(
clientId:="yourkey",
clientSecret:="yoursecret",
displayName:="Microsoft",
extraData:=MsExtraData)
Now go to view _ExternalLoginsListPartial in Views\Account folder
and change button generation code with this :
<button type="submit" id="<%: p.DisplayName%>" name="provider" value="<%: p.AuthenticationClient.ProviderName%>" title="Login with <%: p.DisplayName %>"><%: p.DisplayName%>
<img src="<%: p.ExtraData("Icon")%>" alt="Icon for <%: p.DisplayName%>" />
</button>
Sounds good. The Twitter and Facebook signature require an extra field: displayName.
I just used font-awsome to do that task on the _ExternalLoginsListPartials view like so:
using (Html.BeginForm(Model.Action, "Account", new { ReturnUrl = Model.ReturnUrl }))
{
#Html.AntiForgeryToken()
<div id="socialLoginList">
<p>
#foreach (AuthenticationDescription p in loginProviders)
{
<button type="submit" class="btn btn-default" id="#p.AuthenticationType" name="provider" value="#p.AuthenticationType" title="Log in using your #p.Caption account"><span class="fa fa-#p.Caption.ToLower()"> </span>#p.AuthenticationType</button>
}
</p>
</div>
}
That off course provided you are using Font-Awsome but I think it would also work with other glyphicons. Also this is MVC5 and VS2013 but I guess it's still applicable for previous MVC versions since I am using html, css and Razor only.
Hope that helps!