AJAX Object Passes Null to Controller - javascript

Good Day,
I am at my wits end and I know that it's probably something simple I am missing. After searching and searching I can't seem to find a solution that works for me. My problem is that I am trying to pass information from input fields via AJAX to a controller using JSON.
This is the code for my C# Model
public partial class EgInput
{
public string DisplayId { get; set; }
public string EgUid { get; set; }
public double Quantity { get; set; }
public string Quality { get; set; }
public string Required { get; set; }
public string MaxAmount{ get; set; }
}
This is the Code for my C# Controller Action
public String SaveTest(EgInput obj)
{
Debug.WriteLine("Uid Value: "+ obj.DisplayId);
return (obj.DisplayId);
}
Below is the Input Fields
<input asp-for="DisplayId" class="form-control" />
<span asp-validation-for="DisplayId" class="text-danger"></span>
<input asp-for="EgUid" class="form-control" />
<span asp-validation-for="EgUid" class="text-danger"></span>
<table>
<tr id="eg_row">
<td>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</td>
<td>
<input asp-for="Quality" class="form-control" />
<span asp-validation-for="Quality" class="text-danger"></span>
</td>
<td>
<input asp-for="Required" class="form-control" />
<span asp-validation-for="Required" class="text-danger"></span>
</td>
<td>
<input asp-for="MaxAmount" class="form-control" />
<span asp-validation-for="MaxAmount" class="text-danger"></span>
</td>
</tr>
</table>
<button type="button" id="save_test">Save</button>
This is the JavaScript I'm Executing.
$('#save_test').on("click", function () {
$("tr").each(function () {
if ($(this).is("#eg_row")) {
var did = $("#DisplayId").val();
var eid = $("#EgUid").val();
var quantity = $(this).find("#Quantity").val();
var quality = $(this).find("#Quality").val();
var req = $(this).find("#Required").val();
var max = $(this).find("#MaxAmount").val();
var obj = JSON.stringify({
"DisplayId": did,
"EgUid": eid,
"Quantity": quantity,
"Quality": quality,
"Required": req,
"MaxAmount": max
});
console.log("clicked");
$.ajax({
type: "POST",
dataType: "json",
data: obj,
contentType: 'application/json',
url: '/Index/SaveTest',
success: function (msg) {
alert(msg);
}
});
}
});
});
I have Console logged the JSON array to see that their are indeed values pulled from the fields. I have tested that the correct action in the controller is called and changed its return to a message to know that it was successfully processed. Using the is() function in C# it says that the object is indeed to the type. However, the values are always null when using Debug Console to verify the information in the object. Thanks in advance for any assistance that is provided.

Like I said, it was a rather simple solution to my problem. For some reason the JSON stringify wasn't being passed. I tried using the [FromBody] attribute or the [FromUri] but the object still remained null. So instead I tried just simply passing the Javascript object directly, and did not use json and the data transferred.
Revised JavaScript Code Below
$('#save_test').on("click", function () {
$("tr").each(function () {
if ($(this).is("#eg_row")) {
var did = $("#DisplayId").val();
var eid = $("#EgUid").val();
var quantity = $(this).find("#Quantity").val();
var quality = $(this).find("#Quality").val();
var req = $(this).find("#Required").val();
var max = $(this).find("#MaxAmount").val();
var obj = {
"DisplayId": did,
"EgUid": eid,
"Quantity": quantity,
"Quality": quality,
"Required": req,
"MaxAmount": max
};
console.log("clicked");
$.ajax({
type: "POST",
dataType: "html",
data: obj,
contentType: 'application/x-www-form-urlencoded',
url: '/Index/SaveTest',
success: function (msg) {
alert(msg);
}
});
}
});
});

Related

.NET Core MVC - AJAX POST Request with prefix binding

