ASP.NET MVC Unknown Action when delete is pressed - javascript

I have a problem, when I try to delete something, it gives me the following error message:
"Error: Unknown Action"
This is my controller:
[Authorize(Roles = "Admin, Staff")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int? id)
{
string result = null;
try
{
if (id == null)
{
result = HIQResources.errorMessageUnknownAction;
return new JsonResult { Data = result };
}
StudentViewModel vm = new StudentViewModel();
StudentDetail studentDetail = studentManager.GetStudentDetailById(id.Value);
if (studentDetail == null)
{
result = HIQResources.errorMessageUnknownRecord;
return new JsonResult { Data = result };
}
int deleteResult = studentManager.Delete(id.Value);
if (deleteResult == 1)
{
vm.Alert.SetSuccessMessage(HIQResources.messageOperationSuccess);
TempData["alert"] = vm.Alert;
result = HIQResources.messageOperationSuccess;
return new JsonResult { Data = result };
}
else
{
vm.Alert.SetErrorMessage(HIQResources.errorMessageUnableToExecuteOperation);
TempData["alert"] = vm.Alert;
result = HIQResources.errorMessageUnableToExecuteOperation;
return new JsonResult { Data = result };
}
}
catch (DbUpdateException ex)
{
Log.AddLogRecord(LogManager.LogType.Warning, LogManager.LogPriority.Low, LogManager.LogCategory.Teacher, ex.Message, ex.StackTrace, base.GetLoggedUser());
result = HIQResources.errorMessageUnableToDeleteRecord;
return new JsonResult { Data = result };
}
catch (Exception ex)
{
Log.AddLogRecord(LogManager.LogType.Error, LogManager.LogPriority.High, LogManager.LogCategory.Inscription, ex.Message, ex.StackTrace, base.GetLoggedUser());
result = HIQResources.errorMessageExceptionOccurred;
return new JsonResult { Data = result };
}
}
This is my Javascript:
$('#ModalDeleteButton').on("click", function (e) {
var token = $('input[name="__RequestVerificationToken"]').val();
$.post("/Student/Delete/",
{
__RequestVerificationToken: token,
id: id
},
function (data) {
$('#myModal .close').click();
var baseurl = '#Url.Action("Index")';
var url = baseurl + "?message=" + data;
window.location.href = url;
});
});
I would need more specific details on this error, it seems to me that the controller and the javascript is right, so I don't really know what possibly can be.

If you're going to call $.post then you need to put the [HttpPost] attribute above the method definition. Otherwise, it just assumes that method is actually a GET (which is why the action is "unknown")
EDIT:
Try changing your $.post to this:
$.ajax({
type: "POST",
data: {
__RequestVerificationToken: token,
id: id
},
success: function(data) {
$('#myModal .close').click();
var baseurl = '#Url.Action("Index")';
var url = baseurl + "?message=" + data;
window.location.href = url;
}
});

Related

Json Not hitting controller

