Why is my HTTP edit post method not working? - c#

When I try to submit my form, my request is not reaching the Post-method 'Edit and is returning HTTP Error Code 415.
My Razor page does not fire an action, I am using metronic theme integration and then not working post method. The following is the server-side code:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [FromForm] Firma firma)
{
//code here[enter image description here][1]
}
And the following is the client side code:
#model satinalma.Models.Firma
#{
ViewData["Title"] = "Edit";
}
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<div class="form-group">
<label asp-for="Baslik" class="control-label"></label>
<input asp-for="Baslik" class="form-control" />
<span asp-validation-for="Baslik" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

You've got the asp-action tag helper for the method, but not one for the controller. Try adding that and see if it routes properly.
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1

Related

Call POST asp-action from _layout.cshtml FORM to controller doesn't work

I have this form:
<form method="post" asp-controller="Auth" asp-action="RegisterUser">
<div class="form-group ms-1 my-1">
<input class="form-control" type="text" placeholder="Register Username" name="RegisterUsername" id="RegisterUsername"/>
</div>
<div class="form-group ms-1 my-3">
<input class="form-control" placeholder="Enter password" name="RegisterPassword" type="password" id="RegisterPassword"/>
</div>
<div class="form-group ms-1 my-3">
<input class="form-control" placeholder="Confirm password" name="registerConfirmPassword" type="password" id="RegisterConfirmPassword"/>
</div>
<div class="modal-footer">
<button type="submit" value="Submit" class="btn btn-success button button4">Register</button>
</div>
</form>
And this is found in my AuthController.cs file:
[HttpPost]
public IActionResult RegisterUser(string registerUsername, string registerPassword, string registerConfirmPassword)
{
Console.WriteLine("AAAAAAAAAAAAAAAAAAAA");
Console.WriteLine($"{registerUsername} - {registerPassword} - {registerConfirmPassword}");
return Ok();
}
Whenever I press the submit button nothing happens, please help me.
The form is in _Layout.cshtml and the post method is in another controller.

post form without refresh .net core mvc

