Hidden field "ufprt" being added to Razor Umbraco Form - Why? - ajax

I have got a form (below) that is posted to an umbraco surface controller.
#using (Html.BeginUmbracoForm("AddToBasket", "Basket"))
{
<h1>#Model.productSelectionModel.Product.Title - #Model.productSelectionModel.Product.Price.ToString("C")</h1>
<ul>
#foreach (var productOption in Model.productSelectionModel.ProductOptions)
{
<li>#productOption.Option.Title</li>
#Html.DropDownList(productOption.Option.Id.ToString(), productOption.ValuesInOptions.ToSelectList(f => f.OptionValue.OptionValue1,
f => f.Id.ToString(),
"Select"));
}
</ul>
<input type="submit" value="Add To Basket">
}
When I look at the HTML rendered for this form it seems to have added a hidden field called ufprt. Does any one know what this is? Why is it being added, I'm not using it any where ( I don't think I am anyway)
Any ideas?
<input name='ufprt' type='hidden' value='6C01896EF3D5F430F9ED041DD2B0D31F89FA969A085C6F4FDEC3C9D4B906846E7AA80041CEA12573E9F58C1740893B770AAE3319FAA8FA35C89A54D301CFE31B85ADC0D3D9506D208DB068D1257C5F0D5F1B3B90FD59A5C2938EED0A2EB1168AD4573CD5D043D47A8F1AA789E988CC614686B89BE57D35DA8EAAA110044C393F' />

It is to route the form to the correct controller/action method (Umbraco has the ability to route forms via that input value rather than the typical MVC approach of using the URL). I believe this is particular to surface controllers (i.e., it wouldn't apply to a normal controller, API controller, or RenderMvcController).
It is not a CSRF token as another answer indicates. If it were, it would likely have a name of "__RequestVerificationToken" as indicated here: http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-%28csrf%29-attacks
EDIT: This information has been added here: https://github.com/kgiszewski/LearnUmbraco7/blob/a97e85e5ad17e2ba9fc463f02c76885911046b57/Chapter%2006%20-%20Surface%2C%20WebAPI%20and%20RenderMVC%20Controllers/02%20-%20Surface%20Controllers.md#special-routing

Related

Pass data from Thymeleaf template to springboot controller

I have simple web application written using Springboot and Thymeleaf templates. Report controller receives the data from form and builds the TestPlanReportResponse object which is added as model attribute like this:
#PostMapping("/report")
public String homeSubmit(#ModelAttribute HomeFormInput homeFormInput, Model model, Errors errors) {
final TestPlanReportResponse response = new TestPlanReportResponse(homeFormInput);
model.addAttribute("allData", response);
return "charts";
}
I can work with that data in "charts" thymeleaf template and show the data I need, but I need to send exactly the same object back to controller when button is clicked, but i getting TestPlanReportResponse
object as parameter with nulls set.
#PostMapping("/report/send")
public String sendReport(#ModelAttribute TestPlanReportResponse reportData, Model model) {
//reportData contains just nulls
}
Here is how my button is set in charts template:
<form action="#" th:action="#{/report/send}" th:object="${allData}" method="post">
<button type="submit">Send the report</button>
</form>
So my question is how to send the object back from thymeleaf template? Should i create a hidden input and put there the "allData" object just to send it back? It looks for me like dirty hack. What would be the appropriate way to pass data back? I want to have this app stateless so don't to store the data on a server side.
When I used to work with Spring and Thymeleaf and form, we had the same issue, passing the data back and forth between a form, the template, and different controllers.
And what you suggest is what we did, we used hidden input as dirty as it may look,it was the standard suggested answer, we did not find anything better.
You need to create an input, with a type a value and link it to a field, like this:
<form action="#" th:action="#{/report/send}" th:object="${allData}" method="post">
<input type="hidden" th:value="*{allDataValue1}" th:field="*{allDataField1}" />
//Do this for all your attributes/values that you wish to pass to the controller
<button class="btn btn-info btn-lg btn-block" type="submit">Send the report</button>
</form>
Though, i found this answer, you can try looking into this thread

Model binding on POST with query string AND form parameters

What is the defined behavior for form binding in ASP.NET/MVC if you POST a form and its action has query parameters and you have form data?
For example:
<form action="my/action?foo=1" method="post">
<input type="hidden" name="bar" value="2">
</form>
If such a form is submitted should the controller get both foo and bar or only one of them?
The controller will get both values. The default model binder will try to find matches for the parameters from both the URI (either query string or route parameters) or the body (and forms data is supported out-of-the-box).
Note, you can see this is supported by Html.BeginForm helper, you do so through routeValues:
#Html.BeginForm("ActionName", "ControllerName", new { foo = "1" })
It essentially generates the same html as your form tag, but wanted to post for those who find this question and want to know how to pass additional values that are not part of the form using the BeginForm helper.
I think it should be able to get both. In this case, I would create a ViewModel that contains two string or int properties, one named 'foo' and the other named' bar' and have your ActionResult accept the ViewModel. You should see both values come in.

ASP MVC 3 is it possible to identify the <input> id in the controller [post] method?

I'm using a so as to edit an object, with an <input type="submit"> for validation
I've also another input, type="button" with an onclick event for the cancel button (with a redirect). However, this use a JS call, which I'd like to avoid.
I'd rather prefer to process the validation or cancel choice within the controller, so as to be NoScript compliant.
So is it possible to retrieve, within the controller post method, the id of the <input> that was clicked in the <form>?
Thanks
You can set the name of your
<input type="submit" name="submitButton" />
Then in your controller:
if(Request["submitButton"] != null) {
// ...
}
I'm not sure if I understand you, but if your cancel button does a redirect, it should end in a GET, and your submit button does a POST, that's how you should difference both request.
Check the [HttpPost] attribute in controller action methods.

How can I use multiple ajax forms with AntiForgery validation on the same MVC3 page?

When we have more than one possible form to post to the controller on the same cshtml page,
the Antiforgery validation does not work. We went through the MVC3 code and we found the problem is in this part of the code:
if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) {
// error: form token does not match cookie token
throw CreateValidationException();
}
The cshtml that we have is something like this:
#using (#Ajax.BeginForm()) {
#Html.AntiForgeryToken()
<input type="submit" class="buttonBlue" value="form1" />
}
#using (#Ajax.BeginForm()) {
#Html.AntiForgeryToken()
<input type="submit" class="buttonBlue" value="form2" />
}
Can you help me to fix this issue? We found that after removing one of the antiforgery tokens eveyrthing seems to work as expected.
We tried setting the machine key for the antiforgery and it didn't work either.
Regards.
In order to use the AntiForgeryToken multiple times, I do the following. First, at the top of my view, I add the following line:
ViewBag.__RequestVerificationToken = #Html.AntiForgeryToken().ToString();
Then, in each form where I need the token, I add the following:
#Html.Raw(ViewBag.__RequestVerificationToken)

