How to fetch model value to api controller from ajax call - asp.net-mvc-4

I am trying to add User Type details to database. When Passing through ajax to Web API ... model value is passing as null ... I need Model value to be passed as Parameter .. Can an one Help me on this
#model ConstructionModels.UserTypeModel
#using Newtonsoft.Json
#{
// Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>UserTypeModel</h4>
<hr />
<div class="form-group">
#Html.LabelFor(model => model.User_Type, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.User_Type, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" id="btnSave" class="btn btn-default" />
</div>
</div>
</div>
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
var baseUrl= '#System.Configuration.ConfigurationManager.AppSettings["ApiUrl"]';
$("#btnSave").click(function () {
var data1 = #Html.Raw(JsonConvert.SerializeObject(this.Model));
console.log(data1);
$.ajax({
url: baseUrl + 'Usertype/Save',
type: 'post',
data: data1,
dataType: 'json',
success: function () {
alert("Saved");
},
error: function (error) {
alert("Error While Saving");
}
})
})
</script>

Related

Bootstrap Modal Popup background view

I am working on a ASP.NET Core CRUD applciation using modal popup i have a master detail models Stock and Article. i used this code to display the modal popup:
StockController:
public IActionResult Index()
{
List<Category> categories = _dbcontext.Category.ToList();
ViewBag.ListCategories = new SelectList(categories, "CategoryId", "CategoryName");
List<Stock> AllStocks = _dbcontext.Stock.ToList();
return View(AllStocks);
}
[HttpGet]
public IActionResult Create()
{
Stock stock = new Stock();
stock.Articles.Add(new Article() { ArticleId = 1 });
return View("_AddStockPartialView", stock);
}
[HttpPost]
public IActionResult Create(Stock stock)
{
if (stock != null)
{
_dbcontext.Stock.Add(stock);
_dbcontext.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
Index.cshtml:
#model IEnumerable<Stock>
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Theme.cshtml";
}
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Stock</h3>
<div class="card-tools">
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#addStock" onclick="GetDetails()">
<i class="fa fa-plus"></i>
Ajouter
</button>
</div>
</div>
<div class="card-body" id="display">
<table class="table table-bordered table-hover">
.....
</table>
</div>
</div>
</div>
</div>
<script>
function GetDetails() {
$.ajax({
type: "Get",
url: "/Stock/Create",
success: function (res) {
$("#display").html(res);
$("#addStock").modal('show');
}
});
}
</script>
_AddStockPartialView.cshtml:
#model GestionStock.Models.Stock
#{
ViewData["Title"] = "_AddStockPartialView";
}
<div class="modal fade " role="dialog" tabindex="-1" id="addStock" aria-labelledby="addStockLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
<h5>Stock</h5>
</div>
<div class="modal-body">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CategoryId" class="control-label"></label>
<select asp-for="CategoryId" class="form-control" asp-items="ViewBag.ListCategories"></select>
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
.......
<table class="table table-striped" id="articleTable">
<thead>
<tr>
<th>Numero serie</th>
<th>Marque</th>
<th>etat</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Articles.Count; i++)
{
<tr>
<td>
#Html.EditorFor(x => x.Articles[i].NumeroSerie, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(x => x.Articles[i].Marque, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(x => x.Articles[i].Etat, new { htmlAttributes = new { #class = "form-control" } })
</td>
</tr>
}
</tbody>
</table>
<input type="hidden" id="hdnLastIndex" value="0" />
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" #*onclick="javascript:window.location.reload()"*#>Annuler</button>
<button type="submit" class="btn btn-primary">Sauvegarder</button>
</div>
</form>
</div>
</div>
</div>
</div>
Everything works fine and the modal popup is displaying with master detail models. But when i click te button to display the modal popup, the background view (Index.cshtml) is changed like the picture below and the CategoryId SelectList isn't populating:
Although this is the index view which is supposed to display in the background of the modal popup:
So why is Index view chaning when displaying the modal popup?
Below is a work demo, you can refer to it.
In controller, make some change in create action.
[HttpGet]
public IActionResult Create()
{
List<Category> categories = _dbcontext.Category.ToList();
ViewBag.ListCategories = new SelectList(categories, "CategoryId", "CategoryName");
Stock stock = new Stock();
stock.Articles.Add(new Article() { ArticleId = 1 });
return PartialView("_AddStockPartialView", stock);
}
2.In the Index view:
remove table (<table>) before <div class="card-body" id="display">
3.In the _Theme.cshtml, check and make sure you already have below code:
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/GestionStock.styles.css" asp-append-version="true" />
...
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
4.result(I use my model data to show the table) :