I have a simple application in .NET Core MVC, with this simple form. When I try to post the form without refresh whole page only rest the form and got the result of done.
My code trial is:
<form asp-area="" asp-controller="ContactUs" asp-action="UserMessage" data-ajax="true">
<h5>Reach us quickly</h5>
<div class="row">
<span asp-validation-for="UserName" class="text-danger"></span>
<div class="col-sm-6 col-12">
<div class="form-group">
<input asp-for="UserName" class="form-control" name="UserName" placeholder="Enter name" required="required">
</div>
</div>
<span asp-validation-for="Email" class="text-danger"></span>
<div class="col-sm-6 col-12">
<div class="form-group">
<input asp-for="Email" class="form-control" name="Email" placeholder="Enter email" required="required">
</div>
</div>
</div>
<div class="row">
<span asp-validation-for="Msg" class="text-danger"></span>
<div class="col-12">
<div class="form-group">
<textarea asp-for="Msg" name="Msg" class="form-control" rows="7" cols="25" placeholder="Message"></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 mt-3">
<button type="submit" class="btn solid-btn" id="btnContactUs">
Send Message
</button>
</div>
</div>
</form>
and my action is:
[HttpPost]
public async Task<IActionResult> UserMessage(ContactUs model)
{
try
{
if (ModelState.IsValid)
{
_context.Add(model);
await _context.SaveChangesAsync();
return NoContent();
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return NoContent();
}
I want to change return NoContent(); so I can show a message to the user that his message has sent or failed, without refreshing the whole page.
Your form tag is missing some other ajax attributes:
<form method="post"
data-ajax="true"
data-ajax-method="post"
data-ajax-url="#Url.Page("UserMessage", "ContactUs")"
data-ajax-loading="#loading"
data-ajax-mode="replace"
data-ajax-update="#updateDiv">
<!-- form controls -->
<button type="submit" class="btn solid-btn" id="btnContactUs">Send Message</button>
<span id="loading" style="display:none;"> <i class="fas fa-spinner fa-spin"></i></span>
</form>
<div id="updateDiv">
<!-- ajax content will load here -->
<!-- you can put the form inside this div -->
<!-- so after submit the result will replace the form controls -->
</div>
<!-- include jquery libraries -->
#section Scripts {
<script src="https://cdn.jsdelivr.net/npm/jquery#3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-ajax-unobtrusive#3.2.6/dist/jquery.unobtrusive-ajax.min.js"></script>
}
The backend method can return the result as below:
public async Task<ContentResult> OnPostUserMessageAsync(ContactUs model)
{
try
{
if (ModelState.IsValid)
{
_context.Add(model);
await _context.SaveChangesAsync();
return Content("done");
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return Content("something went wrong...");
}
See Ajax Request Using Inline Attributes
If you don't want the page to be replaced, you'll have to use ajax to post the data via javascript. Posting a form in a browser will replace the current html with the result of the controller, that's just how forms work.
It is also common practice to redirect any successful POST to a different page, so that the user can refresh that page without processing the POST request twice.
thanks for #Laz Ziya i have used his code and modify form to be
instead of
<form method="post"
data-ajax="true"
data-ajax-method="post"
data-ajax-url="#Url.Page("UserMessage", "ContactUs")"
data-ajax-loading="#loading"
data-ajax-mode="replace"
data-ajax-update="#updateDiv">
to be
<form asp-area="" asp-controller="ContactUs" asp-action="UserMessage" data-ajax-loading="#loading" data-ajax-mode="replace" data-ajax-update="#updateDiv" data-ajax-success="Success" data-ajax-failure="Failure" data-ajax="true">
for post form without refresh ,you need to use ajax in your code.

ASP.NET core 2.2 Unhandled exception when creating a form

I am currently creating a web application that takes in a new user, adds their information to a list, and then displays the users. When I follow the link to my form with validation (a form I have used many times before in other projects) I am getting an unhandled exception.
Here is the specific error code
AspNetCore.Views_Home_RegisterNewUser.<ExecuteAsync>b__12_0() in RegisterNewUser.cshtml, line 15
To this point, I have double checked that the model is correct and has the correct validation. I have made sure the controller and action are correct.
Here is the page for the form
#{
ViewData["Title"] = "RegisterNewUser";
}
<h1>RegisterNewUser</h1>
#model Lab20.Models.RegisterUser
#Html.ValidationSummary()
<form asp-controller="Home" asp-action="ListAllUser" method="post" class="bg-dark">
<div class="col-12">
First Name:
<input type="text" name="FirstName" value="#Model.FirstName" placeholder="#Model.FirstName" class="col-5" />
#Html.ValidationMessageFor(m => m.FirstName)
</div>
<div class="col-12">
Last Name: <input type="text" name="Last Name" value="#Model.LastName" placeholder="#Model.LastName" class="col-5" />
#Html.ValidationMessageFor(m => m.LastName)
</div>
<div class="col-12">
Birthday: <input type="datetime" name="Birthday" value="#Model.Birthday" placeholder="#Model.Birthday" class="col-5" />
#Html.ValidationMessageFor(m => m.Birthday)
</div>
<div class="col-12">
Email: <input type="text" name="Email" value="#Model.Email" placeholder="#Model.Email" class="col-5" />
#Html.ValidationMessageFor(m => m.Email)
</div>
<div class="col-12">
Password: <input type="text" name="Password" value="#Model.Password" placeholder="#Model.Password" class="col-5" />
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="col-12">
Favorite Color: <input type="text" name="FavoriteColor" value="#Model.FavoriteColor" placeholder="#Model.FavoriteColor" class="col-5" />
#Html.ValidationMessageFor(m => m.FavoriteColor)
</div>
<input type="submit" value="Add User" />
</form>
Here is the HomeController
public class HomeController : Controller
{
List<RegisterUser> listOfUsers = new List<RegisterUser>() { };
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult RegisterNewUser()
{
return View();
}
[HttpPost]
public IActionResult RegisterNewUser(RegisterUser newUser)
{
if (!ModelState.IsValid)
{
return View(newUser);
}
else
{
return View("AddNewUser", newUser);
}
}
public IActionResult AddNewUser(RegisterUser user)
{
listOfUsers.Add(user);
return View("Index");
}
public IActionResult ListAllUsers()
{
return View();
}
}
I would like my page to firstly, display, secondly, catch the validation I have added, and thirdly take the new user's information and display it in the ListAllUsers View.
<form asp-controller="Home" asp-action="RegisterNewUser" method="post" class="bg-dark">
</form>
your form post action will be in RegisterNewUser method, you're pointing it wrong in ListAllUsers.
hope, you get it
You form is posing to the action ListAlluser in the controller Home. Now according to your code, you don't have an action method by that name.
The correct asp-action parameter should be RegisterNewUser. So the code becomes
<form asp-controller="Home" asp-action="RegisterNewUser" method="post" class="bg-dark">
</form>

ASP.NET MVC: Why request is being caught by the wrong method?

I'm using to wrap my forms the following helper:
#using (Html.BeginForm("Edit", "MyController", FormMethod.Post)) { ... }
In my Controller I have two methods, one for loading my partial view and another one for processing the Post request:
[SomeFilter]
[ChildActionOnly]
[AcceptVerbs(HttpVerbs.Get)]
public PartialViewResult Edit(int id)
{
//Some Code
}
[SomeFilter]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MyViewModel model, string submit) {
//Some Code
}
Everything seems to be working fine except when users submit an empty form. In that case request is being caught by GET Method instead of POST one. I know it's calling the GET method because I get an exception as:
"The action 'Edit' is accessible only by a child request."
And only the GET overload has [ChildActionOnly] filter. I don't understand why is this happening. Both are different and both are decorated.
Any suggestions?
Partial View code:
#model MVC.Models.MyViewModel
#using (Html.BeginForm("Edit", "MyController", FormMethod.Post))
{
#Html.HiddenFor(m => m.Id)
#Html.AntiForgeryToken()
<div class="row margin-top-20 form-group text-center">
<div class="col-md-3 col-lg-offset-2">
#Html.LabelFor(m => m.ManyItemsAvailable)
#Html.ListBox("ManyItemsAvailable", Model.ItemsAvailable)
</div>
<input type="submit" class="btn btn-default" value=">" id="add" name="submit" />
<input type="submit" class="btn btn-default margin-top-10" value="<" id="remove" name="submit" />
<div class="col-md-3">
#Html.LabelFor(m => m.ManyItemsSelected)
#Html.ListBox("ManyItemsSelected", Model.ItemsSelected)
</div>
</div>
}
So, I replaced both submit buttons with these:
<input type="submit" class="btn btn-default" value=">" id="add" name="submit" />
<input type="submit" class="btn btn-default margin-top-10" value="<" id="remove" name="submit" formmethod="post" />
Explicitly specifying formmethod="post" and it's now working as expected.

How I can use html tags with bootstrap in asp.net mvc for get a result from controller?

Hey Guys I have a problem with my ASP.NET MVC Application. I want to make a Search textfield and a image button in my application. If I input a valu in the textfield I want use this value for search in a list and send the result to the View. I use bootstrap because it looks fine.
here is my code: Index.cshtml
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Search", "HomeController"))
{
<div class="container">
<div class="row">
<h2>Suche</h2>
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" id="txtSearch" class=" search-query form-control" placeholder="Search" name="txtSearch" />
<span class="input-group-btn">
<button class="btn btn-danger" type="submit">
<span class=" glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
</div>
</div>
}
Here is my Controller:
[HttpPost]
public ActionResult Search(string txt)
{
List<string> petList = new List<string>();
petList.Add(txt);
ViewBag.liste = petList;
return View();
}
Your input does not have a name attribute that matches the parameter in the method so it is not bound. Change it to
<input type="text" id="txtSearch" class="..." name="txt" />
or change the method to match the current name attribute
[HttpPost]
public ActionResult Search(string txtSearch)
Side note: Assuming your controller is named HomeController then it should be #using (Html.BeginForm("Search", "Home")), not #using (Html.BeginForm("Search", "HomeController")) (which would only work if you have a controller named HomeControllerController)

Categories