Using input tag helper "name" and getting input value empty. ASP.NET MVC (.NET 5) - asp.net

I have simple form for creating items
<form asp-action="CreateItem" enctype="multipart/form-data">
<div class="form-group">
<label asp-for="#Model.ItemPhoto" class="control-label"></label>
<input type="file" asp-for="#Model.ItemPhoto" name="Photo" class="form-control-file" />
<span asp-validation-for="#Model.ItemPhoto" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.Name" class="control-label"></label>
<input asp-for="#Model.Name" class="form-control" />
<span asp-validation-for="#Model.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.ItemType" class="control-label"></label>
<select asp-for="#Model.ItemType" class="form-control">
#foreach (var itemType in Enum.GetValues(typeof(RandApp.Enums.ItemType)))
{
<option value="#itemType.ToString()">#itemType</option>
}
</select>
<span asp-validation-for="#Model.ItemType" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.MaterialType" class="control-label"></label>
<select asp-for="#Model.MaterialType" class="form-control">
#foreach (var materialType in Enum.GetValues(typeof(RandApp.Enums.MaterialType)))
{
<option value="#materialType.ToString()">#materialType</option>
}
</select>
<span asp-validation-for="#Model.MaterialType" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.Color" class="control-label"></label>
<select asp-for="#Model.Color" class="form-control">
#foreach (var color in Enum.GetValues(typeof(RandApp.Enums.ItemColor)))
{
<option value="#color.ToString()">#color</option>
}
</select>
<span asp-validation-for="#Model.Color" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.Size" class="control-label"></label>
<select asp-for="#Model.Size" class="form-control">
#foreach (var size in Enum.GetValues(typeof(RandApp.Enums.ItemSize)))
{
<option value="#size.ToString()">#size</option>
}
</select>
<span asp-validation-for="#Model.Size" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.DesignedFor" class="control-label"></label>
<select asp-for="#Model.DesignedFor" class="form-control">
#foreach (var desigendFor in Enum.GetValues(typeof(RandApp.Enums.DesignedFor)))
{
<option value="#desigendFor.ToString()">#desigendFor</option>
}
</select>
<span asp-validation-for="#Model.DesignedFor" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.Price" class="control-label"></label>
<input asp-for="#Model.Price" class="form-control" />
<span asp-validation-for="#Model.Price" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.Description" class="control-label"></label>
<textarea asp-for="#Model.Description" class="form-control"></textarea>
<span asp-validation-for="#Model.Description" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
there is its controller
public async Task<IActionResult> CreateItem(Item item, IFormFile Photo)
{
if (ModelState.IsValid)
{
var path = Path.Combine(_webHostEnvironment.WebRootPath, "assets", Photo.FileName);
var stream = new FileStream(path, FileMode.Create);
await Photo.CopyToAsync(stream);
item.ItemPhoto = Photo.FileName;
await _itemRepo.CreateAsync(item);
ViewBag.Item = item;
return RedirectToAction("ReadItems");
}
return View();
}
my goal is to get the path of chosen photo and save it in folder called "assets"(located in "wwwroot" folder).
The problem is that when i fill the fields and submitting the values, i get item.ItemPhoto value null and i can't enter in if statement. (see the photo down below).
[1]: https://i.stack.imgur.com/H2aLt.png
one solution i have found is to remove "enctype="multipart/form-data" from form and "name="Photo" tag helper from input
<form asp-action="CreateItem" enctype="multipart/form-data">
<div class="form-group">
<label asp-for="#Model.ItemPhoto" class="control-label"></label>
<input type="file" asp-for="#Model.ItemPhoto" name="Photo" class="form-control-file" />
<span asp-validation-for="#Model.ItemPhoto" class="text-danger"></span>
</div>
but in this case i can't get the path properly.
what can i do to solve this problem, why am i getting empty value from input?

