Why Javascript POST Request to ASP.NET controller action getting NULL parameter? - javascript

The parameters of my ASP .NET controller method stays null when I send a XmlHttpRequets from my JavaScript file. The JavaScript debugger shows that the request sends successfully. Why is It not working?
JavaScript function:
function BuyBook(title) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", "home/BuyBook", true);
xmlHttp.setRequestHeader("Content-Type", "multipart/form-data");
var order = { BookTitle: title, Quantity: document.getElementById("quantity").value };
xmlHttp.send(JSON.stringify({ order: order }));
console.log(xmlHttp.responseText);
}
Controller method:
[HttpPost]
public IActionResult BuyBook(Models.Order order)
{ .... }
Models.Order class:
public class Order
{
[Required]
public string BookTitle { get; set; }
[Range(1,100)]
public int Quantity { get; set; }
}

Try the following things:
Check that the class signature matches the JSON being sent. For above example, the JSON being sent would look like
{ "BookTitle": title, "Quantity": "value" }
Also I see that the class defines Quantity as int, so use parseInt() to convert Quantity value into int. By default document.getElementById(..).value would give a string.
let quantity = parseInt(document.getElementById("quantity").value);
var order = { BookTitle: title, Quantity: quantity };
Use Content-Type as application/json
Add [FromBody] attribute to the model
BuyBook([FromBody]Models.Order order)
Send the order object like below.
xmlHttp.send(order);
OR
xmlHttp.send(JSON.stringify(order));

Update your method like this:
[HttpPost]
public IActionResult BuyBook([FromBody] Models.Order order)
{ .... }
You can find more information here

Related

Print model data without saving

if (saleDetails.length) {
var htmlData;
var paymentStatus = 0;
if ($('#PaymentStatus option:selected').val() != 0) {
paymentStatus = $('#PaymentStatus option:selected').text()
}
var SaleAmount = parseFloat(total + vat).toFixed(2);
var data = {
'AccountID': $('#hdnAccountID').val(),
'QuoteID': $('#hdnQuoteID').val(),
'BranchID': $('#BranchID option:selected').val(),
'PONO': $('#PONO').val(),
'PaymentStatus': $('#PaymentStatus').val(),
'SalesDate': $('#SaleDate').val(),
'PaymentStatus': paymentStatus,
'PaymentTypeID': $('#PaymentType option:selected').val(),
'VAT': vat,
'TotalAmount': invoiceAmount,
'DiscountAmount': $('#discInput').val(),
'AmountPaid': $('#amountPaid').val(),
'SaleDetails': saleDetails
};
var json = JSON.stringify({ 'model': data });
public ActionResult printOrder(Models.DTO.Sales model)
{
return PartialView(model);
//return View(model);
}
I am working on POS , In sales client requirement is that we should give him an option of print , so that if client click on Print button we should open a new tab and show invoice , so client can take out print and if customer pay him then client will save SalesOrder.
The problem I am facing is that I am unable to open new tab from controller . And if I am trying to do this from java script I am unable to pass model to view from java script.
So please help me in this issue as I am not too much expert in MVC.
You can use Html.ActionLink to open the page in new tab from your Razor page as below.
#Html.ActionLink("Print", "Action", new { controller="PrintOrder" }, new { target="_blank" })
Html.ActionLink however does not allow you to pass complex objects. You can use trick as mentioned in this stackoverflow answer to pass your model. From the post:
MODEL: Make static Serialize and Deserialize methods in the class like
public class XYZ {
// Some Fields
public string X { get; set; }
public string Y { get; set; }
public string X { get; set; }
// This will convert the passed XYZ object to JSON string
public static string Serialize(XYZ xyz)
{
var serializer = new JavaScriptSerializer();
return serializer.Serialize(xyz);
}
// This will convert the passed JSON string back to XYZ object
public static XYZ Deserialize(string data)
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<XYZ>(data);
}
}
VIEW: Now convert your complex object to JSON string before passing it in
Action View <%= Html.ActionLink(Model.x, "SomeAction", new { modelString = XYZ.Serialize(Model) })%>
CONTROLLER: Get the
object as string in Action method and convert it back to object before
using public ActionResult SomeAction(string modelString) { XYX xyz = XYX.Deserialize(modelString); }

How to send two Array objects using http in AngularJS?