Passing values between View and Controller in MVC 2

I'm constantly confused about how to pass values between Views and Controllers in MVC. I know I can set ViewData in the Controller and use that in the View, but what about the other way around?
What I have found is I can use a hidden field and then access it through Request.Form["name"] like this:
<% using (Html.BeginForm("Upload", "Customers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<br />
<input id="currentDir" type="hidden" name="currentDir" value="" />
<input type="file" name="fileTextbox" id="fileTextbox" />
<br />
<br />
<input type="submit" value="Send" />
<% } %>
What complicates it even more is that the value originally comes from a jquery script, so that's why the input field was the only way I could think of. But it still feels wrong... Maybe it isn't but I'd basically like to know if there are other more "proper" established ways to pass values between the View and Controller (both ways). Should one use querystrings instead? If so, how would they look in the html.beginform htmlhelper?
Also, what I'm trying to do here is enable upload possibilities for my application. And I'm trying to make the whole application as "Ajaxy" as possible. But this form will make a complete post. Is there another way to do this and not have to reload the entire page for this upload?
Let's ignore the "AJAX-y" aspects for a moment (because that's a different issue) and just look at passing data between views and controllers. I would first recommend that you check out the NerdDinner Tutorial which provides some good insights into how MVC works and how you use some of the features of MVC.
To address your specific question of how data is passed from View to Controller and back, there are a few ways to do this. However, the one that tends to make sense to most people is the idea of using strongly-typed views.
Let's say you have a model called Person. For now, don't worry about how we store Person data - we just have a Person class in the Models folder inside your MVC project.
public class Person {
public string FirstName;
public string LastName;
public Person() {
FirstName = "John";
LastName = "Doe";
}
}
When we want to display data about Person in a View, we make a request to a specific controller. In this case (and for clarity) we'll call this controller the MainController. This will go in the Controllers folder and will be called MainController. Let's call the Action (an action is really just a specialized method) we want to get data from Index. Due to how ASP.NET MVC routing works, the path to our server will be: http://localhost/Main/Index. Notice the Controller (minus the "Controller" name), and the Action make up the path. (The first part is your server name, of course.)
Let's look at your controller - I'm going to keep it very simple for now:
public class MainController : Controller {
public ActionResult Index() {
Person person = new Person();
return View(person);
}
}
What we have going on inside the Index Action is that it is returning a View (which, by default, has the same name as the Action) and a model to correspond with that view. Now, we have to create our view.
The important part here is that you want to strongly-type the model that is being returned in the controller to your view. You do that with this line (which is first in your aspx file).
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewUserControl<Project.Namespace.Person>" %>
Notice the "Inherits" attribute and notice that your Person model makes up that attribute.
Now, just code the rest of your view as normal. Let's say we want to display the current Person name, and allow someone to change the name. The page would look like this (I'm not making this pretty):
<% using (Html.BeginForm()) { %>
<%: Html.LabelFor(model => model.FirstName) %>
<%: Html.TextBoxFor(model => model.FirstName) %>
<%: Html.LabelFor(model => model.LastName) %>
<%: Html.TextBoxFor(model => model.LastName) %>
<input type="submit" value="Submit" name="submitButton" />
<% } %>
This is the important part about getting data back and forth between Controllers and Views. What we are doing here is that we are taking your strongly-typed view (which is typed with the Person class) and using helper methods (like LabelFor and TextBoxFor) to tie the model together with its data and, ultimately, together with the actions contained in the controller (which we have to finish developing here in one moment).
So, you can now see the data. But, if a user changes the name and clicks submit - we want the page to display the new name. This means we need to add one more action to MainController - the one that receives the data.
[HttpPost]
public ActionResult Index(Person person) {
// Do whatever you want with the Person model. Update a database, or whatever.
return View(person);
}
This action looks very similar to the other action we just developed. However, this one takes a person object (from the form that is being submitted) and it gives the controller an opportunity to do whatever needs to be done with that object. Once this is done, you can choose to redirect to a different page, redisplay the page (useful if there are errors), or do any number of other things.
Again, this is ALL covered (and much more) in the NerdDinner Tutorial. I highly recommend you read and follow through that.
As for the AJAX-y aspects you discussed, the premise is still the same (although there is a little bit of JavaScript/jQuery work that goes on in there). I won't go into it now, but the basics are also covered in the NerdDinner tutorial.
I hope this gets you started. I remember being a bit confused too when I first started working with web technologies, so I hope this helps you out!

Resources