ASP.NET Core razor view doesn't show up in browser

This is what the browser shows me:
This is my _Layout:
#using Microsoft.AspNetCore.Mvc.Localization
#inject IViewLocalizer _localizer
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>#_localizer[(string)ViewData["Title"]] - Accounter</title>
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
<link rel="manifest" href="icons/site.webmanifest">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"/>
<link rel="stylesheet" href="~/css/site.css"/>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.1.412/styles/kendo.bootstrap-v4.min.css"/>
<script src="https://kendo.cdn.telerik.com/2022.1.412/js/kendo.all.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.1.412/js/kendo.aspnetmvc.min.js"></script>
</head>
<body>
<header>
<nav class="navbar navbar-expand navbar-light">
<div class="container">
<a class="navbar-brand" asp-action="Index">Tasker</a>
<div class="navbar-nav">
#if (User.Identity.IsAuthenticated)
{
<a class="nav-link text-dark" asp-controller="Authentication" asp-action="LogOut">#_localizer["Log out"]</a>
}
else
{
<a class="nav-link text-dark" asp-controller="Authentication" asp-action="Index">#_localizer["Log in"]</a>
}
</div>
<partial name="_SelectLanguagePartial"/>
</div>
</nav>
</header>
<div></div>
<div class="vh-100 pt-5 backdrop">
<div class="container rounded-3 p-3">
<main role="main">
#RenderBody()
</main>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/cdc2f29cb5.js" crossorigin="anonymous"></script>
#await RenderSectionAsync("Scripts", false)
</body>
</html>
I require user to be authenticated and redirect to the authentication page in ConfigureServices.
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Authentication";
options.SlidingExpiration = true;
});
AuthenticationController:
public class AuthenticationController : Controller
{
private readonly IAuthenticationBL _authenticationBL;
public AuthenticationController(IAuthenticationBL authenticationBL)
{
_authenticationBL = authenticationBL;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register([Bind("Email", "Password")] AuthenticationVM vm)
{
if (!ModelState.IsValid) return View("Index", vm);
await _authenticationBL.RegisterAsync(vm.Email, vm.Password, Request);
return RedirectToAction("Index", "GeneralInformation");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LogIn([Bind("Email", "Password")] AuthenticationVM vm)
{
if (!ModelState.IsValid) return View("Index", vm);
await _authenticationBL.LogInAsync(vm.Email, vm.Password, User);
return RedirectToAction("Index", "GeneralInformation");
}
public async Task<IActionResult> LogOut()
{
await _authenticationBL.LogoutAsync(User);
return RedirectToAction("Index");
}
}
Authentication Index view:
#model Web.Models.VMs.AuthenticationVM
#inject IViewLocalizer _localizer
#using Microsoft.AspNetCore.Mvc.Localization
#{
ViewData["Title"] = "Authentication";
}
<div class="card w-50 container justify-content-center">
<div class="card-body">
<h5 class="text-center mb-3">#_localizer["Log in"]</h5>
<form asp-controller="Authentication" id="authentication-form">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating mb-4 row">
<input asp-for="Email" class="form-control" placeholder="Email" autocomplete="email">
<label asp-for="Email">#_localizer["Email"]</label>
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-floating mb-4 row">
<input asp-for="Password" class="form-control" placeholder="Password">
<label asp-for="Password">#_localizer["Password"]</label>
<i class="btn fa-solid fa-eye" id="password-toggle"></i>
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="row justify-content-between">
<button type="submit" class="col-sm-5 btn btn-primary" asp-action="Register">#_localizer["Register"]</button>
<button type="submit" class="col-sm-5 btn btn-primary" asp-action="LogIn">#_localizer["Log in"]</button>
</div>
</form>
</div>
</div>
#section Scripts {
<script src="~/js/authentication.js"></script>
}
The problem was that I deleted the indication of default action in Startup:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action}");
});
The framework wasn't able to understand what action to invoke on redirection to a controller, and I didn't get a page. Fix:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action=Index}");
});

How to Implement HttpDelete and HttpPut in Asp.Net MVC Core 3.1 c#. Resolve HTTP ERROR 405?

