Adding AntiForgeryToken to non-Ajax Form Submit - c#

I found plenty of examples that demonstrate how to add an AntiForgeryToken to the Ajax call for POST submit method. My need, as the title suggests, is to submit a form NOT via the ajax call. Instead, I'm simply using jQuery submit() function.
What I have in my razor view file is as follows (Note: I'm using html string literal because this particular DOM needs to be dynamically attached to a separate element at a later point):
var html =
"<form id='exportPdfForm' action='" + exportUrl + "' method='post'>" +
"<input type='hidden' id='exportContent'>" +
"<input type='hidden' id='__RequestVerificationToken' value='#Html.AntiForgeryToken()'>" +
"</form>";
And, obviously, I'm using the following jQuery to submit this form:
$("#exportPdfForm").submit();
Also, using the DOM Explorer I can see the AntiForgeryToken value is properly in place:
However, when I actually submit the form, I still run into the The required anti-forgery form field "__RequestVerificationToken" is not present error. I checked out several other Q&A's but can't seem to find anything that might shed some light on my problem.
Am I missing something obvious or doing something wrong here?
EDIT (Solution)
Assigning the __RequestVerificationToken to the name attribute will fix it:
<input type='hidden' name='__RequestVerificationToken' value='...'>

This one turns out to be one of those "How did I miss that...?!" moments. While the above approach is perfectly legitimate, the only problem is that the __RequestVerificationToken has to belong to a name attribute instead of to an id as in my initial example. I tried posting my form with the fix and the problem is now gone.
Obviously this wouldn't have been an issue in the first place if I could just use the <% Html.AntiForgeryToken(); %> expression, but this particular case required an unconventional approach for the reason I stated in my initial post. So, I guess this is something to look out for!

Related

Selenium Automation unable to enter username in Way2Automation website

I am trying to do registration for this site
Registration page is inside a popup page.
HTML Code:
<fieldset>
<label>Username:</label>
<input name="username" required="" type="text"/>
</fieldset>
When I try to find the element using below tried code, element is not getting find.
driver.FindElement(By.XPath(".//*[#id='load_form']/fieldset[1]/input")).SendKeys("Kal");
I have also tried this with using CssSelector, but facing the same issue.
driver.FindElement(By.CssSelector("div#load_box form#load_form input[name=username]")).SendKeys("kal");
When I execute above code, I have got an error like element not visible
Can anyone help me on this issue?
Try this below code using xpath locator
driver.FindElement(By.XPath("//input[#name='name']")).SendKeys("Kal");
Explanation of xpath:- Use name attribute of <input> tag.
Suggesstion:- Instead of using absolute xpath, use relative xpath.
Note:- Before reach to this web-element provide some few seconds of wait, so your driver may able to find the web-element. So, you will not get an error like element not visible
Use below xpath:
//*[#id='load_form']/fieldset[6]/input[#name='username']
that site has 2 forms with the id load_form so you're getting the first one which isn't visible since it's the login form. You want the second one which is the register form.
you can use a selector to grab one of the fields that exists on the registration page and then move up to it's parent form and get all descendants that are fieldsets to fill out.
Here is the xpath you can use to pass the text "Dev" into the field labelled with "Name".
driver.findElement(By.xpath("//div[#class='fancybox-overlay fancybox-overlay-fixed']//form[#id='load_form']/fieldset/input[#name='name']")).sendKeys("Dev");
Let me know if this answers your question.
The problem is that there are two username INPUT fields. The way I typically handle this is to find a parent of the element that I want that has an ID or something unique that will distinguish the two elements. In this case, you can use a simple CSS selector,
#load_box input[name='username']
Note the load_box ID that distinguishes the two INPUTs.
Ajax popup on way2automation site is a tricky one because if you look for the username field by name By.name("username"), you will end up with 2 elements - one for username from signup popup, one from singin popup. To avoid this you have to explicity mention the correct element. This can be done via the following code:
webDriver.get("http://way2automation.com/way2auto_jquery/index.php");
WebDriverWait wait = new WebDriverWait(webDriver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a[href='#login'"))).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".ajaxlogin input[name='username']"))).sendKeys("my_username");
As you can see in the code I am using class of the login popup - .ajaxlogin. I have used Java, but the concept is the same - you have to refer to the username element via css selector with popup class included: By.cssSelector(".ajaxlogin input[name='username']")

Fill a form with WatiN in C#

that's my first question, i hope i'm doing everything correctly.
Anyway, i have a weird issue. I basically have this HTML input which i want to fill with WatiN :
<input name="edit[id]" class="form-text required" id="edit-id" type="text" size="60" maxlength="64" value="">
That's my code in C# :
IE ie = new IE();
ie.GoTo(urlhere, just too long);
ie.TextField(Find.ByName("edit[id]")).TypeText("Text");
It's not working and it returns this exception :
Ulteriori informazioni: Could not find INPUT (hidden) or INPUT (password) or INPUT (text) or INPUT (textarea) or TEXTAREA element tag matching criteria: Attribute 'name' equals 'edit[id]' at about:blank
I'm not sure why it gives "at about:blank" honestly. I tried with a random google page and the code it's working. If i put a random name instead of the correct one, it gives me the same exception but with the correct url instead of "about:blank".
Note : I'm trying to fill a form.
Thanks for your help!
Not sure what web page are you using but from the information you posted it looks like that form might be "somewhere else" (another div, frame, etc.) To be able to find the EXACT entry you should press F12 (IE) or CTRL+SHIFT+I (Chrome) and traverse the HTML web page to find the exact portion were the input lies and you will find the exact spot.
The code you posted is perfectly fine, there's nothing else you need to do to make it work. If you need more help, posting the webpage you are trying to use will go a long way (if possible, of course).

In a C# MVC app is it possible to submit variables from a web page in controls that did not change?

I have a C# MVC application and a <form> in my page.cshtml file. In that form I have <input type="text" ... /> elements. If I submit this form I only get the values in Response.Params or Response.Form from the inputs where I changed the value manually (i.e. Entered the text box then typed something).
If I change the value with jQuery, $('#myInput').val('some value'); this does not count as a change in the input's value and I do not get myInput's value when I submit the form.
Is there any way to make sure all inputs are submitted? If not then is there a good workaround for this, maybe in some event that occurs before my model gets bound? I need to know all the input values from the form when submitted whether they changed or not.
Some additional info:
The form and other values are getting submitted correctly and I am receiving my model when the POST action is called in my controller.
The real issue is when my model is being bound. It is being created and bound with all values except the one not being submitted because it is not in the Request.Params collection.
I have only ever seen this behaviour when a field is disabled. Due to this, I commonly have a javascript function that handles the form submission and re-enables them on submit, this way the correct values get sent to the server.
Something like this does the trick for me (NOTE: I am using JQuery):
$(document).ready() {
$("#ButtonSubmit").click(SubmitForm);
}
function SubmitForm(e) {
e.preventDefault();
//ensure fields are enabled, this example does text and checkbox types
$("[type='text']").attr("disabled", false);
$("[type='checkbox']").attr("disabled", false);
//submit the form
document.forms[0].submit();
}
I am unaware of any easier way to do this, it would be nice if you could 'flag' something that instructs all fields to be submitted. But I don't know if this exists, maybe somebody else can offer a better solution.
EDIT: It appears that disabled fields not submitting is just the nature of HTML, and is not something that is tied to MVC.
It seems that if you make the fields readonly instead of disabled then the values will still submit. However, with this approach you lose the 'disabled' styling. The exception to this rule is select control, it seems this will not submit under readonly either. More information on this can be in this question
Try using the razor helper to build the form tag.
#using(Html.BeginForm()) {
..
// make sure this is a submit button
<input type="submit" value="Save" />
}
In your controller action post method make sure you decorate it [HttpPost].
e.g.,
[HttpPost]
public ActionResult Edit(YourModel model) {
}

Remove browser autocompletion in MVC

I am currently trying to remove the form autocompletion done by the user's browser which can cause some critical behavior since it fills the password field. I have already added the autocompletion attribute to all of my textbox fields but when I try with firefox it stills load my current login information into the fields.
Does anyone know how to resolve this issue?
EDIT: Since it's not clear, I have already added the aucompletion attribute with the value set to "off".
There is an autocomplete=off property in html.
It is used in the top right search box on this very page, inspect the html you'll see:
<input autocomplete=​"off" name=​"q" class=​"textbox" placeholder=​"search" ..... />
See this MDN article: https://developer.mozilla.org/en/How_to_Turn_Off_Form_Autocompletion
In MVC you would implement this at the form or for a textbox like so:
Html.BeginForm(
action, controller, FormMethod.Post, new {autocomplete="off"})
OR
Html.TextBoxFor(model => model.EmployerNumber, new {autocomplete="off"})
If you check HERE, setting autocomplete="off" on the form should do the trick.
The HTML5 have a add-on syntax for form/input elements, it is called autocomplete="off".
See http://www.w3schools.com/html5/att_form_autocomplete.asp
You can randomize id and name attributes of your textboxes - this will make browser autocomplete functions not working.
My implementation
In view:
<%
var guidString = Guid.NewGuid().ToString();
%>
<%=Html.TextBox(guidString, String.Empty)%>
<%=Html.Hidden("NameGuid", guidString) %>
in Controller:
string userName = Request[model.NameGuid];
...

Pass data to server side from Javascript code

I'm trying to send data from client-side to server-side (asp.net c#), if you really want to know, I want to send the window.name property.
First I thought about having a asp:HiddenField and on the OnSubmit event have some JS write the value in the hidden field. The only problem is that I can access the hidden field value (according to this) only from PreLoad event to PreRenderComplete event. The project that I'm working on has a lot of code in the OnInit event, and unfortunately I cannot move it and I need to use the window.name value here.
The other ideas that I have is to add a custom HTTP Header windowId or on the OnSubmit event have a JS that appends a parameter to the document.location.href.
I managed to write to the header from JS with the XMLHttpRequest setRequestHeader, but, maybe I did something wrong in my implementation, this generates 2 requests, the first one is the normal, expected one(clicking a button/link ...) and the second is from the XMLHttpRequest. I find this behavior very unnatural. Do you have any sugestions? (see code snippet below). I do not what to use AJAX.
var oReq = new window.XMLHttpRequest;
oReq.open('POST', document.location, false);
oReq.setRequestHeader("windowId", window.name);
oReq.send(null);
For the OnSubmit hook idea, i haven't spent to much time on it, but i think I have to append the # character before i append my windowId parameter with it's value, so that the page doesn't reload. I might be wrong about this. Any way, I have to remove this from the URL after I take the value, so that the user doesn't see the nasty URL. Do you have any sugestions?
Ok so what are your ideas?
Thank you for reading all my blabbering, and thank you, in advance, for you answers.
I would recommend the <asp:HiddenField /> (e.g., <asp:HiddenField ID="hfWindowName" runat="server" />. In OnInit you can still access its value by using Request.Form:
string windowName = Request.Form(hfWindowName.UniqueID);

Categories