I would like to post a request via AJAX to a Controller with a model prefix. I need a prefix as I have two forms on one page with similiar model properties ("asp-for" is generating similiar IDs and Names). I'm using .NET Core 3.1.
Request post works fine without a prefix. When I'm using a prefix like in the example below, passed model is null in Controller:
Controller with prefix
[HttpPost]
public async Task<IActionResult> Save([Bind(Prefix="ShipmentAddress"), FromBody]ShipToAddressViewModel model)
{
// model is null
...
return PartialView(ShipmentAdressFormView, model);
}
View with prefix
In my View I set the HTMLFieldPrefix as well:
#model ShipToAddressViewModel
#{
ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "ShipmentAddress";
}
...
$("body").on('submit','#formShipmentAddress', function (e) {
// Getting the data (see passed JSON below)
var formData = new FormData(<HTMLFormElement>document.getElementById('formShipmentAddress'));
var object = {};
formData.forEach(function (value, key) {
object[key] = value;
});
var data = object;
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: (data) => {
success(data);
}
});
});
Passed JSON payload with prefix
{"ShipmentAddress.ID":"3","ShipmentAddress.Name":"Eddard Stark","ShipmentAddress.Name2":"c/o Ned",..."}
Model
public class ShipToAddressViewModel
{
public int ID { get; set; }
[Display(Name="Name")]
public string Name { get; set; }
[Display(Name = "Name 2")]
public string Name2 { get; set; }
...
}
UPDATE
If I remove the prefix from keys of my objects, then it works, though more like a work around (Model binding starts by looking through the sources for the key ShipmentAddress.ID. If that isn't found, it looks for ID without a prefix.):
// Getting the data (see passed JSON below)
var formData = new FormData(<HTMLFormElement>document.getElementById('formShipmentAddress'));
var object = {};
formData.forEach(function (value, key) {
object[key.replace("ShipmentAddress.","")] = value;
});
var data = object;
For Asp.Net Core, there are two ways to bind the model, ModelBinding and JsonInputFormatter. For sending request with json, it will use JsonInputFormatter. Bind will not work with JsonInputFormatter.
Here is a working demo like below:
1.View:
#{
ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "ShipmentAddress";
}
#model ShipToAddressViewModel
<form id="formShipmentAddress">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ID" class="control-label"></label>
<input class="form-control" asp-for="ID">
<span asp-validation-for="ID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input class="form-control" asp-for="Name">
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Name2" class="control-label"></label>
<input class="form-control" asp-for="Name2">
<span asp-validation-for="Name2" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
#section Scripts
{
<script>
$("body").on('submit', '#formShipmentAddress', function (e) {
e.preventDefault();
var id = parseInt($("#ShipmentAddress_ID").val());
var name = $("#ShipmentAddress_Name").val();
var name2 = $("#ShipmentAddress_Name2").val();
var data = {
ID: id,
Name: name,
Name2: name2
};
$.ajax({
type: "POST",
url: "/Home/Save",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: (data) => {
success(data);
}
});
});
</script>
}
2.Controller:
public async Task<IActionResult> Save([FromBody]ShipToAddressViewModel model)
{
//do your stuff...
}
3.Result:

Passing ViewModel back from controller to Javascript Function MVC

So I have a ViewModel that holds some basic information, and I am taking in an input from the view. Then the input is sent to a .js function that sends it to a controller function that does some work with it. Right now I am just trying to get the Javascript function to connect and display some irrelevant code on the page just to make sure its connected. I make it through everything with no errors, and at the very end I am returned the errorOnAjax Function, inside of the browser tools, that I have written myself. So there is no problem with any of the code that I can see.
My thought is, I am converting the ViewModel to Json wrong in the controller, in turn, it is returning it the wrong way to the Javascript function and giving the error. If anyone has any suggestions, it would be greatly appreciated!
public class MapInfoViewModel
{
public string Place { get; set; }
public string City { get; set; }
public string State { get; set; }
public string URL { get; set; }
}
And I am getting information from the view via an input box
#using (Html.BeginForm())
{
<input type="text" id="name" />
<button id="myButton" onclick="getInfo()">AJAX</button>
}
This is what my Javascript Function looks like. showInfo is just injecting a basic table into the view with just 1 value inside, just to make sure it is connected.
function getInfo(Info) {
var myInfo = document.getElementById('name').value;
$.ajax({
type: "GET",
dataType: "json",
url: "/CreateRoute/DisplayInfo",
data: { 'myInfo': myInfo },
success: showInfo,
error: errorOnAjax
})
}
and my Controller Function
public ActionResult DisplayInfo()
{
string request = Request.QueryString["myInfo"];
MapInfoViewModel info = new MapInfoViewModel()
{
Place = request
};
return new ContentResult
{
Content = JsonConvert.SerializeObject(info),
ContentType = "application/json",
ContentEncoding = System.Text.Encoding.UTF8
};
}
You wrote everything correct code but you just miss the one attribute in view.
you need to mention button type then it will work as per your expectations
<button id="myButton" onclick="getInfo()">AJAX</button>
Now I sharing the complete details of this issue.
Javascript-
function getInfo(Info) {
var myInfo = document.getElementById('name').value;
$.ajax({
type: "GET",
dataType: "json",
url: "/Test/DisplayInfo",
data: { 'myInfo': myInfo },
success: showInfo,
error: errorOnAjax
})
function showInfo(result) {
console.log(result);
}
function errorOnAjax() {
console.log("errorOnAjax");
}
}
View -
#using (#Html.BeginForm())
{
<input type="text" id="name" />
<button type="button" id="myButton" onclick="getInfo()">AJAX</button>
}
Controller-
public ActionResult DisplayInfo()
{
string request = Request.QueryString["myInfo"];
MapInfoViewModel info = new MapInfoViewModel()
{
Place = request
};
return new ContentResult
{
Content = JsonConvert.SerializeObject(info),
ContentType = "application/json",
ContentEncoding = System.Text.Encoding.UTF8
};
}
First return with json in controller.
public ActionResult DisplayInfo(string myInfo)
{
MapInfoViewModel info = new MapInfoViewModel()
{
Place = myInfo
};
return Json(info,JsonRequestBehavior.AllowGet);
}
In Front End use ajax like this.
$( "#myButton" ).click(function() {
let data={myInfo:$('#name').val();};
$.ajax({
type: "GET",
dataType: "json",
url: "/CreateRoute/DisplayInfo",
data: data,
success: function (response){
//do
},
error: function (error){
}
});
});
You need to create JsonResult function, then return Json(info, JsonRequestBehavior.AllowGet) as #sadullah zolfqar answered you.
Please refer to the below link to get the full explanation:
https://www.c-sharpcorner.com/UploadFile/2ed7ae/jsonresult-type-in-mvc/

JQuery dropdown click function not working in asp.net mvc

I'm new to jQuery, here when I click the department code dropdown list then department name want to come inside the input field as well as I used jQuery function for that. the problem is to the department name didn't come while click the dropdown. I couldn't find out my mistake in my jQuery code, if anyone find out that it will be most helpful for me. Below, I saw my necessary code only
1.Create.cshtml
<tr class="spaceUnder">
<td>
<label for="departmentId">DepartmentCode</label>
</td>
<td>
<select name="departmentId" id="departmentId">
<option value="">Select...</option>
#foreach (var department in ViewBag.Departments)
{
<option value="#department.ID">#department.Code</option>
}
</select>
</td>
</tr>
<tr class="spaceUnder">
<td><label for="DepartmentName">DepName</label></td>
<td>
<input type="text" readonly="readonly" name="DepartmentName" id="DepartmentName" data-val="true">
</td>
</tr>
<script>
$(document).ready(function()
{
$('#departmentId').change(function ()
{
var DepId = $('#departmentId').val();
var json = { DepartmentId: DepId };
$.ajax(
{
type: "POST",
url: "/TeacherCourseAssign/GetDepartmentByDepartmentId",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(json),
success: function
(data) {
$('#DepartmentName').val(data.Name);
}
}
);
}
);
}
);
</script>
2.SubjectController.cs
public ActionResult Index()
{
var subjects = db.Subjects.Include(s => s.Department);
return View(subjects.ToList());
}
3.TeacherCourseAssignController.cs
public JsonResult GetDepartmentByDepartmentId(int departmentId)
{
List<Department> departments = aDepartmentManager.GetAllDepartments();
var department = departments.Find(a => a.ID == departmentId);
return Json(department);
}
4.DepartmentManager.cs
public List<Models.Department> GetAllDepartments()
{
return aDepartmentGateway.GetAllDepartment();
}
5.DepartmentGateway.cs
public List<Department> GetAllDepartment()
{
SqlConnection connection = new SqlConnection(connectionString);
string Query = "SELECT * FROM Departments ";
SqlCommand command = new SqlCommand(Query, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
List<Department> departments=new List<Department>();
while (reader.Read())
{
Department department = new Department()
{
ID=(int)reader["ID"],
Name = reader["Name"].ToString(),
Code=reader["Code"].ToString()
};
departments.Add(department);
}
reader.Close();
connection.Close();
return departments;
}
6.Subject.cs ( model )
public class Subject
{
public int SubjectID { get; set; }
[DisplayName("Department")]
public int? DepartmentId { get; set; }
[ForeignKey("DepartmentId")]
public virtual Department Department { get; set; }
[DisplayName("DepName")]
public string DepartmentName { get; set; }
}
i think, you made several mistake while writing the JQuery code.Try this, it might work for you.
#section scripts
{
<script>
$(document).ready(function()
{
$("#departmentId").change(function ()
{
var DepId = $("#departmentId").val();
var json = { DepartmentId: DepId };
$.ajax(
{
type: "POST",
url: '/TeacherCourseAssign/GetDepartmentByDepartmentId',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(json),
success: function
(data) {
$("#DepartmentName").val(data.Name);
}
}
);
}
);
}
);
</script>
}
then After try to Debugging JavaScript in your browser ,here you want to put the breakpoints appropriate place and find your solution as well.(More Details Debugging JavaScript in chrome.LinkHere)

Send data to WebAPI (C#) GET Request Ajax call

I want to use html to get WebApi ReturnValue. (type:Get、datatype:Jsonp)
Now when I direct execution WebApi, it can get ReturnValue "2" (indicate execution Success).
But when via by html + Jquery + ajax , it always show error function information.
How an I resolve this problem, thanks.
------------- code -------------
API Model:
public class LoginModel
{
public int Userno { get; set; }
public List<Second> LoginSecond { get; set; }
}
public class Second
{
public string testinfo01 { get; set; }
public string testinfo02 { get; set; }
public List<Third> Third { get; set; }
}
public class Third
{
public string finValue { get; set; }
}
API Controller:
[HttpGet]
public string Get(string id, string id1) //id=Account,id1=password
{
string conn = ConfigurationManager.ConnectionStrings["testconn"].ConnectionString;
string Dictionary = Login.Login(id, id1).ToString();
return Dictionary;
}
Html:
<div class="form" id="form">
<form class="login-form" method="get">
<input type="text" id="inpAcc" placeholder="Acc"/>
<input type="password" id="inpPwd" placeholder="pwd"/>
<input id="loginbtn" type="button" value="login"></input>
<input id="data" type="label" />
</form>
</div>
jquery + ajax:
<script type="text/javascript" >
$(document).ready(function() {
$(document).on('click', '#loginbtn',function(){
var username = $("input#inpAcc").val();
var password = $("input#inpPwd").val();
alert(username);
var APIurl = "localhost:10733/Api/Login/";
$.ajax({
type: "get",
dataType: 'jsonp',
username:username,
password:password,
url: APIurl +"/"+username+"/"+password,
async: false,
headers: { "cache-control": "no-cache" },
contentType: 'application/json; charset=utf-8',
data :function (data)
{
var returnvalue = data[0].request();
console.log(data.stat);
console.log(data.status);
console.log(data.message);
console.log(data.html);
alert(returnvalue);
},
error: function(request, status, error) {
console.log(request.stat);
console.log(request.status);
console.log(request.message);
console.log(request.html);
alert(request.responseText);
},
success: function(data) {
console.log(data.stat);
console.log(data.status);
console.log(data.message);
console.log(data.html);
alert(data);
}
});
});
});
</script>
Please check your source. Remove the route configuration as below source included route config inline.
[RoutePrefix("api/Login")]
public class LoginController : ApiController
{
[HttpGet]
[Route("Get/{id}/{id1?}")]
public string Get(string id, string id1 = null) //id=Account,id1=password
{
return "Working";
}
}
to call above api your url should be like
http://localhost:11299/api/login/Get/id/id1/
In the above id1 is optional

Knockout: Bind uploaded files

I have ran into an issue of being unable to upload multiple files from nested models within the main knockout view model.
Testing out uploading HttpPostedFileBase properties, I was succesful in uploading a file and using two synchronous ajax calls within the EditTestStepjs file, using the XmlFile property.
However, in trying to send over multiple files that are bound to the nested models within the list, I am unable to have their values sent over to the controller using form-data.
Nested View Model
public class XmlParameterViewModel
{
public string ParameterName { get; set; }
public HttpPostedFileBase XmlValue { get; set; }
}
Main View Model
public class EditTestStepViewModel
{
public string TestStepName { get; set; }
public HttpPostedFileBase XmlFile { get; set; }
public List<XmlParameterViewModel> XmlParameters { get; set; }
public EditTestStepViewModel()
{
this.XmlParameters = new List<XmlParameterViewModel>();
}
}
Controller
[HttpPost]
public ActionResult SaveEdit(EditTestStepViewModel editTestStepViewModel)
{
return View("Index", editTestStepViewModel);
}
public JsonResult FileUpload(List<HttpPostedFileBase> xmlFile)
{
return Json(new {success = true}, JsonRequestBehavior.AllowGet);
}
EditTestStepJS file
var EditTestStepViewModel = function(data) {
var self = this;
ko.validatedObservable(ko.mapping.fromJS(data, mapping, self));
self.saveTestStep = function() {
if (self.isValid()) {
var file = new FormData($("#editForm").get(0));
$.ajax({
type: "POST",
url: "/Home/FileUpload/",
data: file,
processData: false,
contentType: false,
dataType: "json",
success: function () {
var dataToSend = ko.mapping.toJSON(self);
$.ajax({
url: "/Home/SaveEdit/",
type: "POST",
contentType: "application/json",
data: dataToSend
});
}
});
}
}
View
<form enctype="multipart/form-data" id="editForm">
<table class="table table-striped">
<tr>
<th>XmlPara</th>
</tr>
<tbody data-bind="foreach: XmlParameters">
<tr>
<td class="form-group"> <input name="ParameterName" class="form-control input-sm" data-bind="value: ParameterName" disabled="disabled"/></td>
<td class="form-group"> <input name="XmlValue" type="file" class="btn btn-group" data-bind="value: XmlValue" /></td>
</tr>
</tbody>
</table>
<button data-bind="click: saveTestStep" type="submit">Save Test Step</button>
<form>

Categories

Resources