How to receive two parameters as an array in http action(List abc, List) xyz.
after that attempt I use a model class. lik
public class ItemAndChecque
{
public List<SaleItem> saleitem { get; set; }
public List<itemChecqe> itemchecq { get; set; }
}
public IHttpActionResult TowArrayValue(List<ItemAndChecque> abc)
I did many attempt to solve it but not... Some one can send me any Solution.
Your arrays need to be grouped in one object array:
var Indata = {saleitem: $scope.saleitem,itemchecq: $scope.itemchecq}
$http({
url: "someAPI",
method: "POST",
data: Indata
});
Add ItemAndChecque as model class to your backend.
Then you can receive it in your API Controller like this:
public void Post(ItemAndChecque request)
{
var productRepository = new ProductRepository();
var newProduct = productRepository.Save(request.product);
}
Here request contains 2 props with values of saleitem and itemchecq
Edit: based on the comment of #Icycool

data is saved but post request is failed when and give server error

I try to save fields by action controller action method which return different view. But failed to do this: My Jquery code is:
$("#btnAdd").click(function () {
var Product = {
name: $("#txtProductName").val(),
color: $("#ddlColor option:selected").val(),
gage: $("#ddlGage option:selected").val(),
rate: $("#txtrate").val()
};
$.ajax({
});
$.post("ProductTable", { Pro: JSON.stringify(Product) }, function (data) {
$("#RightDiv").html(data);
alert(data);
});
});
and my controller action method on the same controller which return different view:
public ActionResult ProductTable()
{
Product product = new Product();
JavaScriptSerializer serializer = new JavaScriptSerializer();
product = serializer.Deserialize<Product>(Request.Form["Pro"]);
productDB.addProduct(product);
productManager.productTable = productDB.getAllProducts();
return View(productManager);
}
Browser give me error:
HTTP500: SERVER ERROR - The server encountered an unexpected condition that prevented it from fulfilling the request.
(XHR)POST - http://localhost:59008/Product/ProductTable
If you're using MVC, it should handle the serialization/deserialization for you. You just need to make sure the object sent over matches the object you declare in MVC controller action parameter.
Client-side
// Suggestions:
// * use camelCase for javascript variables and functions
// * jQuery .val() on selects should give you the selected value
// * always use fully qualified Url generated by Html.Helper
$("#btnAdd").click(function () {
var product = {
name: $("#txtProductName").val(),
color: $("#ddlColor").val(),
gage: $("#ddlGage").val(),
rate: $("#txtrate").val()
};
var createUrl = '#Url.Action("create", "product", new { area = "" })';
$.post(createUrl, product, function (response) {
$("#RightDiv").html(response);
alert(response);
});
});
Server-side
// Suggestions:
// * NEVER send your domain model back to the page! You should create
// a ViewModel to just include what you want to show the users
[HttpPost]
public ActionResult Create(CreateProductViewModel model)
{
...
productDB.addProduct(new Product {
Name = model.Name,
Color = model.Color,
Gage = model.Gage,
Rate = model.Rate,
// And other stuff like
// CreatedBy = User.Identity.Name
});
// This looks weird to me too!
productManager.productTable = productDB.getAllProducts();
return View(productManager);
}
The ViewModel
public class CreateProductViewModel
{
public string Name { get; set; }
public int Color { get; set; }
public int Gage { get; set; }
public double Rate { get; set; }
}

Pass values to database with selectize multiselect

