How to import parameters from post method - asp.net

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.

Related

my update method in Dbset does not working and it just add another row in database

I am trying to learn web development with asp.net 6 and I'm trying to update a category that I created .I've written a get and a post method but it just doesn't working in Edit action and it is adding a new row in database instead of updating.
this is my edit action in category controller
//GET
public IActionResult Edit(int? id)
{
if(id == null || id == 0)
{
return NotFound();
}
var CategoryFromDb = _db.Categories.Find(id);
if (CategoryFromDb == null)
{
return NotFound();
}
return View(CategoryFromDb);
}
//POST
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Category obj)
{
if (obj.Name == obj.DisplayOrder.ToString())
{
ModelState.AddModelError("name", "The DisplayOrder cannot exactly match the Name.");
}
if (ModelState.IsValid)
{
_db.Categories.Update(obj);
_db.SaveChanges();
return RedirectToAction("Index", "Category");
}
return View(obj);
}
}
this is my Edit.cshtml
#model Category
<form method="post" asp-action="Edit">
<div class="border p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary">Edit Category</h2>
<hr/>
<div asp-validation-summary="All"></div>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="Name"></label>
<input style="width: 100%;clear: both;" asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-bg-danger"></span>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="DisplayOrder"></label>
<input style="width: 100%;clear: both;" asp-for="DisplayOrder" class="form-control" />
<span asp-validation-for="DisplayOrder" class="text-bg-danger"></span>
</div>
<button type="submit" class="btn btn-primary" style="width:150px;">Update</button>
<a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">Back to List</a>
</div>
</form>
and this is my category model
public class Category
{
[Key]
public int? CategoryID { get; set; }
[Required]
public string Name { get; set; }
[DisplayName("Display Order")]
[Range (1,100,ErrorMessage ="Not in Range of Display Order")]
public int DisplayOrder { get; set; }
public DateTime CreatedDateTime { get; set; } = DateTime.Now;
}
and this is my index view part that I created Edit button
<div class="w-75 btn-group" role="group">
<a asp-controller="Category" asp-action="Edit" asp-route-id ="#obj.CategoryID" ><i class="bi bi-pencil"></i>Edit</a>
</div>
and it's adding a new row to database instead of updating the database based on the primary key
please help me...
thanks
Your main issue is that you're not filling in the model correctly - namely, your View doesn't fill in the CategoryID, so the controller doesn't "know" which Category to update. You need to modify your View similar to this (I've added the line right below <form>):
#model Category
<form method="post" asp-action="Edit">
#Html.HiddenFor(m => m.CategoryID)
<div class="border p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary">Edit Category</h2>
<hr/>
<div asp-validation-summary="All"></div>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="Name"></label>
<input style="width: 100%;clear: both;" asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-bg-danger"></span>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="DisplayOrder"></label>
<input style="width: 100%;clear: both;" asp-for="DisplayOrder" class="form-control" />
<span asp-validation-for="DisplayOrder" class="text-bg-danger"></span>
</div>
<button type="submit" class="btn btn-primary" style="width:150px;">Update</button>
<a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">Back to List</a>
</div>
</form>

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?

Download text file via ASP.NET MVC dynamically changed

I have to generate file depending on input (checkboxes) and download it:
[HttpGet]
public FileResult GenerateFormatSettingsFile(IEnumerable<string> values)
{
var content = FileSettingsGenerator.Generate(values);
MemoryStream memoryStream = new MemoryStream();
TextWriter tw = new StreamWriter(memoryStream);
tw.WriteLine(content);
tw.Flush();
tw.Close();
return File(memoryStream.GetBuffer(), "text/plain", "file.txt");
}
And on my view this:
<button id="GenetateFormatSettingsFile" class="btn btn-primary" data-dismiss="modal" style="margin-right: 1500px">Generate</button>
$(document).ready(function() {
$("#GenetateFormatSettingsFile").click(function() {
var f = {};
var checkboxes = [];
$('input:checked').each(function() {
checkboxes.push($(this).attr("value"));
});
f.url = '#Url.Action("GenerateFormatSettingsFile", "Home")';
f.type = "GET";
f.dataType = "text";
f.data = { values: checkboxes},
f.traditional = true;
f.success = function(response) {
};
f.error = function(jqxhr, status, exception) {
alert(exception);
};
$.ajax(f);
});
});
</script>
The problem is the download doesn't start. How could I fix it?
If I do it with Html.ActionLink, the download starts, but I can't pass the values of checkboxes which is done by my ajax function above
Thanks!
Edit - that's how my check-boxes looks like:
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="modal" id="formatterSettings" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Settings</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="defaultG">To default view</label>
<input class="form-control" type="checkbox" value="Default" id="defaultG">
</div>
<div class="form-group">
<label for="extendedG">To extended view</label>
<input class="form-control" type="checkbox" value="Extended" id="extendedG">
</div>
/div>
</form>
</div>
<div class="modal-footer">
<div class="col-md-6">
<button id="GenetateFormatSettingsFile" class="btn btn-primary" data-dismiss="modal" style="margin-right: 1500px">Generate</button>
#Html.ActionLink("Generate!", "GenerateFormatSettingsFile")
</div>
<div class="col-md-6">
<a class="btn btn-primary" data-dismiss="modal" >Generate From Code</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Put a submit button in your form and POST your form synchronously (without ajax).
when a form is posted, values of all input elements (TextBoxes, CheckBoxes, ...) are sent to the server (with the request) and you don't need to do anything.