In My code to save Order JSON not hitting controller also there is no Error appearing even in
Browser Console, Only I am getting Error: Order Not Complete!
My controller:
public ActionResult SaveOrder([FromBody]string name, string address, Order[] order)
{
//var settings = new JsonSerializerSettings();
string result = "Error! Your Order Is Not Complete!";
try
{
if (name != null && address != null && order != null)
{
var cutomerId = Guid.NewGuid();
Customer model = new();
model.CustomerId = cutomerId;
model.Name = name;
model.Address = address;
model.OrderDate = DateTime.Now;
db.Customers.Add(model);
foreach (var item in order)
{
var orderId = Guid.NewGuid();
Order O = new();
O.OrderId = orderId;
O.ProductName = item.ProductName;
O.Quantity = item.Quantity;
O.Price = item.Price;
O.Amount = item.Amount;
O.CustomerId = cutomerId;
db.Orders.Add(O);
}
db.SaveChanges();
result = "Successfully! Order Is Complete!";
}
return Json(result);
}
catch (Exception)
{
throw;
}
}
And here is the JavaScript Code:
function saveOrder(data) {
return $.ajax({
contentType : 'application/json; charset=utf-8',
dataType : 'json',
type : 'POST',
url : "/Orders/SaveOrder",
data : data,
success : function (result) {
alert(result);
location.reload();
},
error : function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveOrder").click(function (e) {
e.preventDefault();
var orderArr = [];
orderArr.length = 0;
$.each($("#detailsTable tbody tr"), function () {
orderArr.push({
productName : $(this).find('td:eq(0)').html(),
quantity : $(this).find('td:eq(1)').html(),
price : $(this).find('td:eq(2)').html(),
amount : $(this).find('td:eq(3)').html()
});
});
var data = JSON.stringify({
name : $("#name").val(),
address : $("#address").val(),
order : orderArr
});
$.when(saveOrder(data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
I am reading and searching But couldn't find any difference in my code or even knows my mistake, that is why I seeking Help from you please
It looks like you are trying to bind all three arguments [FromBody]string name, string address and Order[] order to the JSON body of your request, but as explained in .NET Core Web API: multiple [FromBody]? you can only have one [FromBody] parameter as the body can only be read once.
Instead, create a top-level DTO corresponding to the JSON in your body, and bind to that:
public class SaveOrderRequestModel
{
public string name { get; set; }
public string address { get; set; }
public Order[] order { get; set; }
}
and then
public ActionResult SaveOrder([FromBody] SaveOrderRequestModel saveOrderRequest)
{
string result = "Error! Your Order Is Not Complete!";
var (name, address, order) = (saveOrderRequest?.name, saveOrderRequest?.address, saveOrderRequest?.order);
if (name != null && address != null && order != null)
{
// Proceed as before
As #dbc said,you can only have one [FromBody] parameter as the body can only be read once.
I think your error may be due to the incorrect JSON format, the controller does not receive the parameters passed by Ajax, you can check if your Json body is like this when it is passed:
Below is my test code,you can refer to it:
View:
#model _2022072501.Models.OrderDTO
<button id="saveOrder" class="btn btn-primary">submit</button>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script>
function saveOrder(data) {
$.ajax({
contentType : 'application/json; charset=utf-8',
dataType : 'json',
type : 'POST',
url : "/Home/SaveOrder",
data : data,
success : function (result) {
alert(result);
location.reload();
},
error : function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveOrder").click(function (e) {
e.preventDefault();
debugger;
var orderArr = [];
orderArr.push({
productName : "Test1",
quantity : "Test1"
});
orderArr.push({
productName : "Test2",
quantity : "Test2"
});
var data = JSON.stringify({
name : "testName",
address : "testAdress",
order : orderArr
});
$.when(saveOrder(data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
</script>
Controller:
public IActionResult SaveOrder([FromBody] OrderDTO orderDTO)
{
//var settings = new JsonSerializerSettings();
string result = "Error! Your Order Is Not Complete!";
var (name, address, order) = (orderDTO?.name, orderDTO?.address, orderDTO?.order);
try
{
if (name != null && address != null && order != null)
{
foreach (var item in order)
{
var orderId = Guid.NewGuid();
Order O = new();
O.OrderId = orderId;
O.ProductName = item.ProductName;
O.Quantity = item.Quantity;
//db.Orders.Add(O);
}
//db.SaveChanges();
result = "Successfully! Order Is Complete!";
}
return Json(result);
}
catch (Exception)
{
throw;
}
}
You can cancel your $.each like me and change it to a fixed value, maybe it's more convenient to find the problem

How to call IActionResult from Javascript?

I have an ASP.NET Application and want to call this IActionResult method from the HomeController:
public IActionResult ReadNewestFile(FileInfo filePath) {
String st = System.IO.File.ReadAllText(filePath.ToString());
ChartData chartData = new ChartData();
string[] lines = st.Split("\n");
foreach (var line in lines) {
string[] values = line.Split(',');
try {
chartData = new ChartData {
Timestamp = Convert.ToDateTime(values[0] + "." + values[1]),
Function = Convert.ToString(values[2]),
Duration = Convert.ToInt32(values[4]),
IsError = Convert.ToBoolean(values[5])
};
db.ChartDatas.Add(chartData);
db.SaveChanges();
}
catch (Exception exc) {
exc.ToString();
}
}
return View(chartData);
}
Now I want to get the return value of this method in the site.js file:
$.ajax({
type: "GET",
url: "Home/ReadNewestFile",
success: function(data) {
console.log(data);
}
});
When I try it like this, the browser says "500 Internal Error". Any ideas to solve this problem?

Pass javascript array to c# array/list using $.post without specifing datatype as json

I have a model created in javascript as follows
function Vehicle() {
this.type = 'Vehicle';
this.data = {
VehicleKey: null
}
};
I have a similar model created in c# as follows
public class Vehicle
{
public string VehicleKey { get; set; }
}
Now I am building an array of VehicleKeys in javascript as follows
function GetVehicleDetails(inputarray) {
var vehicleKeys = [];
for (var i = 0; i < inputarray.length; i++) {
var vehicleObject = new Vehicle();
vehicleObject.data.VehicleKey = inputarray[i].VehicleKey ? inputarray[i].VehicleKey : null;
vehicleKey.push(vehicleObject.data);
}
return vehicleKeys ;
}
I am calling the $.post(url, data) as follows
var objectToSend = GetVehicleDetails(selectedVehicles);
var data = JSON.stringify({
'vehicles': objectToSend
});
$.post(url, data)
.done(function (result) {
if (result) {
download(result, 'VehicleReport.xlsx', { type: 'application/octet-stream' });
console.log("Report created successfully");
}
else {
console.log("Error creating report");
}
}).fail(function (error) {
console.log("Error creating report.");
});
The MVC Controller has a method to accept Vehicles with multiple VehicleKeys coming from javascript
public byte[] CreateVehicleReport(List<Vehicle> vehicles)
{
//Generation of report and pass it back to javascript
}
Here I am able to submit the data in javascript as 10 and 11 for Vehicles but when it catches the c#, the count is coming as 0.
Any help would be greatly appreciated.
$.post is not posted Content-Type json data so you need to use $.ajax
function GetVehicleDetails(inputarray) {
var vehicleKeys = [];
for (var i = 0; i < inputarray.length; i++) {
var vehicleObject = {}; // Set Object
vehicleObject.VehicleKey = inputarray[i].VehicleKey ? inputarray[i].VehicleKey : null;
vehicleKeys.push(vehicleObject);
}
return vehicleKeys;
}
var objectToSend = GetVehicleDetails(selectedVehicles);
$.ajax({ type: 'POST',
url: url,
data: JSON.stringify(objectToSend),
contentType: "application/json",
dataType: 'json',
success: function (data) {
alert('data: ' + data);
},
}).done(function () {
if (result) {
console.log("Report created successfully");
}
else {
console.log("Error creating report");
}
}).fail(function () {
console.log("Error creating report.");
});
C# Method
[HttpPost("CreateVehicleReport")]
public byte[] CreateVehicleReport([FromBody]List<Vehicle> vehicles)
{
return null;
//Generation of report and pass it back to javascript
}
I used a similar approach once but with ajax and it went like this:
fill your array directly with the properties inside your class as object { } make sure the names are exactly the same:
function GetVehicleDetails(inputarray) {
var data_Temp = [];
for (var i = 0; i < inputarray.length; i++) {
var _vehiclekey = inputarray[i].VehicleKey ? inputarray[i].VehicleKey : null;
data_Temp.push({ VehicleKey : _vehiclekey });
});
return data_Temp;
}
var objectToSend = GetVehicleDetails(selectedVehicles);
var JsonData = JSON.stringify({ vehicles: objectToSend });
$.ajax({
type: "POST",
contentType: "application/json",
url: "/controllerName/actionName", //in asp.net using mvc ActionResult
datatype: 'json',
data: JsonData,
success: function (response) {
},
error: function (response) {
console.log(response);
}
});
And the ActionResult in the controller should look like this:
[HttpPost]
public ActionResult Create(List<Vehicle> vehicles)
{
//do whatever you want with the class data
}
I don't know if this is helpful for you but this always works for me and i hope it helps.

MVC Controller JsonResult error Server cannot set content type after HTTP headers have been sent, while return

Have this function in a Controller:
public async Task<JsonResult> getTipoPerfil(int id)
{
PerfilesCalificacion pc = await db.PerfilesCalificaciones.FindAsync(id);
int ret = -1;
if (pc!=null)
{
switch (pc.Tipo)
{
case TipoCalificacion.NotaGlobal:
ret = 0;
break;
case TipoCalificacion.PerfilCalificacion:
ret = 1;
break;
default:
ret = -1; ;
break;
}
}
return new JsonResult { Data = ret };
}
In the return line above I'm getting the error.
I searched a lot but I cannot find the solution.
This function it is called by a JS function. This is part of the HTML (cshtml):
.
.
.
#Html.DropDownListFor(model => model.ApiTdEx.PerfilCalificacionId, (List<SelectListItem>)ViewBag.LstPerfiles, new { #class = "form-control", #onchange = "MuestraPerfil()" })
.
.
.
<script>
function MuestraPerfil() {
var idperfil = document.getElementById("ApiTdEx_PerfilCalificacionId").value;
$.ajax({
type: 'POST',
url: '#Url.Action("getTipoPerfil", "MenuProfesor")',
dataType: 'json',
data: { id: $("#ApiTdEx_PerfilCalificacionId").val() },
success: function (tipo) {
alert(tipo);
},
error: function (request, status, error) {
alert(error);
}
});
}
</script>
I have some code in global.asax that maybe have some relation:
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.BufferOutput = true;
string culture = null;
if (context.Request.UserLanguages != null && Request.UserLanguages.Length > 0)
{
culture = Request.UserLanguages[0];
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
}
}
Thanks a lot!

Getting Null object array jquery post

I am new to Angular.js framework. I am getting data which i am further assigning to array using angular scope.
Modal.CS:
public class AppSetting1
{
public int lng_AppSettings { get; set; }
public string str_SettingName { get; set; }
public string str_SettingValue { get; set; }
public string str_Type { get; set; }
public AppSetting1(int _lng_AppSettings, string _str_SettingName, string _str_SettingValue, string _str_Type)
{
lng_AppSettings = _lng_AppSettings;
str_SettingName = _str_SettingName;
str_SettingValue = _str_SettingValue;
str_Type = _str_Type;
}
}
internal string GetAppSettings()
{
try
{
List<AppSetting1> objAppsettings = new List<AppSetting1>();
objAppsettings.Add(new AppSetting1(1,"Name1","Value1","Type"));
objAppsettings.Add(new AppSetting1(2, "Name2", "Value2", "Type2"));
return JsonConvert.SerializeObject(objAppsettings, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
}
catch (Exception ex)
{
throw ex;
}
}
Controller.CS:
[AuthCheckService, SessionCheckService]
[HandleModelStateException]
public string GetAppSettings()
{
try
{
ManageAppSettings accExec = new ManageAppSettings();
return accExec.GetAppSettings();
}
catch (Exception ex)
{
throw new ModelStateException(ex.Message, ex.InnerException);
}
}
[HttpPost]
public JsonResult SaveSettings(List<AppSetting1> AppSetting)
{
try
{
ManageAppSettings accExec = new ManageAppSettings();
return Json(AppSetting, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
throw new ModelStateException(ex.Message, ex.InnerException);
}
}
Angular.js:
(function () {
var app = angular.module('myAppSeetings', []);
app.controller('AppSettingsController', function ($scope) {
$scope.items = [];
$scope.SaveSettings = function () {
if (validate()) {
var token = $('[name=__RequestVerificationToken]').val();
var test = $scope.items;
$.ajax({
beforesend: showProgress(),
type: 'POST',
headers: { "__RequestVerificationToken": token },
url: getAppPath() + 'AppSettings/SaveSettings',
dataType: 'json',
data: { AppSetting: $scope.items },
success: function (result) {
if (result != "") {
//ShowSaveMessage(result);
//fetchData();
//$('#EditPopUp').css('display', 'none');
//$('#exposeMaskManageUser').css('display', 'none');
//clearForm();
}
else
ShowErrorPopup('An error has occurred. Please contact System Administrator.');
},
complete: hideProgress,
error: function (ex) {
ShowErrorPopup('An error has occurred. Please contact System Administrator.');
}
});
}
else {
ShowWarningMessage('Required fields must be completed prior to completing the work');
}
};
function fetchData() {
var token = $('[name=__RequestVerificationToken]').val();
$.ajax({
beforesend: showProgress(),
type: 'GET',
headers: { "__RequestVerificationToken": token },
url: getAppPath() + 'AppSettings/GetAppSettings',
dataType: 'json',
success: function (data) {
// console.log(data);
$scope.items = data;
$scope.$apply();
console.log($scope.items);
},
complete: hideProgress,
error: function (ex) {
ShowErrorPopup('An error has occurred. Please contact System Administrator.');
}
});
};
function validate() {
var val = true;
if ($("input").val().trim() == "") {
val = false;
}
return val;
}
fetchData();
});
})();
Problem:
On save click i am getting null on server side. Where i am going wrong here?
Try adding
contentType: 'application/json; charset=utf-8',
See this answer
Your code wrong here:
data: { AppSetting: $scope.items }
It should be
data: $scope.items
In your saveClick function: $scope.items now is []. It should have some values as you expect. Depend on your case it is from client or a default value for testing:
$scope.items = [{lng_AppSettings: 1, str_SettingName : 'Name 1'},
{lng_AppSettings: 2, str_SettingName : 'Name 2'}];

Categories

Resources