I have an "Add Employee" modal with a multiselect selectize "Department" dropdown. On button click, an ajax call will run to call respective controller and pass values to database. I can pass everything aside from the "Department" dropdown.
I have tried:
$.ajax({
...
data: { ..., Department: $("#cmbAddDepartment").val(), .... }
})
$.ajax({
...
data: { ...., Department: $("#cmbAddDepartment").getValue(), ... }
})
and
var selectize = $('#cmbAddDepartment').get(0).selectize;
var cmbAddDepartment=selectize.getValue();
$.ajax({
...
data: { ... , Department: cmbAddDepartment, ... }
})
Funny thing is, all those work inside an alert() but not inside an ajax data.
I am using:
Bootstrap 4 alpha 6,
JQuery 3.2.1,
Standalone Selectize 0.12.4
EDIT:
Just an fyi, all my other comboboxes are single-select (still selectize), and $("#cmbAddSomething").val()` works for them.
EDIT 2: Here is the controller and (view)model
Viewmodel - vmEmpCreate.cs
public class vmEmpCreate
{
public vmEmpCreate()
{
//constructor
}
//combo
public string Company { get; set; }
public string Site { get; set; }
public string[] Department { get; set; } //can be multiple
public string ProductionLine { get; set; }
public IEnumerable<SelectListItem> AddCompany { get; set; }
public IEnumerable<SelectListItem> AddSite { get; set; }
public IEnumerable<SelectListItem> AddDepartment { get; set; }
public IEnumerable<SelectListItem> AddProductionLine { get; set; }
}
public class MyListSelectForAdd
{
public string Key { get; set; }
public string Display { get; set; }
}
Controller - Controller.cs
[HttpPost]
public ActionResult AddEmployee(vmEmpCreate vmc)
{
if (ModelState.IsValid)
{
modEmployee addemp = new modEmployee();
addemp.Company = vmc.Company;
addemp.Site = vmc.Site;
addemp.Department = vmc.Department;
...
addemp.Remarks = vmc.Remarks;
conn = new SqlConnection(someConnectionString);
conn.Open();
comm = new SqlCommand("insert into someTable (company, site, department, ..., remarks) values ('"
+ addemp.Company + "' , '"
+ addemp.Site + "' , '"
+ addemp.Department + "' , '"
...
+ addemp.Remarks + "')", conn);
comm.ExecuteNonQuery();
conn.Close();
}
return PartialView();
}
EDIT 3: as per suggestions, i checked my program with chrome inspector to see any errors, but none came up.
I am not very familiar with selectize, but in order to send the set of information you need to store it in an object (aka. associative array):
var selectize = $('#cmbAddDepartment').get(0).selectize;
var cmbAddDepartment=selectize.getValue();
$.ajax({
...
data: {
... ,
Department: cmbAddDepartment,
...
}
});
You can pass as much data as you need into that. So if all of your methods work, then use the one that is best for you, making sure that the data is enclosed in the brackets.
More on JavaScript Objects
I was able to create a workaround for this problem by storing the multiselect dropdown selected values to a HiddenFor, and then passing that value to my "Department" property in the ajax call. I also changed my viewmodel "Department" property from an array to a string.
(View)Model:
public string Department;
View:
#Html.HiddenFor(m => m.Department, new { #id = "hdnDepartment" })
$('#btnAddEmployee').click(function (e) {
e.preventDefault();
var selectize = $('#cmbAddDepartment').get(0).selectize;
var cmbAddDepartment = selectize.getValue();
$("#hdnDepartment").val(cmbAddDepartment);
$.ajax({
..
data: { ..., Department: $("#hdnDepartment").val(), ... }, // optional data
...
});
});
Pretty cheap solution, but it gets the job done.
Thanks to everyone with their help!

Pass List<int> from Javascript to AJAX-Enabled WCF in ASP.Net page

I am calling a WCF method from an ASP.Net page, but I am getting format exception when WCF tries to deserialize the recordIds parameter received from JavaScript.
The first parameter passed to the WCF method needs to be of List type. Is there something wrong I have done in using JSON.stringify?
Javascript Code to call WCF
function Update() {
var myarray1 = new Array();
myarray1[0] = 1;
myarray1[1] = 11;
myarray1[2] = 14;
WCFService1.AJAXEnabledService.BatchUpdateRecords(
JSON.stringify({recordIDs: myarray1}) , "ddsd", "gggg",
updateGrid, OnError);
}
WCF method being called by above JavaScript
[OperationContract]
public bool BatchUpdateRecords(List<int> recordIds, string columnNameToUpdate, string columnValue)
{
DataTable tierIDsTable = new DataTable("RecordIds");
tierIDsTable.Columns.Add(new DataColumn("Integer", typeof(Int32)));
tierIDsTable.PrimaryKey = new DataColumn[] { tierIDsTable.Columns["TierId"] };
foreach (int recordId in recordIds)
{
tierIDsTable.Rows.Add(recordId);
}
return true;
}
Not 100% sure, but have you tried this?
WCFService1.AJAXEnabledService.BatchUpdateRecords(
myarray1,
"ddsd",
"gggg",
updateGrid, OnError);
The issue (without knowing the error that you are receiving) is most likely that you are trying to pass in multiple parameters types. WCF does not usually support and expects an object instead. Create a response class with your parameters and use that instead.
public class ResponseObject
{
public List<int> recordIds { get; set; }
public string columnNameToUpdate { get; set; }
public string columnValue { get; set; }
}
Use this object as your parameter
public bool BatchUpdateRecords(ResponseObject responseObject)
{...

Categories