Technology Info:
Framework = Asp.Net Core 3.1
IDE = VisualStudio 2019
Problem:
I have a controller with Update and Delete Action Methods. I have UpdateView and DeleteView from where I need to redirect to the respective controller. I have implemented a button that can submit the form. Still I'm facing HTTP ERROR 405 Issues with PUT & DELETE. Can somebody help me to resolve this issue. Thanks in advance
Controller:
[HttpPut]
[ActionName("ModifyEmployee")]
public IActionResult ModifyEmployee(int employeeId, Malips.Data.Employee employee)
{
if (ModelState.IsValid)
{
Malips.Data.Employee employeeDetail = _hrService.EmployeeSystem.UpdateEmployee(employee);
return View("GetEmployee", employeeDetail);
}
return View();
}
[HttpDelete]
public IActionResult DeleteEmployee(int employeeId)
{
_hrService.EmployeeSystem.DeleteEmployee(employeeId);
return View("Index");
}
UpdateView:
#model Employee
#{
ViewBag.Title = "Modify Employee";
}
<div>
<form asp-controller="Hr" asp-action="ModifyEmployee" asp-route-employeeId="#Model.EmpId">
<div class="form-group">
<div asp-validation-summary="All" class="text-danger">
</div>
</div>
#Html.HiddenFor(e => e.EmpId)
<div class="form-group row">
<label asp-for="FirstName" class="col-sm-2">First Name</label>
<input asp-for="FirstName" class="col-sm-10" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-info">Update</button>
</form>
</div>
DeleteView:
<form asp-controller="Hr" asp-action="DeleteEmployee" asp-route-employeeId="#Model.EmpId">
<div class="row card" style="width: 18rem;">
<div class="card-body">
<label hidden="hidden">#Model.EmpId</label>
<h5 class="card-title">#Model.FirstName #Model.LastName</h5>
<p class="card-text">#Model.Salary </p>
<button type="submit" class="btn btn-danger">Delete</button>
</div>
</div>
</form>
The current HTML5 does not support PUT or DELETE in forms. You can use it with ajax or httpclient only. Or you can try #Html.BeginForm razor page template if it is possible. #Html.BeginForm has post metod choice.
For now remove [ActionName("ModifyEmployee")], [httpput] and [httpdelete] from your action attributes.
And change
public IActionResult ModifyEmployee(int employeeId, Malips.Data.Employee employee)
to:
public IActionResult ModifyEmployee(Employee employee)
since you don't use and don't need emploeeId. And remove asp-route-employeeId="#Model.EmpId" from ModifyEmployee view too.
Like #Sergey said,You can use it with ajax.Below is a working demo.
UpdateView:
<div>
<form id="update" asp-controller="Hr" asp-action="ModifyEmployee">
<div class="form-group">
<div asp-validation-summary="All" class="text-danger">
</div>
</div>
#Html.HiddenFor(e => e.EmpId)
<div class="form-group row">
<label asp-for="FirstName" class="col-sm-2">First Name</label>
<input asp-for="FirstName" class="col-sm-10" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group row">
<label asp-for="LastName" class="col-sm-2">First Name</label>
<input asp-for="LastName" class="col-sm-10" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<button type="submit" id="submit" class="btn btn-info">Update</button>
</form>
</div>
#section scripts
{
<script>
$("#submit").click(function (e) {
e.preventDefault();
var data = $('#update').serialize();
$.ajax({
type: "PUT",
url: "/hr/Modifyemployee",
data: data,
success: function (response) {
window.location.href = response.redirectToUrl;
}
});
})
</script>
}
ModifyEmployee Action
[HttpPut]
[ActionName("ModifyEmployee")]
//remember add this.
[ValidateAntiForgeryToken]
public async Task<IActionResult> ModifyEmployee(Employee employee)
{
//....
return new JsonResult(new { redirectToUrl = Url.Action("Index", "Hr") });
}
DeleteView:
<div>
<form id="delete" asp-controller="Hr" asp-action="DeleteEmployee" asp-route-employeeId="#Model.EmpId">
<div class="row card" style="width: 18rem;">
<div class="card-body">
<label hidden="hidden">#Model.EmpId</label>
<h5 class="card-title">#Model.FirstName #Model.LastName</h5>
<button type="submit" id="submit" class="btn btn-danger">Delete</button>
</div>
</div>
</form>
</div>
#section scripts
{
$("#submit").click(function (e) {
e.preventDefault();
$.ajax({
type: "delete",
url: "/hr/DeleteEmployee?id=" + #Model.EmpId,
success: function (response) {
window.location.href = response.redirectToUrl;
}
});
})
</script>
}
DeleteEmployee Action
[HttpDelete]
public async Task<IActionResult> DeleteEmployee(int id)
{
//......
return new JsonResult(new { redirectToUrl = Url.Action("Index", "hr") });
}
Test Result:

Axios is not defined in vue js applications

