POST URL is missing handler query string in Razor Page - asp.net

I'm having an issue where my form submission url does not have a query string which points to the handler in the Code Behind. As a result I'm getting a 400 (bad request) error.
The request URL looks like this:
http://localhost:60900/EventRename
When it should look like this:
http://localhost:60900/EventRename?handler=RenameEvent
Here's the .cshtml
<form asp-page-handler="RenameEvent" method="post">
<div class="form-group">
<label asp-for="RenameDataSource"></label>
#Html.DropDownListFor(x => x.RenameDataSource, Model.DataSources, "-- select data source --")
</div>
<div class="form-group">
<label asp-for="RenameTempEvent"></label>
#Html.DropDownListFor(x => x.RenameTempEvent, Model.RenameTempEvents, "-- select event type --")
</div>
<div class="form-group">
<label asp-for="NewName"></label>
#Html.DropDownListFor(x => x.NewName, Model.EventTypes, "-- select event type --")
</div>
<div class="form-group">
<button type="submit">Start Renaming</button>
</div>
</form>
It might be related, but I've also noticed that the form data is missing the '__RequestVerificationToken', which should be included by default in Razor pages?
To clarify, I'm not expecting to see the data from the form in the URL. I'm expecting to see a handler reference so the Razor Code Behind knows which method to run when the form is submitted. See this section: https://learn.microsoft.com/en-us/aspnet/core/razor-pages/#multiple-handlers-per-page
the URL path that submits to OnPostJoinListAsync is http://localhost:5000/Customers/CreateFATH?handler=JoinList

#using (Html.BeginForm(ActionName, ControllerName, new { handler = "value of your handler" }, FormMethod.Post))
Now you can submit the form it will give you the value for the same.

your form method is post try to use get if you want to see the data string in url.
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data

Related

TempData Dictionary is null after Redirect to page

So I have this issue that I am not unable to solve the way I think it's supposed to be solved.
I have an ASP.NET Core 2.1 Razor pages project. The code is pasted below and my problem is the following:
On the index page, I have a search form. The city name I enter in the search form gets used in the SearchResults OnPost method.
The OnPost redirects to OnGet which retrieves some results from the database based on the city passed in from the search form. From my understanding, TempData should be able to retain the value for the city passed in from the form, however, whenever I try to read TempData["CityFromForm"] in the OnGet method, the TempData dictionary is empty, even though that in the OnPost method I used the TempData.Keep method.
My current solution for this is using in memory cache to store the city value and pass it to the method that fetches the data from the database, but I would like to know why the TempData approach is not working.
On the index page on that project, there is a search from in which I enter a city for which I want to search the data, like so:
#model SearchDataViewModel
<form asp-page="/Search/SearchResults" method="post" class="col s6">
<div class="row">
<div class="input-field col s12">
<input placeholder="Please enter a city" type="text" name="City" class="validate autocomplete" id="autocomplete-input" autocomplete="off" />
<label for="City">City</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="StartDate" name="StartDate" type="text" class="datepicker datepicker-calendar-container">
<label for="StartDate">Start date</label>
</div>
<div class="input-field col s6">
<input id="EndDate" name="EndDate" class="datepicker datepicker-calendar-container" />
<label for="EndDate">End date</label>
</div>
</div>
<input type="submit" hidden />
</form>
What matters in that form is the city. That form gets sent to the SearchResults razor page.
SearchResults.cshtml.cs
public IActionResult OnPost()
{
// Cache search form values to persist between post-redirect-get.
var cacheEntry = Request.Form["City"];
_cache.Set<string>("City", cacheEntry);
TempData["CityFromFrom"] = Request.Form["City"].ToString();
TempData.Keep("CityFromForm");
return RedirectToPage();
}
// TODO: Find a better way to persist data between onPost and OnGet
public async Task OnGet(string city)
{
City = _cache.Get<string>("City");
var temp = TempData["CityFromForm"];
// Here I'd like to pass the TempData["CityFromForm"] but it's null.
await GetSearchResults(City); // this method just gets data from the database
}
TempData keys are prefixed by "TempDataProperty-". So if you have a key named "City", you access it via TempData["TempDataProperty-City"].
See https://www.learnrazorpages.com/razor-pages/tempdata
You also have a typo in the line where you assign the tempdata value: TempData["CityFromFrom"] should be TempData["CityFromForm"], I suspect.
So here is what I came up with, basically I get a city string from the search form. In the OnPost method I redirect to page where I add a route value which OnGet method can use.
In SearchResults.cshtml I added a #page "{city?}"
The url ends up looking like: https://localhost:44302/Search/SearchResults?searchCity={city}
In SearchResults.cshtml.cs
public async Task OnGet()
{
City = HttpContext.Request.Query["searchCity"];
PetGuardians = await GetSearchResults(City);
}
public IActionResult OnPost(string city)
{
return RedirectToPage(new { searchCity = city });
}

Get Label value in MVC 2

