asp.net localization decimal point - c#

I have a problem where numbers i export from my server with decimal numbers are using the decimal sign instead of a point making it not appear on the screen as shown on the images
image of screen
image of Elements
and here if i replace in manualy with a dot
image of screen
i dont know whats happening since it should be imposible for a double to have a comma in it.
i have tried changing around the double to a string and that works but it only avoids the problem, and i dont want to be able to save text in price.
View code:
#model Produkt
#{
<form asp-action="sparaProdukt" method="post">
<div id="in">
<h2>ID:</h2>
<h1>#Model.id</h1>
</div>
<input type="hidden" name="id" value="#Model.id">
<div id="in">
<label for="Name">name:</label>
<input type="text" id="produktnamn" name="produktnamn" value="#Model.produktnamn">
</div>
<div id="in">
<label for="Supplier">Supplier:</label>
<input type="text" id="Supplier" name="tillverkare" value="#Model.tillverkare">
</div>
<div id="in">
<label for="Info">Info:</label>
<input type="Info" id="Info" name="produktinfo" value="#Model.produktinfo">
</div>
<div class="field">
<div class="wrapper">
<label for="Price">Price:</label>
<input type="number" id="Price" name="pris" class="Price" value="#Model.pris" step="0.01" min="0" lang="en">
<span>| kr</span>
</div>
</div>
<button type="submit">Confirm</button>
</form>
}
Model code:
using Webbshop.Models;
using MySql.Data;
using MySql.Data.MySqlClient;
namespace Webbshop.Models
{
public class Produkt
{
public string produktnamn { get; set; } = "";
public string produktinfo { get; set; } = "";
public string tillverkare { get; set; } = "";
public double pris { get; set; } = 0;
public long id { get; set; } = 0;
public static bool sparaProdukt(Produkt p)
{
string conStr = "server=|removed|;user=|removed|;port=|removed|;database=|removed|;password=|removed|";
MySqlConnection conn = new MySqlConnection(conStr);
MySqlCommand MyCom = new MySqlCommand("UPDATE Produkt set produktnamn = #PRNAMN, tillverkare = #TILL, pris = #PRIS where id = #ID ", conn);
MyCom.Parameters.AddWithValue("#PRNAMN", p.produktnamn);
MyCom.Parameters.AddWithValue("#TILL", p.tillverkare);
MyCom.Parameters.AddWithValue("#PRIS", p.pris);
MyCom.Parameters.AddWithValue("#ID", p.id);
conn.Open();
int rader = MyCom.ExecuteNonQuery();
MyCom.Dispose();
conn.Close();
if (rader == 0) return false; else return true;
}
}
Controller code:
using Microsoft.AspNetCore.Mvc;
using Webbshop.Models;
namespace Webbshop.Controllers
{
public class ProduktController : Controller
{
List<Produkt> allaP = new List<Produkt>();
Produkt P = new Produkt();
public IActionResult Index()
{
return View(Produkt.getAllProdukt());
}
public IActionResult newProdukt()
{
return View();
}
public IActionResult redigeraProdukt(int id)
{
Produkt p = Produkt.getSingleProduktById(id);
return View(p);
}
public IActionResult sparaProdukt(Produkt p)
{
Produkt.sparaProdukt(p);
return View("Index");
}
}
}

Related

How to Get Selected List of DropDownList from Database or Model and Populate in Dropdown on View

I am performing a Bitwise-Create operation on my modal(view) and I am to select a dropdown list of users from another table/model and bind to the view so I can forward the request to them. I want to select users based on a certain role, if possible: but I just want to select the users from the database table.
If you need any other model or controller, kindly prompt me so i add it.
Please help..
Below is my Code:
Cshtml Code for the Modal View:(Removed Other TextFields):
So where I have the select tags, i want to get the select list of users and add it.
<div class="row">
<div class="col-md-12">
<form asp-action="AddOrEdit" asp-route-id="#Model.BitwiseId" autocomplete="false" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="AccountName" class="control-label"></label>
<input asp-for="AccountName" class="form-control" />
<span asp-validation-for="AccountName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="File" class="control-label"></label>
<input type="file" name="userfile" class="form-control" accept=".xlsx"/>
<span asp-validation-for="File" class="text-danger"></span>
</div>
<div class="form-group">
<label for="cars">Select 1st Approver </label>
<select name="group_heads" id="group_heads" class="form-control">
<option value="">Select</option>
<option value="2">Bobby</option>
</select>
</div>
<hr />
<div class="d-grid gap-2">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
Code: Controller for the Bitwise - Add Method:
namespace BOGBitwiseApp.Controllers
{
public class BitwiseController : Controller
{
private readonly ApplicationDbContext _context;
public BitwiseController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
return View(await _context.Bitwises.ToListAsync());
}
// GET: Transaction/AddOrEdit(Insert)
// GET: Transaction/AddOrEdit/5(Update)
[NoDirectAccess]
public async Task<IActionResult> AddOrEdit(int id = 0)
{
if (id == 0)
return View(new BitwiseModel());
else
{
var bitwiseModel = await _context.Bitwises.FindAsync(id);
if (bitwiseModel == null)
{
return NotFound();
}
return View(bitwiseModel);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddOrEdit(int id, [Bind("BitwiseId,..., Amount")] BitwiseModel bitwiseModel, ...)
{
if (ModelState.IsValid)
{
//New
if (id == 0)
{
string filename = userfile.FileName;
...
await userfile.CopyToAsync(stream);
var data = _context.Users.ToListAsync();
bitwiseModel.Date = DateTime.Now;
_context.Add(bitwiseModel);
await _context.SaveChangesAsync();
}
//Update
else
{
try
{
_context.Update(bitwiseModel);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!BitwiseModelExists(bitwiseModel.BitwiseId))
{ return NotFound(); }
else
{ throw; }
}
}
return Json(new { isValid = true, html = Helper.RenderRazorViewToString(this, "_ViewAll", _context.Bitwises.ToList()) });
}
return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEdit", bitwiseModel) });
}
Model Code for Bitwise (Add):
public class BitwiseModel
{
[Key]
public int BitwiseId { get; set; }
[Required]
[Column(TypeName = "nvarchar(100)")]
[DisplayName("Customer Name")]
public string AccountName { get; set; }
[NotMapped]
[DisplayName("Invoice File")]
public IFormFile? File { get; set; }
}
**Model for Users Table:**
public class ApplicationUser : IdentityUser
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public int UsernameChangeLimit { get; set; } = 2;
public byte[]? ProfilePicture { get; set; }
}

ASP.NET Web App CORE: the HttpPost Edit Method in Controller not being called

When i redirect to the Edit.cshtml page, only the HttpGet seems to be working. The HttpPost is not working. Which means that when I make changes and click on the Edit button on the Edit form, the HttpPost Edit is supposed to be invoked to call the PUT API. But the HttpGet Edit is called instead... What have I done wrong?
The HttpGet to retrieve the existing info
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
await ViewBags();
HttpResponseMessage response = await GlobalVariables.WebApiClient.GetAsync("article/detail/" + id.ToString());
if (response.IsSuccessStatusCode)
{
var authorTagArticle = new AuthorTagArticle();
authorTagArticle = response.Content.ReadAsAsync<AuthorTagArticle>().Result;
var articleForm = new ArticleForm();
articleForm.ArticleId = authorTagArticle.Article.ArticleId;
articleForm.ArticleTitle = authorTagArticle.Article.ArticleTitle;
articleForm.ArticleContent = authorTagArticle.Article.ArticleContent;
articleForm.CreatedOn = authorTagArticle.Article.CreatedOn;
articleForm.ImagePath = authorTagArticle.Article.ImagePath;
articleForm.AuthorIds = authorTagArticle.Author.Select(e => e.UserId).ToArray();
articleForm.TagIds = authorTagArticle.Tag.Select(e => e.TagId).ToArray();
return View(articleForm);
}
else
{
TempData["error"] = "Error - Unable to open Edit Article Menu";
return RedirectToAction("Index", "Home");
}
}
The HttpPost Edit method: to call the PUT API
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, ArticleForm articleForm)
{
if (id != articleForm.ArticleId)
{
return NotFound();
}
//If Image is Updated
var content = Request.Form.Files;
const long MaxLength = 10485760; // 10MB
string oldImagePath = articleForm.ImagePath;
if (content.Count() > 0 && content.First().ContentType.Contains("image") && content.First().Length < MaxLength)
{
articleForm.ImagePath = "article/" + content.First().FileName;
}
else
{
ModelState.AddModelError("Image", "Please select a valid image less than 10MB");
}
if (ModelState.IsValid)
{
try
{
Article article = new Article();
article.ArticleId = articleForm.ArticleId;
article.ArticleTitle = articleForm.ArticleTitle;
article.ArticleContent = articleForm.ArticleContent;
article.CreatedOn = articleForm.CreatedOn;
article.ImagePath = articleForm.ImagePath;
HttpResponseMessage response = await GlobalVariables.WebApiClient.PutAsJsonAsync("article/edit/" + id, article);
if (response.IsSuccessStatusCode)
{
TempData["success"] = "Article Updated!";
return RedirectToAction("Index", "Article");
}
else
{
TempData["error"] = "Error - Unable to edit article!";
return RedirectToAction("Index", "Home");
}
}
catch (DbUpdateConcurrencyException) { }
}
return View(articleForm);
}
Edit.cshtml
#model SCANews_UI.Models.ArticleForm
#{ ViewData["Title"] = "Edit"; }
<h1>Edit Article</h1>
<div class="card" style="width: 70rem;">
<div class="card-body">
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="ArticleId" />
<div class="form-group">
<label asp-for="ArticleTitle" class="control-label"></label>
<input asp-for="ArticleTitle" class="form-control">
<span asp-validation-for="ArticleTitle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ArticleContent" class="control-label"></label>
<textarea asp-for="ArticleContent" id="testCK" class="form-control"></textarea>
<span asp-validation-for="ArticleContent" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ImagePath" class="control-label"></label>
<br />
<img style="max-width: 100%; height: 200px;" src="#Model.ImagePath" class="rounded img-thumbnail" alt="Article Image" id="existingImage">
<input hidden asp-for="ImagePath" class="form-control" />
<div class="custom-file">
<input type="file" asp-for="ImagePath" onchange="readURL(this)" class="custom-file-input form-control" name="Image" id="customFile">
<label class="custom-file-label" for="customFile">Choose file</label>
</div>
<span asp-validation-for="ImagePath" class="text-danger"></span>
<!-- Uploaded image area-->
<div class="image-area mt-4"><img id="imageResult" src="#" alt="" class="img-fluid rounded shadow-sm mx-auto d-block"></div>
</div>
<div class="form-group">
<input type="submit" value="Edit" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/ckeditor/ckeditor.js"></script>
<script>
var contentTextArea = document.getElementById("testCK")
CKEDITOR.replace(contentTextArea);
</script>
<script type="text/javascript">
$(".custom-file-input").on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
});
</script>
<script>
//Show Image
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#imageResult')
.attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
var beforeImage = document.getElementById('existingImage');
beforeImage.style.display = 'none';
}
$(function () {
$('#customFile').on('change', function () {
readURL(input);
});
});
</script>
<script type="text/javascript">
//Show Image Name
document.querySelector('.custom-file-input').addEventListener('change', function (e) {
var name = document.getElementById("customFile").files[0].name;
var nextSibling = e.target.nextElementSibling
nextSibling.innerText = name
})
</script>
ArticleForm model
public class ArticleForm
{
public int ArticleId { get; set; }
[Required, Column(TypeName = "varchar(150)")]
[DisplayName("Article Title")]
public string ArticleTitle { get; set; }
[Required, Column(TypeName = "text")]
[DisplayName("Article Content")]
public string ArticleContent { get; set; }
public DateTime CreatedOn { get; set; }
[Column(TypeName = "text")]
[DisplayName("Image")]
public string ImagePath { get; set; }
public int[] AuthorIds { get; set; }
public int[] TagIds { get; set; }
}
Article Model
public class Article
{
public int ArticleId { get; set; }
public string ArticleTitle { get; set; }
public string ArticleContent { get; set; }
public DateTime CreatedOn { get; set; }
public string ImagePath { get; set; }
}
AuthorTagArticle Model
public class AuthorTagArticle
{
public Article Article { get; set; }
public List<User> Author { get; set; }
public List<Tag> Tag { get; set; }
}
GlobalVariables
public class GlobalVariables
{
public static HttpClient WebApiClient = new HttpClient();
static GlobalVariables()
{
//local testing
WebApiClient.BaseAddress = new Uri("https://localhost:44361/api/");
//lambda APIs
WebApiClient.DefaultRequestHeaders.Clear();
WebApiClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
}
Try to edit your code as following: <form asp-controller="{Your controller}" asp-action="Edit" method="post">
Also you can read some info about Tag Helpers here

How to get image from form

I've made a website and can't get image from form. When I inputted all dates and chose image and click on "Submit", image doesn't get from form. I need to get image from form and convert to array of bytes to write in database.
This is my code:
[HttpPost]
public IActionResult Post([FromForm] Products product)
{
Images image = new Images();
if (ModelState.IsValid && product != null && !(string.IsNullOrEmpty(product.Name)) && product.price != 0 && !(string.IsNullOrEmpty(product.description)) && product.CategoryId != 0)
{
//insert
string query = #"insert into dbo.Product values('" + product.Name + #"'," + product.price + #",'" + product.description + #"',"+ product.CategoryId + #")";
DataTable table = new DataTable();
string sqlDataSource = _configuration.GetConnectionString("CommandsConnection");
SqlDataReader myReader;
using (SqlConnection myCon = new SqlConnection(sqlDataSource))
{
myCon.Open();
using (SqlCommand myCommand = new SqlCommand(query, myCon))
{
myReader = myCommand.ExecuteReader();
table.Load(myReader);
myReader.Close();
myCon.Close();
}
}
//select
string query2 = #"select id from dbo.Product where Name= '" + product.Name + #"'";
DataTable table2 = new DataTable();
string sqlDataSource2 = _configuration.GetConnectionString("CommandsConnection");
SqlDataReader myReader2;
using (SqlConnection myCon = new SqlConnection(sqlDataSource2))
{
myCon.Open();
using (SqlCommand myCommand = new SqlCommand(query2, myCon))
{
myReader2 = myCommand.ExecuteReader();
table2.Load(myReader2);
myReader2.Close();
myCon.Close();
}
}
foreach (DataRow item in table2.Rows)
{
image.id = (int)item["id"];
}
//var file = Convert.ToByte(product.image);
image.image = (byte[])(new ImageConverter()).ConvertTo(file, typeof(byte[]));
Console.WriteLine(image.image);
var client = new MongoClient("mongodb://localhost:27017/");
var database = client.GetDatabase("cmscart");
var collection = database.GetCollection<Images>("images");
collection.InsertOne(image);
return View();
}
else
{
return Content("Bed");
}
}
When I click on submit I have a null in product.image. I choose all dates from form and write it in SQL DB and after it, I take id for this data and assign id to image.id and need to take image from product.image and assign to image.image but before it converted to bytes array and after all write to MongoDB.
These are the models:
public class Products
{
public int id { get; set; }
public string Name { get; set; }
public double price { get; set; }
public string description { get; set; }
public string image { get; set; }
public int CategoryId { get; set; }
}
public class Images
{
[BsonId]
public ObjectId _id { get; set; }
[BsonElement("id")]
public int id { get; set; }
[BsonElement("image")]
public byte[] image { get; set; }
}
Image property in Products model should be of type IFormFile.
public IFormFile image { get; set; }//public string image { get; set; }
Also, don't forget to add enctype="multipart/form-data" attribute to your form.
<form asp-action="Create" enctype="multipart/form-data">
Following is the complete sample code in ASP.NET Core 3.1.
View
#model MVC_Core_Example.Controllers.Products
#{
ViewData["Title"] = "Create";
}
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="image" class="control-label"></label>
<input asp-for="image" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
Controller
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace MVC_Core_Example.Controllers
{
public class Products
{
public int id { get; set; }
public string Name { get; set; }
public double price { get; set; }
public string description { get; set; }
public IFormFile image { get; set; }//public string image { get; set; }
public int CategoryId { get; set; }
}
public class ImageController : Controller
{
public IActionResult Create()
{
return View(new Products());
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Products product)//IFormCollection collection
{
return View(product);
}
}
}
When I click on submit I have a null in product.image.
The issue is related to the image data type in the Product class, and the image upload method (using tag helper or directly using html file upload element).
In asp.net core application, we could upload the files via the IFormFile. More detail information, check Upload files in ASP.NET Core.
Then, when upload image to the action method, we could use the following methods:
Using Tag Helper:
<input asp-for="Image" class="form-control" type="file" />
If using this element, remember add type="file" in the input element, you could find the image content from the ProductViewModel model.
Directly using html file upload element:
<input id="file" type="file" name="file" />
If using this method, you have to add a IFormFile parameter in the action method and get the image content based on the name attribute.
[Note] Using both of the above methods, we have to add enctype="multipart/form-data" attribute in the form tag.
More details information, you could check the following sample code:
Create a ProductViewModel to collect information and upload image:
//required using Microsoft.AspNetCore.Http;
public class ProductViewModel
{
public int id { get; set; }
public string Name { get; set; }
public double price { get; set; }
public string description { get; set; }
public IFormFile Image { get; set; }
}
Then, in the AddProduct.cshtml page, use the following code to upload image:
#model WebApplication.Models.ProductViewModel
#{
ViewData["Title"] = "AddProduct";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="row">
<div class="col-md-4">
<form asp-action="AddProduct" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
#*other fields*#
<div class="form-group">
<label asp-for="Image" class="control-label"></label>
#*<input id="file" type="file" name="file" />*#
<input asp-for="Image" class="form-control" type="file" />
<span asp-validation-for="Image" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
Controller code:
[HttpPost]
public async Task<IActionResult> AddProductAsync(ProductViewModel productvm, IFormFile file)
{
if (ModelState.IsValid)
{
//If you are using `<input id="file" type="file" name="file" />` to submit the image, you could get the image from the file.
if (productvm.Image.Length > 0)
{
using (var memoryStream = new MemoryStream())
{
await productvm.Image.CopyToAsync(memoryStream);
// Upload the file if less than 2 MB
if (memoryStream.Length < 2097152)
{
var product = new Product()
{
imageContent = memoryStream.ToArray()
};
//_dbContext.Products.Add(product);
//await _dbContext.SaveChangesAsync();
}
else
{
ModelState.AddModelError("File", "The file is too large.");
}
}
}
}
return View();
}
The screenshot as below:

.NET Core Radio button group is not getting passed to the controller

Model:
public class TaxCertificateMailing
{
public IList<Report> SelectReports { get; set; }
public class Report
{
public string Text { get; set; }
public bool Selected { get; set; }
}
}
View:
#model LandNav.Areas.Reports.Models.TaxCertificateMailing
#{
ViewData["Title"] = "Tax Certificate Mailing List";
}
#using (Html.BeginForm("TaxCertificateMailing", "Reports", FormMethod.Post, new { id = "reportForm", #class = "report-form col-9" }))
{
<!--Start of the form body-->
<div class="row">
<div class="col-12">
<label><b>Select the report to run:</b></label><br />
#for (var x = 0; x < Model.SelectReports.Count; x++)
{
<input type="radio" asp-for="SelectReports" name="#reports" value="#Model.SelectReports[x].Selected" />
<input type="hidden" asp-for="SelectReports[x].Text"/>
<b>#Model.SelectReports[x].Text</b>
}
</div>
</div>
...
Controller:
[HttpPost]
public ActionResult TaxCertificateMailing(
//IFormCollection form
TaxCertificateMailing TCM
)
{
return View();
}
When the form is posted the SelectReports IList has a count of 0. What is the best way to handle posting a radio button group using .net core?
The name attribute of the input field should be #Model.SelectReports[x].Selected.
Use the code below for the for loop;
#for (var x = 0; x < Model.SelectReports.Count; x++)
{
<input type="radio" asp-for="SelectReports" name="#Model.SelectReports[x].Selected" value="#Model.SelectReports[x].Selected" />
<input type="hidden" asp-for="SelectReports[x].Text"/>
<b>#Model.SelectReports[x].Text</b>
}
Assuming only one value is selected at a time (which is how radio buttons are intended to be used), you have some issues with your models. I'd suggest this:
public class TaxCertificateMailing
{
public TaxCertificateMailing()
{
Reports = new HashSet<Report>();
}
public int SelectedReportID { get; set; }
public ICollection<Report> Reports { get; set; }
}
public class Report
{
public string Text { get; set; }
public int ID { get; set; }
}
This assumes you're pulling these from some sort of database - change the identifier to whatever makes sense, updating SelectedReportID's type to match.
Then, your view would look something like this:
<form asp-action="TaxCertificateMailing" asp-controller="Reports" method="post" id="reportForm" class="report-form col-9">
<fieldset>
<legend>Select the report to run:</legend>
#foreach (var report in Model.Reports)
{
<div class="form-group form-check">
<input type="radio" asp-for="SelectedReportID" id="report-#(report.ID)" value="#report.ID" class="form-check-input" />
<label for="report-#(report.ID)" class="form-check-label">#report.Text</label>
</div>
}
</fieldset>
</form>

How to make form input for List of objects?

I have a List of objects in my Model, how can I make a form for it?
I want to have select box and number input box to add objects and be able to keep adding more before posting form.
If it was just public Cargo cargo I would just make a select box to choose cargo type and input box for amount and that's it. But it's a list so I want to add as much cargo as I want and then post a form. I already have input fields for address (like city, street etc.) in my form but I'm stuck with this list.
Order model (Form model):
public class Order
{
public int Id { get; set; }
public Address PickUpAddress { get; set; }
public Address DropOffAddress { get; set; }
[...]
public List<Cargo> Cargo { get; set; }
}
Cargo model:
public class Cargo
{
public int Id { get; set; }
public int Amount { get; set; }
public CargoType CargoType { get; set; }
}
My solution
I implemented this function manually without any JS code.
The code is very simple. You can refer to my code here directly.
Solving process
We have to insert the order table before we can insert the cargo table. Otherwise, we can't connect the two tables.
We need these three form models.We use the cargocount field to link the two order pages with the cargo page.
public class CargoViewModel
{
public int OrderId { get; set; }
public int Amount { get; set; }
public string CargoType { get; set; }
//Other use
public int CargoCount { get; set; }
public List<CargoViewModel> Cargos { get; set; }
}
public class OrderViewModel
{
public int OrderId { get; set; }
public string PickUpAddress { get; set; }
public string DropOffAddress { get; set; }
public int CargoCount { get; set; }
public List<CargoViewModel> Cargos { get; set; }
}
public class OrdersViewModel
{
public List<OrderViewModel> Orders { get; set; } = new List<OrderViewModel>();
}
When we create an order page, we need to provide the data of cargocount. When we submit the order page, we will save the existing data to the order table, jump to the cargo page, and generate cargocount input tags.
Next, submit the list form.
Submit page code
<form asp-controller="Order" asp-action="CreateCargo" method="post">
#if (Model.CargoCount != 0)
{
for (int itemCount = 0; itemCount < Model.CargoCount; itemCount++)
{
<div class="row">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<div class="form-group" style="width:300px; height:auto; float:left; display:inline">
<label asp-for="#Model.Cargos[itemCount].Amount" class="control-label"></label>
<input asp-for="#Model.Cargos[itemCount].Amount" class="form-control" />
<span asp-validation-for="#Model.Cargos[itemCount].Amount" class="text-danger"></span>
</div>
<div class="form-group" style="width:300px; height:auto; float:left; display:inline">
<label asp-for="#Model.Cargos[itemCount].CargoType" class="control-label"></label>
<input asp-for="#Model.Cargos[itemCount].CargoType" class="form-control" />
<span asp-validation-for="#Model.Cargos[itemCount].CargoType" class="text-danger"></span>
</div>
</div>
</div>
}
}
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
Background data processing code
[HttpPost]
public async Task<IActionResult> CreateCargo(CargoViewModel model)
{
var orderId = await _context.Order.Select(o => o.OrderId).MaxAsync();
var cargos = model.Cargos;
foreach (var item in cargos)
{
var cargo = new Cargo
{
OrderId = orderId,
Amount = item.Amount,
CargoType = item.CargoType
};
await _context.AddAsync(cargo);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
Using JS implementation
We need this form models.
public class OrderAndCargoViewModel
{
public int OrderId { get; set; }
public string PickUpAddress { get; set; }
public string DropOffAddress { get; set; }
public List<CargoViewModel> Cargos { get; set; }
}
Next, submit the table form. Submit page code.
<div style="float:right;">
<table id="tb">
<tr>
<th> <label class="control-label">ID</label></th>
<th> <label asp-for="#Model.Cargos.FirstOrDefault().Amount" class="control-label"></label> </th>
<th><label asp-for="#Model.Cargos.FirstOrDefault().CargoType" class="control-label"></label></th>
</tr>
#{
var countId = 0;
for (var itemCount = 0; itemCount < 3; itemCount++)
{
<tr id="trs">
<td>#(++countId)</td>
<td><input asp-for='#Model.Cargos[itemCount].Amount' class= 'form-control' /></td>
<td><input asp-for='#Model.Cargos[itemCount].CargoType' class='form-control' /></td>
</tr>
}
}
</table>
</div>
<input id="btnAdd" value="Add" type="button" class="btn btn-primary" onclick="btnAddClick()">
JS Code.
#section scripts{
<script src="~/js/jquery-3.4.1/jquery-3.4.1.js" type="text/javascript"></script>
<script src="~/js/jquery-3.4.1/jquery-ui-1.12.1.js" type="text/javascript"></script>
<script src="~/js/jquery-3.4.1/jquery.unobtrusive-ajax.js" type="text/javascript"></script>
<script>
var btnAddClick = function () {
var trLen = $("#tb tr[id='trs']").length;
var $lastTr = $("#tb tr[id='trs']").last();
var tr = "<tr id='trs'>";
tr += "<td>" + (trLen + 1) + "</td>";
tr += "<td><input class='form-control' type='number' data-val='true' data-val-required='The Amount field is required.' id='Cargos_"+trLen+"__Amount' name='Cargos["+trLen+"].Amount' value=''></td>";
tr += "<td><input class='form-control' type='text' id='Cargos_"+trLen+"__CargoType' name='Cargos["+trLen+"].CargoType' value=''>";
tr += "</tr>";
$(tr).insertAfter($lastTr);
}
</script>
}
Controller Code.
[HttpPost]
public async Task<IActionResult> CreateOrderAndCargo(OrderAndCargoViewModel model)
{
var order = new Order()
{
PickUpAddress = model.PickUpAddress,
DropOffAddress = model.DropOffAddress
};
await _context.AddAsync(order);
await _context.SaveChangesAsync();
var orderId = await _context.Order.Select(o => o.OrderId).MaxAsync();
var cargos = model.Cargos;
foreach (var item in cargos)
{
var cargo = new Cargo
{
OrderId = orderId,
Amount = item.Amount,
CargoType = item.CargoType
};
await _context.AddAsync(cargo);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
Click here to view source codes.
Reference page
About'#'.
JS operation.
It will solve the problem if you use more than one related model in View pages and give a list parameter in actions..
An example;
View;
<input type="text" name="name" id="name1" />
<input type="text" name="name" id="name2" />
Action
public actionresult post(string [] name)

Categories

Resources