I am developing shopping cart project in visual studio 2017. I am using vue js for front end development and mysql for backend . I added the axios script in my html code . When i run the application I following errors in google chrome console windows ..
Uncaught (in promise) ReferenceError: axios is not defined
at Promise.then.products (index.html:75)
at new Promise (<anonymous>)
at Vue.getAllProducts (index.html:74)
at index.html:130
index.html:110 Uncaught (in promise) ReferenceError: axios is not defined
at Promise.then.vendors (index.html:110)
at new Promise (<anonymous>)
at Vue.findAllVendors (index.html:109)
at index.html:131
Here is my html code .
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstap.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.map"></script>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="index.html">Shop</a>
</li>
<li class="nav-item">
<a class="nav-link" href="index.html">Show All Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/AddProducts.html">Add Product</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.html"> cart</a>
</li>
</ul>
</nav>
<br />
<div class="container" id="app">
<select class="form-control" id="sel1" v-on:change="applyfilters($event.target.value)">
<option value="">Select Any value</option>
<option v-for="v in vendors" :value="v.id">{{ v.name }} </option>
<!-- <option value="v.id">{{v.name}}</option>-->
<!--<option value="2">MI</option>-->
</select>
<br />
<div class="row col-12" id="product-list">
<div class="col-4 card mx-2 p-2" v-for="product in products" style="margin-bottom: 20px">
<b>Product Name :</b>{{product.name}}
<div class="row">
<div class="col-4 m-3 p-3">
<b>Price :</b> {{product.price}}
</div>
<div class="col-4 m-3 p-3">
<b>Vendor :</b> {{product.vendor.name}}
</div>
<div class="col-6 m-2 p-3">
<button class="col btn btn-primary" v-on:click="addToCart(product.id)">Buy</button>
</div>
</div>
</div>
<br />
</div>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
newTask: '',
id: 0,
url: '/todos',
status: false,
products: [],
vendors: []
},
methods: {
getAllProducts() {
new Promise((resolve) => {
axios.get('/api/products').then(function (response) {
resolve(response.data)
})
}).then((data) => {
this.products = data
// console.log(this.products)
})
},
addToCart(id) {
// console.log(id)
var obj = { productId: id };
// console.log(obj)
new Promise((resolve) => {
axios.post('/api/cart/', obj).then(function (response) {
resolve(response.data)
})
}).then((data) => {
// console.log(data)
console.log(data)
console.log(data.id)
if (!data.id) {
// console.log("fist login")
window.alert("Fist login ")
window.location = "signin.html";
}
else {
// console.log("successfully add to cart")
window.alert("product has been added to your cart")
}
})
},
findAllVendors() {
new Promise((resolve) => {
axios.get('/api/vendor').then(function (data) {
resolve(data.data)
// console.log(data.data)
})
}).then((data) => {
this.vendors = data
})
},
applyfilters(id) {
new Promise((resolve) => {
axios.get('/api/products/' + id).then(function (response) {
resolve(response.data)
})
}).then((data) => {
this.products = data
// console.log(this.products)
})
}
}
})
app.getAllProducts();
app.findAllVendors();</script>
</body>
</html>
Here is screen shot when i run the applications .
Did you try importing it? Maybe add this to your imports in head tag.
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

VueJS Get the name of the clicked Button If the v-on directive is in the Form Tag

Is it possible to get the submit button name that is being clicked if the v-on:submit is placed on the form tag and not in the button?
Form
<form method="post" #submit.prevent="getButtonName($event)">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form>
Script
methods: {
getButtonName(event) {
}
}
v-on:submit won't work. but v-on:click will. See #click="handleClick($event)"
<template>
<div class="hello">
<form method="post" #click="handleClick($event)" #submit.prevent="getButtonName($event)">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
}
},
methods: {
getButtonName(event) {
// console.log(event);
},
handleClick(e) {
console.log(e.target.name);
}
}
}
</script>
e.g.
https://codesandbox.io/s/6jwvy6l96k
new Vue({
el: "#app",
data() {
return {
clickedButton: null,
}
},
methods: {
getButtonName(event) {
this.clickedButton = event.target.name
}
}
})
<html>
<head></head>
<body>
<div id="app">
<form method="post" #click.prevent="getButtonName">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form>
<div v-text="clickedButton" v-if="clickedButton"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</body>
</html>
You can easely access to the button's name with submitter.name
Check below:
new Vue({
el: "#app",
data() {
return {
clickedButton: null,
}
},
methods: {
getButtonName(e) {
this.clickedButton = e.submitter.name
}
}
})
<html>
<head></head>
<body>
<div id="app">
<form method="post" #submit.prevent="getButtonName">
<input type="submit" name="button1" value="Button1">
<input type="submit" name="button2" value="Button2">
</form><br />
<div>Pressed: {{clickedButton}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</body>
</html>