File and string type cannot be passed together with the same name automatically and cannot achieve this requirement by using just one input. You can set a hidden input for ItemPhoto and use js to set the value when the file changed:
#model Item
<form asp-action="CreateItem" enctype="multipart/form-data">
<div class="form-group">
<label asp-for="#Model.ItemPhoto" class="control-label"></label>
//change here...
<input type="file" name="ItemPhoto" class="form-control-file" onchange="SetValue(this)" />
//add hidden input......
<input asp-for="#Model.ItemPhoto" hidden/>
<span asp-validation-for="#Model.ItemPhoto" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.Name" class="control-label"></label>
<input asp-for="#Model.Name" class="form-control" />
<span asp-validation-for="#Model.Name" class="text-danger"></span>
</div>
<input type="submit" value="Create"/>
</form>
#section Scripts
{
<script>
function SetValue(input) {
var fileName = input.files[0].name;
//asp-for will generate the id and name
//so you can get the selector by using $("#ItemPhoto")
$("#ItemPhoto").val(fileName);
}
</script>
}
Backend (The name attribute should always match with the parameter/property name):
public async Task<IActionResult> CreateItem(Item item, IFormFile ItemPhoto)
{
//....
return View();
}

Related

The model item passed into the ViewDataDictionary is of type but this ViewDataDictionary instance requires a model item of type 'System.Collections

