Post back Method not get call on button click in MVC4 - asp.net

i have created a login page without _layout.cshtml in mvc4 and added two text box with a button. But when i click button it no getting post back. I have tried using breakpoint. pls help. My Code
#model MapProjectMVC.Models.LoginModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Special Spots</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="loginBox">
<div class="loginHead">
<img src="img/logo.png" alt="Special Spots - responsive admin panel" title="Special Spots - responsive admin panel" />
</div>
<div class="control-group">
<label for="inputEmail">
User Name</label>
#Html.TextBoxFor(a => a.UserName)
</div>
<div class="control-group">
<label for="inputPassword">
Password</label>
#Html.TextBoxFor(a => a.Password)
</div>
<div class="control-group" style="margin-bottom: 5px;">
</div>
<div class="form-actions">
<button type="submit" class="btn btn-block">
Sign in</button>
</div>
</div>
#Scripts.Render("~/bundles/jquery")
</body>
</html>
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel LM)
{
var UserId = new ObjectParameter("userId",typeof(string));
var res = new ObjectParameter("res",typeof(Int32));
int i = ssc.ValidateAdminLogin(LM.UserName, LM.Password, UserId, res);
if (Convert.ToInt32(res) == 1)
{
}
else
{
ModelState.AddModelError("", "Login details are wrong.");
}
return View(LM);
}

You have to put the input elements and submit button in form. For this purpose you can use asp.net mvc Html Helper Extension for form Html.BeginForm() this way:
#using(Html.BeginForm())
{
<div class="loginBox">
<div class="loginHead">
<img src="img/logo.png" alt="Special Spots - responsive admin panel" title="Special Spots - responsive admin panel" />
</div>
<div class="control-group">
<label for="inputEmail">
User Name</label>
#Html.TextBoxFor(a => a.UserName)
</div>
<div class="control-group">
<label for="inputPassword">
Password</label>
#Html.TextBoxFor(a => a.Password)
</div>
<div class="control-group" style="margin-bottom: 5px;">
</div>
<div class="form-actions">
<button type="submit" class="btn btn-block">
Sign in</button>
</div>
</div>
}
There are many overloads of Html.BeginForm(), See all overloads here

Related

Dropdowns blank when rendered as partial view