When model is not valid, return to partial view inside a view, with error message using asp.net core

I´ve got a modal boostrap. I want to show the error of validation on boostrap modal. But when I leave the model empty and click on submit button Its just viewed as a standalone page.
Partial view:
#model WebApplication1.Models.Book
<form asp-controller="Home" asp-action="AddBook"
data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#frmaddbook">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Header of Modal</h4>
</div>
<div class="modal-body form-horizontal" id="frmaddbook ">
<span class="alert-danger">
#Html.ValidationSummary()
</span>
<div class="row">
<div class="form-group">
<label asp-for="BookName" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookName" class="form-control" />
<span asp-validation-for="BookName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="BookDescription" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookDescription" class="form-control" />
<span asp-validation-for="BookDescription" class="text-danger"></span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
Index View :
<div class="panel panel-primary">
<div class="panel-body">
<div class="btn-group">
<a class="btn btn-primary marginbutoon" id="showBookgroup" data-toggle="modal" asp-action="AddBook"
data-target="#modal-book">
<i class="glyphicon glyphicon-plus"></i>
Add Book
</a>
</div>
</div>
i use this libraries at top of index view:
jquery.unobtrusive-ajax.min.js
jquery.validate.unobtrusive.min.js
and use at the bottom of index view:
<script src="~/js/book-index.js"></script>
book-index.js:
(function ($) {
function Home() {
var $this = this;
function initilizeModel() {
$("#modal-book").on('loaded.bs.modal', function (e) {
}).on('hidden.bs.modal', function (e) {
$(this).removeData('bs.modal');
});
}
$this.init = function () {
initilizeModel();
}
}
$(function () {
var self = new Home();
self.init();
})
}(jQuery))
Controller:
[HttpGet]
public IActionResult AddBook()
{
var b = new Book();
return PartialView("_AddBook", b);
}
[HttpPost]
[ValidateAntiForgeryToken]
//[HandleError]//not in core
public IActionResult AddBook(Book model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return PartialView("_AddBook", model);
}
Model :
public class Book
{
[Key]
public int BookId { get; set; }
[Display(Name = "Book Name :")]
[Required(ErrorMessage = "Enter Book Name Please ")]
public string BookName { get; set; }
[Display(Name = "Book Description")]
[Required(ErrorMessage = "Enter Book Description Please ")]
public string BookDescription { get; set; }
}
My code is shown above. How can i show validation error in modal partial view ?
You can set the Id of form as the data-ajax-update property value of the form , which is ajaxified. This value will be used as the jQuery selector when the result is received from the ajax call.
#model Book
<form asp-controller="Home" asp-action="AddBook" id="myform"
data-ajax="true" data-ajax-method="POST"
data-ajax-mode="replace" data-ajax-update="#myform">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Add Book</h4>
</div>
<div class="modal-body form-horizontal" id="frmaddbook ">
<span class="alert-danger">
#Html.ValidationSummary()
</span>
<div class="row">
<div class="form-group">
<label asp-for="BookName" class="col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookName" class="form-control" />
<span asp-validation-for="BookName" class="text-danger"></span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</form>
Now when you submit the form and model state validation fails, the action method code will return the partial view result with the validation error messages (generated by the validation helpers) and the jquery.unobtrusive-ajax.js library code will replace (because we specified that with data-ajax-mode="replace") the content of the result of the jquery selector #data-ajax-update (the form tag and it's inner contents) with the response coming back from the server.

Post back Method not get call on button click in MVC4

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

Resources