I want to print some text on dropDown change. then on submit save the label text to data base. Currently printing value to the label works fine but on submit i'm not receiving the lable text.
$(document).ready(function () {
$('#StockID').change(function () {
// ajax call
function successFunc(data, status) {
$("#lblTotal").text("Stock Value: " + data.Result);
}
}
})
});
<div class="editor-field">
<%: Html.DropDownListFor(x => x.StockID, new SelectList(Model.lstStock, "StockID", "Description"), "-- Please Select a Stock --")%>
<%: Html.ValidationMessageFor(model => model.StockID)%>
</div>
<div id="clslbl">
<br />
<label id="lblTotal"></label>
</div>
Controller:
if (ModelState.IsValid)
{// TODO: Add insert logic here
string a = Request.Form["lblTotal"]; // here i'm not getting the label text
return RedirectToAction("Index");
}
Labels are not posted back to the server same is the case if you use Html.DisplayFor(...). As you change the drop-down value save it in a hidden fields as well. You will be able to access it as part of Request on the server. Only input fields are posted back to the server. So <input type="hidden" .../> should do the job for you.

Spring MCV 3 showErrors doesn't display anything

I try to validate a simple form. The validation is well executed but the result page doesn't display the errors.
I use velocity to render the page.
I've used as example the PetClinic project from spring website.
Here is my controller when I hit the "post form" button:
#Controller
#RequestMapping("/subscription")
public class SubscriptionController {
#RequestMapping(value = "/newCustomer", method = RequestMethod.POST)
public String processSubmit(#ModelAttribute Customer customer, BindingResult result, SessionStatus status) {
new CustomerValidator().validate(customer, result);
if (result.hasErrors()) {
return "subscription";
}
else {
status.setComplete();
return "redirect:/admin";
}
}
}
When I go in debug, I see the errors. I'm successfully redirected on the subscription page but the errors are not displayed.
My webpage (simplified):
...
#springBind("customer")
#springShowErrors("<br/>" "")
<form class="form-horizontal" method="post" action="#springUrl("/subscription/newCustomer/")">
....
<!-- Button -->
<div class="controls">
<button class="btn btn-primary">#springMessage("website.subscription.signup")</button>
</div>
</form>
...
if you need anything else, don't hesitate to tell me. Thanks for your help! I'm stuck on this since several days.
EDIT :
I finally found the error. It was with the springBind tag. I didn't well understand that you need to bind the field to show the associated error. Here is the fixed code for one field for twitter bootstrap framework.
#springBind("customer.name")
<div class="control-group #if(${status.error})error#end">
<!-- Prepended text-->
<label class="control-label">#springMessage("website.subscription.name")</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i></span>
<input class="input-xlarge"
placeholder="John Doe" id="name" name="name" type="text">
</div>
<p class="help-block">
#springShowErrors("<br/>" "")
</p>
</div>
</div>
springShowErrors(...) will show all the errors associated with the field name of the POJO customer.

ASP.Net MVC 4 & Unobtrusive Validation Summary

I am trying to display a summary error message on a form as well as property level errors.
The property errors get rendered using html.validationmessagefor(model =>...) which works fine.
But when there is one or more validation errors, I want html.ValidationSummary(true) to display the message "Your form is missing some details - see below".
There also might be some server side validation which will occur post submit and will be added with ModelState.AddError.
How can I get a class level dataattribute (presumably using [AttributeUsage(AttributeTargets.Class)]) to display in the summary validation using unobtrusive validation?
Is this what you are looking for:
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
#Html.ValidationSummary("Errors:")
<div>
#Html.EditorFor(model => model.PathToExcel)
#Html.ValidationMessageFor(model => model.PathToExcel)
</div>
<div>
<input type="submit" value="Load" />
</div>
}
this uses 2 ValidationSummary's, one to fill the ValidationMessageFor-fields and one to use a Summary. Summary only works after Submitting.

Model binding in Razor View (ASP.NET MVC3) at runtime

My Index method renders a Strongly Typed View of type (InitDetails), auto generated code looks like the following:
#ModelType BookingDeamon.InitDetails
#Using Html.BeginForm()
#Html.ValidationSummary(True)
#<fieldset>
<legend>Reservation</legend>
<div class="editor-label">
#Html.LabelFor(Function(model) model.Pickup)
</div>
<div class="editor-field">
#Html.EditorFor(Function(model) model.Pickup)
#Html.ValidationMessageFor(Function(model) model.Pickup)
</div>
<p>
<input type="submit" value="Create" onclick="SubmitMe()" />
</p>
</fieldset>
End Using
On the above form, I want to display a select list box, as i'll be controlling this select list via JQuery to load different contents depending on different things.
I want to be able to deliver the value of that select list box as Pickup value.
when I try to do the following:
#Html.DropDownListFor(Function(model) model.Pickup)
I receive the following error:
Overload resolution failed because no accessible 'DropDownListFor' accepts this number of argument
Is it possible when user clicks on the submit button, instead of taking Pickup (textbox) value to the controller; it takes the value from the dropdownlist box and submit it to the controller?
try like this
#Html.DropDownListFor(ModelType=>Model.Pickup, (IEnumerable<SelectListItem>)ViewData["Pickup"],"--Select--")
in your controller
var Pickup= GetPickupList();
var PickupList= new SelectList(Pickup, "value", "Text", Pickup.DefaultSelectedValueIfAnyNeeded);
ViewData["Pickup"] = PickupList
write a function GetPickupList()
that returns a list of Pickup values.

Resources