When I Want to post my Form in Asp.net.Mvc I get this Problem How can i fix that
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'FormValidation.Models.Entity.Personel', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable`1[FormValidation.Models.Entity.Personel]'.
Controller
[HttpGet]
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Post(Personel personel)
{
return View(personel);
}
form index
#model FormValidation.Models.Entity.Personel
<form method="post" asp-action="Post" asp-controller="Home">
<div class="container">
<div class="row">
<div class="form-group">
<label for="Name" class="form-control" placeholder="Enter Your Name">Name</label>
<input type="text" class="form-control" asp-for="Name" />
</div>
<br />
<div class="form-group">
<label for="Surname" class="form-control" placeholder="Enter Your Surname">Surname</label>
<input type="text" class="form-control" placeholder="Enter Your surname" asp-for="Surname" />
</div>
<br />
<br />
<div class="form-group">
<label for="City">City select</label>
<select class="form-control" asp-for="City">
<option></option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<br />
<br />
<br />
<div class="form-group">
<label for="Age" class="form-control" placeholder="Enter Your Age">Age</label>
<input type="number" class="form-control" placeholder="Enter Your Age" asp-for="Age" />
</div>
<br />
<div class="form-group">
<label for="Adress">Adres</label>
<textarea class="form-control" rows="3" asp-for="Adress">Adres</textarea>
</div>
</div>
</div>
<br />
<input type="submit" name="submit" value="submit" class="btn btn-primary" />
</form>
Post index
#model IEnumerable<FormValidation.Models.Entity.Personel>
#foreach (var item in Model)
{
<p>#item.Name</p>
<p>#item.Surname</p>
<p>#item.Age</p>
<p>#item.City</p>
}
just as the error indicates,you passed the single personel model to render the view with return View(personel);
However,the View requires IEnumerable<Personel>
If you just want to show the details of the model you just created ,modify your view :
#model FormValidation.Models.Entity.Personel
.......
<p>#Model.Name</p>
<p>#Model.Surname</p>
<p>#Model.Age</p>
<p>#Model.City</p>

Model does not get any properties fillen after post

Problem: Hi fellow programmers, I am new to ASP.NET and tried to figure out why this happens for hours but could not find why. The model in the controller does not get any property after the post. They are all nulls, why is that so?
The view
#model AddProductViewModel
#{
ViewBag.Title = "Add a new Product";
}
<h2 class="text-center">#ViewBag.Title</h2>
<div class="row">
<div class="col-sm-12 offset-lg-2 col-lg-8 offset-xl-3 col-xl-6">
<form asp-action="Add" method="post">
<div class="mb-3">
<label asp-for="#Model.Model" class="form-label">Model Name</label>
<input asp-for="#Model.Model" class="form-control" aria-required="true" />
<span asp-validation-for="Model" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.Description" class="form-label">Description</label>
<textarea asp-for="#Model.Description" class="form-control" aria-required="true" rows="5"></textarea>
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.Colour" class="form-label">Colour</label>
<input asp-for="#Model.Colour" class="form-control" value="" />
<span asp-validation-for="Colour" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.Size" class="form-label">Size</label>
<input asp-for="#Model.Size" class="form-control" value="" />
<span asp-validation-for="Size" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.Price" class="form-label">Price</label>
<input asp-for="#Model.Price" class="form-control" value="" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.ImageData" class="form-label">Image URL</label>
<input asp-for="#Model.ImageData" class="form-control" aria-required="true" />
<span asp-validation-for="ImageData" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.CategoryId" class="form-label">Category</label>
<select asp-for="#Model.CategoryId" class="form-control">
#foreach (var category in Model.Categories)
{
<option value="#category.Id">#category.Name</option>
}
</select>
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="#Model.BrandId" class="form-label">Brand</label>
<select asp-for="#Model.BrandId" class="form-control">
#foreach (var brand in Model.Brands)
{
<option value="#brand.Id">#brand.Name</option>
}
</select>
<span asp-validation-for="BrandId" class="text-danger"></span>
</div>
<div class="mb-3">
<input class="btn btn-primary" type="submit" value="Add" />
</div>
</form>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
The controller
...
[HttpPost]
public async Task<IActionResult> Add(AddProductViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
try
{
await productService.AddProductAsync(model);
return RedirectToAction("Index", "Home");
}
catch (Exception)
{
ModelState.AddModelError("", "Something went wrong");
return View(model);
}
}
...
That's the first time something like that happens to me. I have done another project which was very similar if not the same. Any help will be appreciated!
Your model contains property named Model which will conflict with your parameter AddProductViewModel model.
So just change your parameter name like below:
[HttpPost]
public async Task<IActionResult> Add(AddProductViewModel addProductViewModel)
{
if (!ModelState.IsValid)
{
return View(addProductViewModel);
}
try
{
await productService.AddProductAsync(addProductViewModel);
return RedirectToAction("Index", "Home");
}
catch (Exception)
{
ModelState.AddModelError("", "Something went wrong");
return View(addProductViewModel);
}
}

Unable to bind field of type int in asp.net core

I'm trying to save data in database but the problem i'm facing is that Every data of fields is binding with model except integer type fields it bind 0 to them.
I gives value in the fields but instead of those value it bind 0 to them.
Can anyone help me with this that how do i solve this problem.
This is the View about which i'm facing the problem.
The Fields which are not binding is Adult,Children,Senior and Travelers
#model Airline.Models.BookingModel
#{
ViewData["Title"] = "Buy";
}
<h2>Buy</h2>
<h4>BookingModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Buy">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="FlightSkyMiles" type="hidden" value="#ViewBag.Flight.SkyMiles" />
<div class="form-group">
<label asp-for="FlightName" class="control-label"></label>
<input asp-for="FlightName" value="#ViewBag.Flight.FlightName" class="form-control" readonly />
<span asp-validation-for="FlightName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FlightNo" class="control-label"></label>
<input asp-for="FlightNo" value="#ViewBag.Flight.FlightNo" class="form-control" readonly />
<span asp-validation-for="FlightNo" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="OriginCity" class="control-label"></label>
<input asp-for="OriginCity" value="#ViewBag.Flight.OriginCity" class="form-control" readonly />
<span asp-validation-for="OriginCity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DestinationCity" class="control-label"></label>
<input asp-for="DestinationCity" value="#ViewBag.Flight.DestinationCity" class="form-control" readonly />
<span asp-validation-for="DestinationCity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Departure" class="control-label"></label>
<input asp-for="Departure" type="datetime" value="#ViewBag.Flight.Departure" class="form-control" readonly />
<span asp-validation-for="Departure" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Adult" class="control-label"></label>
<input asp-for="Adult" type="number" name="seats" value="0" class="form-control" id="adult" />
<span asp-validation-for="Adult" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Children" class="control-label"></label>
<input asp-for="Children" type="number" name="seats" value="0" class="form-control" id="childern" />
<span asp-validation-for="Children" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Senior" class="control-label"></label>
<input asp-for="Senior" type="number" name="seats" value="0" class="form-control" id="senior" />
<span asp-validation-for="Senior" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Travelers" class="control-label"></label>
<input asp-for="Travelers" type="number" name="TotalSeats" class="form-control" id="total" readonly required />
<span asp-validation-for="Travelers" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FlightClass" class="control-label"></label>
<select class="form-control" onchange="getPrice(#ViewBag.Flight.Id)" asp-for="FlightClass" id="fclass" asp-items="Html.GetEnumSelectList<Classtype>()" itemid="" required>
<option selected="selected" value="">Please select</option>
</select>
<span asp-validation-for="FlightClass" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" onchange="multPrice()" id="price" class="form-control" readonly />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="radio" name="Reservation" value="Buy" required /> Buy
<input type="radio" name="Reservation" value="Block" /> Block
<span asp-validation-for="ReservationType" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section scripts
{
<script type="text/javascript" src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function (e) {
function calculate() {
var adult = parseInt($("#adult").val());
var chi = parseInt($("#childern").val());
var sen = parseInt($("#senior").val());
$("#total").val(adult + chi + sen);
};
$("#adult").keyup(calculate);
$("#childern").keyup(calculate);
$("#senior").keyup(calculate);
});
</script>
}
<script>
function getPrice(id) {
function multPrice()
{
var mult = $("#total").val() * $("#price").val();
$("#price").val(mult);
}
$.ajax
({
url: '/Home/getPrice',
type: 'post',
data: { id:id,classId: $("#fclass").val()},
success: function (result) {
$("#price").val(result.price);
multPrice();
},
error: function () {
alert("Error")
}
});
}
</script>

Class receiving the value reset

I'm doing insert via post, but my class is getting the zero values of the inputs.
The values of the inputs are passed via variable and corrections are displayed, but at the time of the post are coming down.
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>
[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");
}
Remove Caixas property and add it as parameter in your OnPostAsync method:
// [BindProperty]
// public Caixas Caixas { get; set; }
[HttpPost]
public async Task<IActionResult> OnPostAsync([FromBody]Caixas c)
{
// ...
}

how to get data by finding all and finding one at the same time

In my project on the user edit page I would like to show the current role,wich i get by findOne byId,but I would also like to get all available roles so that I can choose, roles are in a separate collection, and I dont have a problem when displaying eather one...or all..
<div class="form-group col-lg-12">
<label>Email</label>
<input type="email" class="form-control" id="email" value="{{emails.[0].address}}">
</div>
<div class="form-group col-lg-12">
<label>Password</label>
<input type="password" name="" class="form-control" id="password" value="{{password}}">
</div>
<div class="form-group col-lg-6">
<label>Name</label>
<input type="text" name="" class="form-control" id="firstname" value="{{profile.name}}">
</div>
<div class="col-xs-12"><strong>Current role:</strong>
<label class="radio-inline">
<input type="radio" name="optradio" id="accountRole" value="{{roleName profile.role}}" checked>{{roleName profile.role}}
</label>
</div>
{{/with}}
<div class="col-xs-12">
<form>
<div class="col-xs-12"><strong>Roles:</strong>
{{#each rolesInformation}}
<label class="radio-inline">
<input type="radio" name="optradio" id="accountRole" value="{{_id}}">{{roleName}}
</label>
{{/each}}</div>`
helpers look like this:
Template.editUser2.helpers({
user: () => {
return Meteor.users.findOne({_id:Session.get('id')});
},
playerInformation: () => {
return Players.find().fetch();
},
roleName: (id)=>{
return Roles.findOne({_id:id}).roleName;
},
rolesInformation: () =>{
return Roles.find().fetch();
},
when i run roleName or rolesInformation separateli it works fine...
whet both included i get "roleName not defined"

Resources