values are reset to zero - c#

I'm doing insert via post, but my class is getting zero values.
The values of the inputs are passed via variable and are displayed correctly, but at the moment of action via post are coming with zero values.
The most interesting thing is if you type inside the input, then the values come correctly.
<form method="post">
<div class="col-sm-3">
<label>SALDO</label>
<div style="border:1px solid #bbb9b9; border-radius:3px;"></div>
<br />
<div class="form-group">
<label asp-for="Caixas.ValorFinalDinheiro" class="control-label"></label>
<input asp-for="Caixas.ValorFinalDinheiro" name="Caixas.ValorFinalDinheiro" id="Caixas.ValorFinalDinheiro" class="form-control finalFundo" disabled="disabled" />
</div>
<div class="form-group">
<label asp-for="Caixas.ValorFinalCheque" class="control-label"></label>
<input asp-for="Caixas.ValorFinalCheque" class="form-control finalFundo" disabled="disabled"/>
</div>
<div class="form-group">
<label asp-for="Caixas.ValorFinalBoleto" class="control-label"></label>
<input asp-for="Caixas.ValorFinalBoleto" class="form-control finalFundo" disabled="disabled" />
</div>
<div class="form-group">
<label asp-for="Caixas.ValorFinalCartao" class="control-label"></label>
<input asp-for="Caixas.ValorFinalCartao" class="form-control finalFundo" disabled="disabled" />
</div>
<div class="form-group">
<label asp-for="Caixas.ValorFinalDeposito" class="control-label"></label>
<input asp-for="Caixas.ValorFinalDeposito" class="form-control finalFundo" disabled="disabled" />
</div>
<div class="form-group">
<label asp-for="Caixas.ValorFinal" class="control-label"></label>
<input asp-for="Caixas.ValorFinal" class="form-control" style="background-color:#9FF781" />
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<input type="submit" value="Confirmar o Fechamento do Caixa" class="btn btn-primary btn-sm" />
<a asp-page="Index" class="btn btn-success btn-sm">Retorna ao Caixa</a>
</div>
</div>
</form>
And the controller
[BindProperty]
public Caixas Caixas { get; set; }
public async Task<IActionResult> OnPostAsync()
{
var C = _context.Caixas.Find(Caixas.Id);
C.fechado = true;
C.DataFinal = DateTime.Now;
C.HoraFinal = DateTime.Now;
C.FuncionarioFechamentoId = _userManager.GetUserId(HttpContext.User);
C.ValorFinalDinheiro = Caixas.ValorFinalDinheiro;
C.ValorFinalCheque = Caixas.ValorFinalCheque;
C.ValorFinalBoleto = Caixas.ValorFinalBoleto;
C.ValorFinalCartao = Caixas.ValorFinalCartao;
C.ValorFinalDeposito = Caixas.ValorFinalDeposito;
C.ValorFinal = Caixas.ValorFinal;
C.ValorSaida = Caixas.ValorSaida;
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}

In fact, all browsers should not submit the disabled inputs.
Following this
In this example, the INPUT element is disabled. Therefore, it cannot
receive user input nor will its value be submitted with the form.
<INPUT disabled name="fred" value="stone">
I don't know why you have a form like that. But to overcome this situation, you can add an <input type="hidden"> element with the same name and same value as the disabled input. And send the value in POST request.

Try to use, the Data Annotation "HttpPost" before your method. Like this:
[HttpPost]
public async Task<IActionResult> OnPostAsync()
{
...
}

Related

How do I get the userId to save in the database while submitting the form?

