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.
I have the following web form:
Working Form:
<form id="transactionParameters" method="post" runat="server" action="remote_url.aspx">
<fieldset>
<p>
<label for="Username">Username:</label>
<asp:TextBox id="Username" Text="TomSelleck" runat="server" />
</p>
<asp:Button ID="SubmitForm" runat="server" onclick="SubmitForm_Click" Text="Button" />
</fieldset>
</form>
And this successfully submits the form value Username to remote_url.aspx and brings the user to the remote page.
The problem I face is that I need to add a value to the form before submitting the form and redirecting the user e.g:
Desired functionality:
<form id="transactionParameters" method="post" runat="server">
<fieldset>
<p>
<label for="Username">Username:</label>
<asp:TextBox id="Username" Text="TomSelleck" runat="server" />
</p>
<asp:Button ID="SubmitForm" runat="server" onclick="SubmitForm_Click" Text="Button" />
</fieldset>
</form>
// This method is fired but I don't know how to execute the commented out code
protected void SubmitForm_Click(object sender, EventArgs e)
{
// Form["Username"] = Username.Text.Uppercase();
// Form["NewValue"] = DateTime.Now.ToString();
// ExecuteAction(Form, "remote_url.aspx");
}
You can accomplish this in several different ways.
Query String
Session
Cookie
Internal variable / object
The question will be what are the requirements? The easiest would be the Query String, simply do Response.Redirect("...aspx?username=Tom");.
Then on the other form you would simply parse the Query String. Request.QueryString["username"]?.ToString().
The drawback would be your url has a username in clear text and is exposed easily. The Session would store a unique identifier of that information into a cookie, making those approaches similar. But equally easy and may meet your requirements.
An internal object variable after the method fires, storing that object in memory making it accessible and exposed on the other page load event will work also.
So, I have a Paypal form that worked wonders. However, I now need to add a coupon field, where someone can enter a code, and get a reduction based on whatever the backend replies.
This all works wonderfully, but I've ran into an issue when adding the option to know before checking out whether your code is valid or not. Currently, my form (once simplified) looks like this :
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post"
id="payPalForm" runat="server">
<asp:TextBox runat="server" ID="txtCode" />
<asp:Button Text="Validate" OnClick="ValidateDiscount" runat="server" />
<asp:Label ID="txtDesc" runat="server" />
<input type="submit" name="Submit" value="Pay up!" />
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
...
</form>
With the backend having the function :
protected void ValidateDiscount(object sender, EventArgs e)
{
this.txtDesc.Text = "fetch from database using: " + txtCode.Text;
}
My issue is that wheneve I click on the Validate button, the form is submitted and I end up on the Paypal website. I used Jquery at first with preventDefault(), but that actually prevents my server-side function from firing. I've also tried putting a standard <button> or <input type='button'> tag instead, but I couldn't get it to fire my server-side function.
Is there any way to have the Validate button not submit the form, or should I just remove the action from the form and manually submit the form when clicking on the submit button?
You have set your form action to post to PayPal.
This is the action:
action="https://www.sandbox.paypal.com/cgi-bin/webscr"
Here is where you have it in you form tag:
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post"
id="payPalForm" runat="server">
Remove this from your form tag and it should postback to your application.
I have a loop that creates some buttons and (is meant to) make a function call when that button is pressed.
foreach (Answer a in qanswers)
{
//Guid answerid = new Guid();
<form method="post" action="">
<div class="float-left">
<input type="submit" value="#a.Answer1" class="submit" style="width:600px" onmousedown="#{saveTest(a, module, user, quest, healthsafety);}">
<br /><br />
</div>
</form>
}
However, it calls the "saveTest" procedure at page load for each button produced, rather than onmousedown/onmouseclick.
Is it possible to change this?
I assume from this that saveTest is a server side function that you are trying to call.
onmousedown is a client side event and can only directly run client side script.
If you wish to call a server side function then you will need to specify an action in the form that the page will post pack to.
Have a look here for more on this
http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform(v=vs.108).aspx
A quickly modified version of your code would be:
foreach (Answer a in qanswers)
{
using (Html.BeginForm("saveTest", "ControllerName"))
{
<div class="float-left">
<input type="submit" value="#a.Answer1" class="submit" style="width:600px")>
<br /><br />
</div>
}
}
The button will submit to the controller and action that has specified in the form. So please check carefully which controller and action you have specified.
using (Html.BeginForm("saveTest", "Controller"))
{
}
This is the way you have to specify your form.
Regards,
Pavan.G
I have a cancel button in a form:
#using (Html.BeginForm("ConfirmBid","Auction"))
{
some stuff ...
<input type="image" src="../../Content/css/img/btn-submit.png" class="btn-form" />
<input type="image" src="../../Content/css/img/btn-cancel.png" class="btn-form" />
}
The issue is I want this button to go to a particular view when I click on it. How do I do this?
Either you can convert the Cancel button as an anchor tag with #Html.ActionLink helper method and apply a css class which makes the link to looks like a button and then in the controller action for that link, you can return the specific view.
#Html.ActionLink("Cancel","Index","Products",null, new { #class="clsButtonFake"})
or
Use 2 submit buttons in the form. One for real submit and one for the cancel. and in your controller action, check which button called the action method.
You can read more about it here in this answer.
Lot of the answers worked in either of the browsers, chrome or ie but not all.
This worked in all -
<input type="button" value="Cancel" onclick="location.href='#Url.Action("Index","Home")';"/>
This is my button HTML:
<button type="button"
class="btn btn-inverse"
id="cancel"
onclick="window.history.back()">
<i class="icon-remove icon-large"></i>
<br />#Localization.Cancel
</button>
Then to customize the onclick attribute in some views I do this:
<script>
$(document).ready(function ()
{
$("#cancel").
attr("onClick",
"document.location.href='#Html.Raw(Url.Action("Index", "Standard",
new { ManualId = Model.ManualId, ChapterId = Model.ChapterId }))'");
});
</script>
Or a styled submit button:
<input type="submit" value="Save Form" name="Save" class="submit-button btn-form" />
Then Javascript for cancel button:
<input type="button" onclick="document.location.href('Home/Index')" value="Cancel" class="cancel-button btn-form" />
// Note: This avoids any of the validation that may happen in the model that
// normally gets triggered with a submit
So with Shyju's appraoch, you use the built in MVC ActionLink helper. Doing this, you'll need to have any images or icons done through css. However, this is much more cachable, especially if you use base64 strings for your images in css.
I like Adauto's approach because it gives you much more control of the markup. MVC Html Helpers are nice, but they still seem to have their heads in the WebForms mindset of "don't worry about it, we'll take care of it for you".
The one thing I would add is Url.Content.
<img src="#Url.Content("~/Content/css/img/btn-submit.png" class="btn-form" />
It's never really a good idea to make your views have to know the location of content relative to it's location.
<a href="/Auction/[ActionName]">
<input type="image" src="#Url.Content("~/Content/css/img/btn-cancel.png")" class="btn-form" />
</a>
if you want to preserve its look as a button, you could do something like this:
<a href="/Auction/[ActionName]">
<input type="button" value="Cancel">
</a>
where [ActionName] is the name of the action that will return your desired view.
<img src="../../Content/css/img/btn-submit.png" class="btn-form" />
I ended up making a helper so I could reuse the cancel button. I added a js confirm in case people click the cancel button by accident after filling in the form.
#helper FormCancelButton(string cancelUrl)
{
<button type="button" class="btn" onclick="if (confirm('Cancel changes?')) location.href = '#cancelUrl';">Cancel</button>
}
I then call it like so:
#FormCancelButton(Url.Action("Index", "User" ))
If you are really keen you could try and detect the dirty state of the form too and only show the confirm dialog if the form had been changed.
<asp:Button runat="server" class="btn btn-danger"
CausesValidation="false" onclick="Cancel_Click" Text="Cancel"/>
protected void Cancel_Click(object sender, EventArgs e)
{
Response.Redirect("Test.aspx");
}