I am attempting to load a modal create form via the method OnGetCertificationPartial. The form is loading, however the dropdowns are blank.
The dropdowns are not blank when loading the /Create page via the OnGet method
How can I get the dropdowns to populate when loaded as a partial via OnGetCertificationPartial method?
Create.cshtml.cs
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using EmployeeCertification.Models.Scaffold;
namespace EmployeeCertification.Pages.CertificationRuleCertifications
{
public class CreateModel : PageModel
{
private readonly EmployeeCertification.Models.Scaffold.EmployeeCertificationDBContext _context;
public CreateModel(EmployeeCertification.Models.Scaffold.EmployeeCertificationDBContext context)
{
_context = context;
}
public IActionResult OnGet(string ruleName)
{
ViewData["CertificationId"] = new SelectList(_context.Certifications, "CertificationId", "CertificationName");
ViewData["CertificationRuleId"] = new SelectList(_context.CertificationRules.Where(i => i.RuleName == ruleName), "CertificationRuleId", "RuleName");
return Page();
}
[BindProperty]
public CertificationRuleCertification CertificationRuleCertification { get; set; }
public PartialViewResult OnGetCertificationPartial()
{
ViewData["CertificationId"] = new SelectList(_context.Certifications, "CertificationId", "CertificationName");
ViewData["CertificationRuleId"] = new SelectList(_context.CertificationRules, "CertificationRuleId", "RuleName");
return Partial("/Pages/Shared/_CertificationRuleCertification.cshtml");
}
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.CertificationRuleCertifications.Add(CertificationRuleCertification);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
Details.cshtml (the screen the user clicks on to trigger the modal)
#page
#model EmployeeCertification.Pages.CertificationRules.DetailsModel
#{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>CertificationRule</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
#Html.DisplayNameFor(model => model.CertificationRule.RuleName)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(model => model.CertificationRule.RuleName)
</dd>
<dt class="col-sm-2">
#Html.DisplayNameFor(model => model.CertificationRule.AppliesToAllEmployees)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(model => model.CertificationRule.AppliesToAllEmployees)
</dd>
<dt class="col-sm-2">
#Html.DisplayNameFor(model => model.CertificationRule.Active)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(model => model.CertificationRule.Active.ActiveName)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="#Model.CertificationRule.CertificationRuleId">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
<div>
<button class="btn btn-sm btn-dark details" data-id="#Model.CertificationRule.CertificationRuleId" data-toggle="modal" data-target="#details-modal">Details</button>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="details-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Product Details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body"></div>
</div>
</div>
</div>
#section scripts{
<script>
$(function () {
$('button.details').on('click', function () {
$('.modal-body').load('/certificationrulecertifications/create?handler=CertificationPartial');
});
})
</script>
}
_CertificationRuleCertification.cshtml (routed to via OnGetCertificationPartial)
#model EmployeeCertification.Pages.CertificationRuleCertifications.CreateModel
<h1>Add</h1>
<h4>Certification</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CertificationRuleCertification.CertificationRuleId" class="control-label"></label>
<select asp-for="CertificationRuleCertification.CertificationRuleId" class="form-control" asp-items="ViewBag.CertificationRuleId"></select>
</div>
<div class="form-group">
<label asp-for="CertificationRuleCertification.CertificationId" class="control-label"></label>
<select asp-for="CertificationRuleCertification.CertificationId" class="form-control" asp-items="ViewBag.CertificationId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
Create.cshtml (routed to via OnGet)
#page
#model EmployeeCertification.Pages.CertificationRuleCertifications.CreateModel
<h4>CertificationRuleCertification</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CertificationRuleCertification.CertificationRuleId" class="control-label"></label>
<select asp-for="CertificationRuleCertification.CertificationRuleId" class ="form-control" asp-items="ViewBag.CertificationRuleId"></select>
</div>
<div class="form-group">
<label asp-for="CertificationRuleCertification.CertificationId" class="control-label"></label>
<select asp-for="CertificationRuleCertification.CertificationId" class ="form-control" asp-items="ViewBag.CertificationId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
IMHO you have a bug. SelectList constructor needs an IEnumerable list as a parameter, but you use IQueryable. And create model too. You can try this
CertificationRuleCertification= new CertificationRuleCertification();
ViewData["CertificationId"] = new SelectList(_context.Certifications.ToList(), "CertificationId", "CertificationName");
ViewData["CertificationRuleId"] = new SelectList(_context.CertificationRules.ToList(), "CertificationRuleId", "RuleName");
Since you are using Razor, the code that I am suggesting should be placed not in Create page code, but in a code behind the partial page. Use OnGet or OnGetAsync for this code.
But much better variant is to use a model to keep select lists. Just add two more properties CertificationIdList and CertificationRuleIdList to the existing model.

PartialView is opening in another page

I am making a searchfield which triggers a request function returning partial view and according to result I want to show the response in partial view under the searchfield in the same page. User writes something to textfield and clicks the search button then under them result shows. I get the result but my partialview is opening in another page instead of under the searchfield in the same page. Also looks like my onClick function does not trigger.
My main View:
<div class="container">
<!-- Outer Row -->
<div class="row justify-content-center">
<div class="col-6 p-3">
<form class="form-group" method="post" action="/Books/BookDetail">
<div class="input-group">
<input type="text" name="barcodes" class="form-control bg-light border-0 small bg-gray-200" placeholder="Kitap Barkodunu giriniz..." aria-label="Search" aria-describedby="basic-addon2">
<button class="btn btn-primary" type="submit" id="myBtn" name="myBtn" onclick="showBook">
<i class="fas fa-search fa-sm"></i>
</button>
</div>
</form>
</div>
<br />
<div id="partialContent">
</div>
</div>
</div>
<script>
function showBook() {
$('#partialContent').load("/Controllers/BooksController/BookDetail");
}
</script>
Book Detail Controller:
public IActionResult BookDetail(string barcodes)
{
var request = $"?barcodes={barcodes}";
var products = _httpTool.HttpGetAsync<List<Products>>($"{AppSettings.ApiUrl}/GetProducts{request}");
if(products.Result.Count != 0)
{
ViewBag.result = "Success";
var product = products.Result[0];
return PartialView("_BookDetailPartial", product);
}
else
{
ViewBag.result = "Failed";
return View("AddBook");
}
}
_BookDetailPartial:
<div>
<h4>PartialCame</h4>
<br />
<h5>#Model.Author</h5>
</div>
What is the problem here?
Thanks in advance!
onclick="showBook"
should be
onclick="showBook()"
And this path appears to be wrong: "/Controllers/BooksController/BookDetail" it should most likely be "/Books/BookDetail?barcodes=barcode"
I'm not sure what you mean about the partial view loading in another page. Could you give some more detail please?

Pass input with route id to controller method together

I want to create input with game amount. User will write how many copy of concrete game wants to buy. Then two parameters will pass to AddToCart method. First will be gameId like below (it works well) and user amount input. How to pass these two values together into controller method?
View:
#model IEnumerable
<link rel="stylesheet" href="~/css/productcards.css">
<div class="container">
<div class="row">
#foreach (var game in Model)
{
<div class="col-md-3">
<div class="product-grid">
<div class="product-image">
<a asp-controller="Game" asp-action="ShowDetails" asp-route-productId=#game.GameId>
<img class="pic-1" src="~/images/#game.ImagePath">
</a>
</div>
<div class="product-content">
<h3 class="title">
<a asp-controller="Game" asp-action="ShowDetails" asp-route-productId=#game.GameId>#game.Title</a>
</h3>
<div class="price">#game.Price.ToString() zł</div>
<a asp-controller="Cart" asp-action="AddToCart" asp-route-gameId="#game.GameId" class="btn btn-primary"><i class="fa fa-cart-plus"></i> KUP</a>
</div>
</div>
</div>
}
</div>
</div>
Controller:
public RedirectToActionResult AddToCart(int gameId)
{
var selectedGame = _appDbContext.Games.FirstOrDefault(x => x.GameId == gameId);
if(selectedGame != null)
{
_cart.AddToCart(selectedGame, 1);
}
return RedirectToAction("Index");
}
Change your view like below:
#foreach (var game in Model)
{
<form method="post">
<div class="col-md-3">
<div class="product-grid">
<div class="product-content">
<h3 class="title">
<a asp-controller="Game" asp-action="ShowDetails" asp-route-productId=#game.GameId>#game.Title</a>
</h3>
<div class="price">#game.Price.ToString() zł</div>
<div class="amount"><input name="amount" type="number" /></div> #*add this line*#
</div>
</div>
</div>
<div class="col-md-3">
#*change <a> to <input> and add a <form>*#
<input type="submit" asp-route-gameId="#game.GameId" asp-controller="Cart" asp-action="AddToCart" class="btn btn-primary" value="KUP"/>
</div>
</form>
}
Action:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddToCart(int gameId,int amount)
{
//do your stuff...
}
Result:

Recpatcha not rendering until refresh page in Angular js

Recaptcha not rendering until I refresh the page
I'm using Recaptcha in my angular js project for security stuff.
I just implemented the captcha with following below steps:
1. I added below link to my page (in the head tag before every styles and scripts file):
<script src="https://www.google.com/recaptcha/api.js?hl=fa" async ></script>
2. In my form, I added captcha
<div class="g-recaptcha" data-sitekey="my_site_key"></div>
so my page is something like this
<html>
<head>
<title>reCAPTCHA demo: Simple page</title>
<script src="https://www.google.com/recaptcha/api.js?hl=fa" async ></script>
</head>
<body>
<form action="?" method="POST">
<div class="g-recaptcha" data-sitekey="my_site_key"></div>
<br/>
<input type="submit" value="Submit">
</form>
</body>
</html>
Apparently, everything is fine, but Recaptcha not rendering until I refresh the page. actually, it's not gonna work when the page request by ajax but after page reloading, Recaptcha will render on the page!
So how can I render Recaptcha with the first render??
I figure out how can I fix this problem.
instead of adding this script
<script src="https://www.google.com/recaptcha/api.js?hl=fa" async ></script>
to layout page, I added it in every page that I want to render captcha so after routing to the special page, in addition, to render the page content captcha will render for us too.
for exmaple the content page template will be something like this:
contactus.html content
<script src="https://www.google.com/recaptcha/api.js?hl=fa" async></script>
<form name="contactUsForm" novalidate>
<section class="well">
<div class="form-horizontal form-widgets col-sm-6">
<div class="form-group has-feedback" ng-class="{'has-error': contactUsForm.firstName.$error.required && contactUsForm.firstName.$dirty, 'has-success': !contactUsForm.firstName.$error.required }">
<label class="control-label col-sm-4" for="firstName">Name</label>
<div class="col-sm-8 col-md-6">
<input type="text" id="firstName" name="firstName" ng-model="contactUs.firstName" class="form-control" ng-class="{'form-control-error': contactUsForm.firstName.$error.required && contactUsForm.firstName.$dirty, 'form-control-success': !contactUsForm.firstName.$error.required }" placeholder="Name" required />
<span ng-show="contactUsForm.firstName.$error.required && contactUsForm.firstName.$dirty" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
<span ng-show="!contactUsForm.firstName.$error.required" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
<div class="text-danger" ng-show="contactUsForm.firstName.$error.required && contactUsForm.firstName.$dirty">Name is required</div>
</div>
</div>
<div class="form-horizontal form-widgets col-sm-12 col-sm-offset-2" style="display: flex;justify-content: flex-start;margin-bottom: 2rem;">
<div class="g-recaptcha" data-sitekey="my-sitekey"></div> <!-- Server -->
<!--<div class="g-recaptcha" data-sitekey="my-sitekey"></div>--> <!-- Local -->
</div>
<div class="buttons-wrap col-sm-offset-2" style="text-align:right;padding-right:1.6rem">
<button class="btn btn-primary" ng-disabled="contactUsForm.$invalid" data-toggle="modal" data-target="#confirmModal"><i class="glyphicon glyphicon-save"></i><span>&submit</span></button>
</div>
</section>
</form>

How to import parameters from post method

How do I get the get method called aidx parameter by post method?
When I start with the current code, it says that it is not defined.
aidx is the primary key, and I want to assign that primary key to the Family column.
<div id="blogpost" class="inner-content">
<form id="formdata"action="#Url.Action("Detail", "Board")" method="post" enctype="multipart/form-data">
<section class="inner-section">
<div class="main_blog text-center roomy-100">
<div class="col-sm-8 col-sm-offset-2">
<div class="head_title text-center">
<h2>#Html.DisplayTextFor(m => m.Article.Title)</h2>
#Html.HiddenFor(m => m.Article.ArticleIDX)
<div class="separator_auto"></div>
<div class="row">
<div class="col-md-8" style="margin-left:6%;">
<p>
<label>분 류 : </label>
#Html.DisplayTextFor(m => m.Article.Category)
</p>
</div>
<div class="col-md-8" style="margin-left:5%;">
<p>
<label>작성자 : </label>
#Html.DisplayTextFor(m => m.Article.Members.Name)
</p>
</div>
<div class="col-md-8" style="margin-left:10.6%;">
<p>
<label>작성일 : </label>
#Html.DisplayTextFor(m => m.Article.ModifyDate)
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p>
<label style="font-size:x-large;">문의내용</label>
<br />
<br />
#Html.DisplayTextFor(m => m.Article.Contents)
<br />
<br />
<br />
<br />
</p>
</div>
</div>
<div class="dividewhite2"></div>
<p>
#if (User.Identity.IsAuthenticated == true)
{
<button type="button" class="btn btn-sm btn-lgr-str" onclick="btnEdit()">수정하기</button>
<button type="button" class="btn btn-sm btn-lgr-str" onclick="btnReply()">답글달기</button>
}
<button type="button" class="btn btn-sm btn-lgr-str" onclick="javascript:history.go(-1);">목록이동</button>
<br />
<br />
<br />
<br />
</p>
<div>
#Html.Partial("_Comment", new ViewDataDictionary { { "id", Model.Article.ArticleIDX } })
#Html.Partial("_CommentView", new ViewDataDictionary { { "CommentIDX", ViewBag.CommentIDX }, { "idx", Model.Article.ArticleIDX } })
</div>
</div>
</div>
<div class="dividewhite8"></div>
</section>
</form>
<script >
function btnEdit() {
if (#User.Identity.Name.Equals(Model.Article.Members.ID).ToString().ToLower() == true)
{
location.replace("/Board/Edit?aidx=#Model.Article.ArticleIDX");
}
else
{
alert("권한이 없습니다.");
}
}
function btnReply() {
location.replace("ReplyCreate?aidx=#Model.Article.ArticleIDX");
}
[HttpGet]
public ActionResult ReplyCreate(int aidx)
{
Articles articleReply = new Articles();
return View(articleReply);
}
[HttpPost]
public ActionResult ReplyCreate(Articles replyArticles, int aidx)
{
try
{
replyArticles.Family = aidx;
replyArticles.ModifyDate = DateTime.Now;
replyArticles.ModifyMemberID = User.Identity.Name;
db.Articles.Add(replyArticles);
db.SaveChanges();
ViewBag.Result = "OK";
}
catch (Exception ex)
{
ViewBag.Result = "FAIL";
}
return View(replyArticles);
}
You have several problem in your HTML and JavaScript:
You're not submitting anything, you're redirecting the page in JavaScript.
You're hiding the button if the user is not authenticated, but everybody can see, copy, and run the URL from your JavaScript.
Even if you fix #1 and your ReplyCreate() action gets called, it's expecting 2 parameters, but you're only sending one (aidx). The other parameter (replyArticles) will be always null.
Your code is vulnerable to CSRF attack.
To fix #1, you can add the parameter to your form instead of JavaScript, and change your button's type to submit:
<form id="formdata"
action="#Url.Action("Detail", "Board", null, new { aidx = Model.Article.ArticleIDX })"
method="post" enctype="multipart/form-data">
<div class="dividewhite2"></div>
<p><button type="submit" class="btn btn-sm btn-lgr-str">답글달기</button></p>
</form>
Or you can use a hidden field.
To fix #2, move the check outside the form and delete your JavaScript:
#if (User.Identity.IsAuthenticated) {
<form id="formdata"
action="#Url.Action("Detail", "Board", null, new { aidx = Model.Article.ArticleIDX })"
method="post" enctype="multipart/form-data">
<div class="dividewhite2"></div>
<p><button type="submit" class="btn btn-sm btn-lgr-str">답글달기</button></p>
</form>
}
To fix #3, you'll have to add the replyArticles parameter to your form or as a hidden field.
To fix #4, you'll need to add the forgery check to your form and your action.

Resources