I'm a beginner and well i'm doing a form which is capable to send information to the database but I needed one more thing to be sent and it is the Id from the user who submit.
I'm using identity framework I didn't change at all the template code.
My Submit controller was done using scaffold.
Can you guys explain what am I doing wrong? I tried to search in every corner of internet but I didn't get the answer for my question maybe it's too obvious and didn't notice at all.
The code is right below.
.NET CORE VERSION 3.1
Form.cshtml
```
#page
#model AuthSystem.Areas.Identity.Pages.Form.FormModel
#{
ViewData["Title"] = "Form";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<center>
<h1>Form</h1>
<h4>Submit</h4>
</center>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post" class="row">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="row">
<div class="form-group">
<label asp-for="Submit.NrOperador" class="control-label"></label>
<input asp-for="Submit.NrOperador" class="form-control" />
<span asp-validation-for="Submit.NrOperador" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submit.Posto" class="control-label"></label>
<input asp-for="Submit.Posto" class="form-control" />
<span asp-validation-for="Submit.Posto" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submit.Maquina" class="control-label"></label>
<input asp-for="Submit.Maquina" class="form-control" />
<span asp-validation-for="Submit.Maquina" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="form-group">
<label type="time" asp-for="Submit.Hora" class="control-label"></label>
<input type="time" asp-for="Submit.Hora" class="form-control" />
<span asp-validation-for="Submit.Hora" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submit.Date" class="control-label"></label>
<input type="date" asp-for="Submit.Date" class="form-control" />
<span asp-validation-for="Submit.Date" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="form-group">
<label asp-for="Submit.Item122" class="control-label"></label>
<input asp-for="Submit.Item122" class="form-control" />
<span asp-validation-for="Submit.Item122" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submit.Item132" class="control-label"></label>
<input asp-for="Submit.Item132" class="form-control" />
<span asp-validation-for="Submit.Item132" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submit.Item212" class="control-label"></label>
<input asp-for="Submit.Item212" class="form-control" />
<span asp-validation-for="Submit.Item212" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submit.Caract"></label>
<br />
<input type="radio" value="Sim" asp-for="Submit.Caract" class="custom-radio" />
<a> Sim </a>
<br />
<input type="radio" value="Não" asp-for="Submit.Caract" class="custom-radio" />
<a> Não </a>
<span asp-validation-for="Submit.Caract" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Areas/Identity/Pages/Form/FormList">Back to List</a>
</div>
Form.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using AuthSystem.Models;
namespace AuthSystem.Areas.Identity.Pages.Form
{
public class FormModel : PageModel
{
private readonly AuthSystem.Models.FormContext _context;
public FormModel(AuthSystem.Models.FormContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Submit Submit { get; set; }
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Submit.Add(Submit);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
I'm not sure if I understood your issue. But I think you should using Sessions Collection to catch userId. I assume you have model with property UserId type of string after success login make Session["UserId"]
if (!ModelState.IsValid)
{
return Page();
}
model.UserId = Convert.ToString(Session["UserId"]);
Add it before _Context.SaveChanges()

razor pages - how to populate form fields from update model

The 'itemId' is transferred to the Update Page, however, form fields are empty. This is my first try to Update the model in Razor Pages. Any help is appreciated.
[BindProperty]
public MenuItemViewModel MenuItem { get; set; }
public void OnGet(int itemId)
{
var the_item = _menuItemService.GetById(itemId);
}
public IActionResult OnPost()
{
if (ModelState.IsValid)
{
var the_item = MenuItem.ToDomainModel();
_menuItemService.Update(the_item);
}
return Page();
}
cshtml:
<div class="container">
<form asp-page="UpdateMenuItem" method="POST">
<div class="form-group">
<label asp-for="#Model.MenuItem.Name">Name:</label>
<input type="text" asp-for="#Model.MenuItem.Name" class="form-control" placeholder="Enter name" />
<span asp-validation-for="#Model.MenuItem.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.MenuItem.ImageUrl">Image:</label>
<input type="text" asp-for="#Model.MenuItem.ImageUrl" class="form-control" placeholder="Enter image" />
<span asp-validation-for="#Model.MenuItem.ImageUrl" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.">Description:</label>
<input type="text" asp-for="#Model.MenuItem.Description" class="form-control" placeholder="Enter description" />
<span asp-validation-for="#Model.MenuItem.Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.MenuItem.Price">Price:</label>
<input type="text" asp-for="#Model.MenuItem.Price" class="form-control" placeholder="Enter price" />
<span asp-validation-for="#Model.MenuItem.Price" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-success">Update</button>
</form>
Try this:
public IActionResult OnGet(int itemId)
{
MenuItem = _menuItemService.GetById(itemId);
return Page();
}
It seems that you are using the 'asp-for' tag too many times and it creates an ambiguity when the Post method tries to find the model:
<label asp-for="#Model.MenuItem.Name">Name:</label>
<input type="text" asp-for="#Model.MenuItem.Name" class="form-control"
placeholder="Enter name" />
<span asp-validation-for="#Model.MenuItem.Name" class="text-danger"></span>
remove asp-for="#Model.MenuItem.Name" from the label and span. Only use it for the input fields like so:
<label>Name:</label>
<input type="text" asp-for="#Model.MenuItem.Name" class="form-control"
placeholder="Enter name" />
<span asp-validation-for="#Model.MenuItem.Name" class="text-danger"></span>
Only do this for the actual models you are binding. Do not use them for labels.
Let me know if that works out for you.

problem in getting id from query string in.net core in post and put request

when i issue get request i get id of type Guid from query string but when i click on the button or apply
post request i can not get id parameter. why is that and how to solve this problem?
this is my server side code.
public async Task<IActionResult> Edit([FromQuery(Name = "id")] Guid id, [FromForm] User user, [FromForm] IFormFile? file)
{
if (ModelState.IsValid)
{
try
{
using (var data = new MultipartFormDataContent())
{
data.Add(await user.ParseToStringContentAsync(), "user");
if (file is not null)
data.Add(new StreamContent(file.OpenReadStream()), "file", file.FileName);
using (var response = await client.PutAsync("UsersAPI/" + id, data))
{
if (response.StatusCode == HttpStatusCode.OK)
return RedirectToAction(nameof(Index));
else ModelState.AddModelError("", "Something went wrong");
}
}
}
catch (Exception ex)
{
await ex.LogAsync().ConfigureAwait(false);
}
}
return View(user);
}
this is my view for the edit action. when i click on the button eveything seems to be working but my id parameter is Guid.Empty
#model Models.Model.User
#{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>User</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
#*<label asp-for="User_ID" class="control-label"></label>*#
<input asp-for="User_ID" class="form-control" type="hidden" />
#*<span asp-validation-for="User_ID" class="text-danger"></span>*#
</div>
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
#*<div class="form-group">
<label asp-for="RegistrationDate" class="control-label"></label>
<input asp-for="RegistrationDate" class="form-control" />
<span asp-validation-for="RegistrationDate" class="text-danger"></span>
</div>*#
<div class="form-group">
<label asp-for="Image" class="control-label"></label>
<input type="file" name="file" class="custom-file" />
<span asp-validation-for="Image" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Yo can try to remove asp-action="Edit".When you use it,the request url will be changed to https://localhost:xxx/xxxController/Edit here is a working demo:
View:
<form enctype="multipart/form-data" method="post">
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
Controller:
[HttpGet]
public IActionResult Edit() {
return View();
}
[HttpPost]
public IActionResult Edit([FromQuery(Name = "id")]Guid id)
{
return View();
}
result:

Is is any way to show errors in the corresponding form?

I have an ASP.NET Core 3.1 Razor Pages application.
It is quite simple when it is only one form on a page, but how correctly show the errors when there are few forms?
Example:
/ManageUser.cshtml
<div>
<form method="post">
<div class="validation-summary-valid text-danger" asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="OldPassword"></label>
<input asp-for="OldPassword" class="form-control" />
</div>
<div class="form-group">
<label asp-for="NewPassword1"></label>
<input asp-for="NewPassword1" class="form-control" />
</div>
<div class="form-group">
<label asp-for="NewPassword2"></label>
<input asp-for="NewPassword2" class="form-control" />
</div>
<button type="submit" class="btn btn-primary" asp-page-handler="ChangePassword">Change password</button>
</form>
</div>
<!-- let's say it is the other "tab" -->
<div>
<form method="post">
<div class="validation-summary-valid text-danger" asp-validation-summary="All"></div>
<div class="form-group">
<label asp-for="ChangeEmail"></label>
<input asp-for="ChangeEmail" class="form-control" />
</div>
<button type="submit" class="btn btn-primary" asp-page-handler="ChangeEmail">Change email</button>
</form>
</div>
And, if on the backend side any error is found:
public async Task<IActionResult> OnPostChangeEmailAsync([FromService] UserManager<User> userManager)
{
//... skipped for brevity
ModelState.AddModelError("", "User not found or deleted");
return Page();
}
then this error is shown for both forms. Any way to show it for corresponding form only?
PS: Please do not propose to make the errors field-bound: it is not the case and the fields in the example is just for the simplicity.
Taking field validation as an example, you can try the following code.
View:
<div>
<form method="post">
<span class="text-danger">#Html.ValidationMessage("PasswordError")</span>
<div class="form-group">
<label asp-for="UserModel.OldPassword"></label>
<input asp-for="UserModel.OldPassword" class="form-control" />
<span asp-validation-for="UserModel.OldPassword" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="UserModel.NewPassword1"></label>
<input asp-for="UserModel.NewPassword1" class="form-control" />
<span asp-validation-for="UserModel.NewPassword1" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="UserModel.NewPassword2"></label>
<input asp-for="UserModel.NewPassword2" class="form-control" />
<span asp-validation-for="UserModel.NewPassword2" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary" asp-page-handler="ChangePassword">Change password</button>
</form>
</div>
<div>
<form method="post">
<span class="text-danger">#Html.ValidationMessage("EmailError")</span>
<div class="form-group">
<label asp-for="UserModel.ChangeEmail"></label>
<input asp-for="UserModel.ChangeEmail" class="form-control" />
<span asp-validation-for="UserModel.ChangeEmail" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary" asp-page-handler="ChangeEmail">Change email</button>
</form>
</div>
The backend side(you can remove the attributes):
public async Task<IActionResult> OnPostChangeEmailAsync(UserModel userModel)
{
if (!ModelState.IsValid)
{
ModelState.Remove("UserModel.OldPassword");
ModelState.Remove("UserModel.NewPassword1");
ModelState.Remove("UserModel.NewPassword2");
ModelState.AddModelError("EmailError", "User not found or deleted");
}
return Page();
}
public async Task<IActionResult> OnPostChangePassword(UserModel userModel)
{
if (!ModelState.IsValid)
{
ModelState.Remove("UserModel.ChangeEmail");
ModelState.AddModelError("PasswordError", "Password is inconsistent ");
}
return Page();
}
Result:

pass textbox value as parameter to controller route

I'm trying to use a textbox value in controller route and am having some trouble with the syntax. Essentially, I have my end users selecting a file and then submitting the data to the api to process and send the data off. I have working static code below, but can't get the xml path to be dynamically populated via the textbox value.
note that (as far as I can tell) the forward slash at the end of the path is required since there is a dot in the file path.
#using (Html.BeginForm("", "api/food/dummy food file.xml/"))
{
<div class="row">
<div class="col-lg-6">
<label class="control-label">Select File</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" single>
</span>
</label>
<input id="food.filepath" name="food.filepath" type="text" class="form-control" readonly>
</div>
</div>
</div>
<br />
<div>
<button id = "btnSubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
}
I don't what the syntax would be, but I can't get something like the below to work.
#using (Html.BeginForm("", "api/food/" + food.filepath + "/"))
{
<div class="row">
<div class="col-lg-6">
<label class="control-label">Select File</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" single>
</span>
</label>
<input id="food.filepath" name="food.filepath" type="text" class="form-control" readonly>
</div>
</div>
</div>
<br />
<div>
<button id = "btnSubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
}
Because the form is rendered on server and the value food.filepath is on client, you cannot mix them. Changing form action according to client values need to be done on client with javascript.
You can remove the file from action a add it on submit javascript action, for example by changing BeginForm to this:
#using (Html.BeginForm("", "api/food/", FormMethod.Get, new { onSubmit = "this.dataset.act = this.dataset.act||this.action; this.action = this.dataset.act + this['food.filepath'].value" } ))

Categories