ASP CORE JSON OBJECT NULL or COUNT 0 - javascript

I'm trying to send a list of values from View to Controller. I tried a lot of solutions from the Internet but haven't succeeded.
My View HTML Table list of Data send to controller via JSON but the list is empty even when I use JSON.stringify
Heres my code
JavaScript:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
$("body").on("click", "#btnSave", function () {
//Loop through the Table rows and build a JSON array.
var customers = new Array();
$("#tblCustomers TBODY TR").each(function () {
var row = $(this);
var customer = {};
//skill.skill_name = row.find("TD").eq(0).html();
customer.CNIC = row.find("TD").eq(1).html();
customers.push(customer);
});
console.log(customers);
console.log(JSON.stringify(customers));
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
//traditional: true,
url: "/Admin/Reconcile/Customers",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(customers),
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
location.reload();
}
});
});
</script>
Controller Action:
public JsonResult Customers(List<String> customers)
{
}

Firstly,you need to create a model like this:
public class Customer {
public string CNIC { get; set; }
}
Then since you pass json type data in ajax,you need to use [FromBody] in action:
public JsonResult Customers([FromBody]List<Customer> customers)
{
}

You are sending an array of objects, so for the model binder to work you should accept a List of SomeModel, where SomeModel should have a property CNIC. Check the documentation here https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api on how objects are binded.
So you are sending this:
[
{
"CNIC":"somevalue",
"CNIC":"somevalue"
}
]
And you are trying to bind it to a List of string and it will not happen. Try binding it with List of SomeModel:
public class SomeModel
{
public string CNIC { get; set; }
}
Also try this attribute [IgnoreAntiforgeryToken] above your action. If it works then, you should be sending the antiforgery token with the post request.

Related

How model bind Javascript FormData with Asp.net Controllers Model

Is it possible to automatically bind ASP.NET controllers model with an ajax request that submits data as FormData.
in my provided example I'm required to use HttpContext.Current.Request.Form["property_name"]
to receive data because if I provide a model that is identical to the submitted form data, all values are equal to null;
or does ASP.NET model binding only work on JSON requests ?
Simple code bellow:
View:
#using (Html.BeginForm("Post", "Test", FormMethod.Post, new { #class="test-form"}))
{
<input type="text" name="firstName"/>
<input type="text" name="lastName"/>
<button type="submit">Submit</button>
}
Scripts:
<script>
$('.test-form').on('submit', function (e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: "#Url.Action("TestPost", "Test")",
method: "POST",
data: formData,
processData: false,
success: function(e){
}
});
});
</script>
Controller:
[HttpPost]
public ActionResult TestPost()
{
var firstname = HttpContext.Current.Request.Form["firstName"];
var lastName = HttpContext.Current.Request.Form["lastName"];
return PartialView("TestPost");
}
Does Not Work Controller:
public class User
{
public string firstName { get; set; }
public string lastName { get; set; }
}
[HttpPost]
public ActionResult TestPost(User model) //model values are null
{
return PartialView("TestPost");
}
When you use a FormData object with ajax the data is sent as multipart/form-data and the content type header is set automatically for you with the correct boundary.
You can override the content type and set tit to whatever you want, which is what happens here.
You might be thinking well I didn't do it, well you good friend jQuery did it for you. It set the default content type for $.ajax for you (application/x-www-form-urlencoded) which pretty much craps up the request.
To stop this action i.e. to stop jQuery from setting a content type header you have to set the contentType parameter to false.

Problems when trying to fill select tag with AJAX call

I'm working on a small project for controlling libraries and I need fill a select tag with all libraries on the database that I have. For that, I've created a WebService which contains a web method called GetBibliotecas, responsible for returning all the libraries in a JSON format; its code will be shown next:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class BibUtil : WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetBibliotecas()
{
return JsonConvert.SerializeObject(DAOFactory.GetInstance(DAOFactory.DAOType.Biblioteca).Select());
}
}
That's the result returned from the WebMethod:
[{"IdBiblioteca":3,"Nome":"Biblioteca FESO
Campus","Endereco":"Avenida Oliveira
Botelho"},{"IdBiblioteca":5,"Nome":"Biblioteca FESO
Pro-Arte","Endereco":"Rua
Exemplo"},{"IdBiblioteca":11,"Nome":"Biblioteca FESO Quinta do
Paraíso","Endereco":"Avenida da
Prata"},{"IdBiblioteca":12,"Nome":"Exemplo Library","Endereco":"Rua
EX"}]
On my view page, I'm trying to use AJAX in order to consume the WebService method asynchronously, right after the page loads. Below is the snippet I coded:
<script>
$(document).ready(function () {
$.ajax({
type: "POST",
url: "../Services/BibUtil.asmx/GetBibliotecas",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$('#ddlLibraries').get(0).options.length = 0;
$('#ddlLibraries').get(0).options[0] = new Option("Selecione uma biblioteca", "-1");
$.each(data.d, function (index, item) {
$('#ddlLibraries').get(0).options[$("#ddlLibraries").get(0).options.length] = new Option(item.Display, item.Value);
});
}
});
});
But when the page is rendered on the browser, some strange error appears on the Console:
Uncaught TypeError: Cannot use 'in' operator to search for '325' in [{"IdBiblioteca":3,"Nome":"Biblioteca FESO Campus","Endereco":"Avenida Oliveira Botelho"},{"IdBiblioteca":5,"Nome":"Biblioteca FESO Pro-Arte","Endereco":"Rua Exemplo"},{"IdBiblioteca":11,"Nome":"Biblioteca FESO Quinta do Paraíso","Endereco":"Avenida da Prata"},{"IdBiblioteca":12,"Nome":"Exemplo Library","Endereco":"Rua EX"}]
My intention is using the IdBiblioteca like an ID value for the dropdown (select tag) and show the option itself using the library name (Nome). What is wrong with the code?
Thanks.
No need to look for the index and length of options each time. Can create all the options and then use html() or append individually after emptying the container
success: function (data) {
// empty the <select>
var $select = $('#ddlLibraries').empty();
// add default to array
data.d.unshift({
Nome: "Selecione uma biblioteca",
IdBiblioteca: -1
});
// creaate and append options
$.each(data.d, function (index, item) {
var $option = $('<option>').text(item.Nome).val(item.IdBiblioteca);
$select.append($option);
});
}
Was confused by your code using properties to create new Option that didn't exist in data shown

Transfer Data from ASP:NET MVC Controller to view

I have an object in contrroller and I want to use them in view and in javascript code but I can't achived using ViewBag. my code hear :
public class MyController : Controller
{
public async Task<ActionResult> Index()
{
using (var client = new HttpClient())
{
string response = await client.GetStringAsync("http://api/controller/....");
ViewBag.VB = response;
return View();
}
}
}
and my view :
#{
ViewBag.Title = "Index";
}
#section Javacript
{
<script type="text/javascript">
function MyFunction() {
**** //I want to use DATA hear. *********
};
</script>
}
<div id="info">
</div>
How can I do this? Anyone have an idea?
You can put your data into a <script type="text/html"> node and access it from javascript via document.getElementById
<script type="text/html" id="data">#ViewBag.VB</script>
<script>
function MyFunction() {
var data = document.getElementById('data').innerHTML;
// if the data is in the json format, you can use JSON.parse:
data = JSON.parse(data);
// TODO: do something with data
}
</script>
You can also insert the data directly into javascript:
function MyFunction() {
var data = '#(ViewBag.VB)'; // or omit the single quotes if it's json data
// TODO: do something with data
}
This approach requires that the javascript code is embedded into the .cshtml file.
Another possibility is to retrieve the data directly from javascript with an ajax request. This example uses jQuery's $.ajax function:
function MyFunction() {
$.ajax({
url: "/api/controller/...",
contentType: "application/json", // tell the api-controller that we want json
dataType: "application/json", // tell the jQuery callback that it is json
success: function (data) {
// TODO: do something with data
}
});
}

asp.net mvc Render a Partial View with Java Script

I want to make a Partial view that displays data in a table.
I will have a Select element with the services to choose from.
When the user Selects a Service in the combobox I want to the call a partial view with the service Id number:
How can I do this?
Here is a action method which will render the partialView
//
// GET: /Service/ServiceStatusLogs/1
public ActionResult ServiceStatusLogs(int id)
{
var db = new EFServiceStatusHistoryRepository();
IList<ServiceStatusHistory> logs = db.GetAllStatusLogs(id);
return View("_ServiceStatusLogs", logs);
}
Here is the main action method which returns the page:
//
// GET: /Services/Status
public ActionResult Status()
{
IList<Service> services;
using (var db = new EFServiceRepository())
{
services = db.GetAll();
}
return View(services);
}
You can make use $.ajax functionality to achieve, check this :-
//Combo box change event
$("#comboboxName").change(function () {
//Get service Id
var serviceId = $("#comboboxName").val();
//Do ajax call
$.ajax({
type: 'GET',
url: "#Url.Content("/Service/ServiceStatusLogs/")",
data : {
Id:serviceId //Data need to pass as parameter
},
dataType: 'html', //dataType - html
success:function(result)
{
//Create a Div around the Partial View and fill the result
$('#partialViewContainerDiv').html(result);
}
});
});
Also you should return partial view instead of view
//
// GET: /Service/ServiceStatusLogs/1
public ActionResult ServiceStatusLogs(int id)
{
var db = new EFServiceStatusHistoryRepository();
IList<ServiceStatusHistory> logs = db.GetAllStatusLogs(id);
return PartialView("_ServiceStatusLogs", logs);
}
Try this:
public ActionResult ServiceStatusLogs( int id )
{
//Prepare your model
return PartialView( "UserDetails", model );
}
Any then use javascript(ajax) to load contents for an element of the DOM:
$('#user_content').load('/Service/ServiceStatusLogs');

MVC - On Select thumbnail, show data from database

i have a script if the user select a thumbnail shows
the larger image and the id from my database.
Until this point its works very well
what i try to do now is when the user clicks on the
thumbnail, i want to show the data which are in my table.
how can i do that?
My database relationship:
in my database i have 2 tables which one has the primary key
and the other the foreign key.
when i select the thumbnail which are in the table with the
primary key, i want to show the data from my other table
which contains the foreign key.
My code:
Javascript:
function swap(image) {
document.getElementById("imagem-selec").src = image.href;
$("input[name='Id_Img']").val($(image).data("id"));
}
HTML to show the list of thummbnails:
#foreach (var p in ViewBag.Img)
{
<li>
<a href="~/Files/#p.Name" onclick="swap(this); return false;" data-id="#p.Id">
<img src="~/Files/#p.Name"/>
</a>
</li>
Html which receive the path
<div id="wrap">
<img id="i-selec" src=""/>
</div>
Any sugestions?
Thanks in advance
UDPATE MY CODE:
Script
function swap(image) {
var imageID = $(image).data("id");
$.ajax("/{Admin}/GetImageData",
{
data: JSON.stringify({ ID: imageID }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
// Add your content to DOM here:
// values in data.data1 etc...
values in data.De, data.Sc
}
error: function () {
alert("error!");
}
});
};
Controller:
public JsonResult GetImageData(int ID)
{
using (SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
SqlDataAdapter sqlAdapt = new SqlDataAdapter
(#"SELECT C.* From Content C inner join Image B on C.ID_Img = B.Id WHERE C.Id=" + ID, cn);
SqlCommandBuilder sqlCmdBuilder = new SqlCommandBuilder(sqlAdapt);
DataSet data = new DataSet();
sqlAdapt.Fill(data, "Content ");
cn.Close();
return Json(data);
}
}
It seems like there are two choices:
Load the data in the view and have it hidden, on page load, and have the click event simply show the data.
Have an AJAX call to get the data that you want on the click event, and add the data when the call returns.
I would personally go with the AJAX call, as it uses a little extra network overhead on the requests, but potentially saves a lot of useless data from being downloaded:
// Data model.
class ImageData
{
public int data1 { get; set; }
public string data2 { get; set; }
...
}
// Controller action. Data access abstracted out.
public JsonResult GetImageData(int ID)
{
ImageData data = DataAccess.GetImageData(ID);
return Json(data);
}
Your JavaScript might look something like:
function swap(image) {
var imageID = $(image).data("id");
$.ajax("/{YourControllerHere}/GetImageData",
{
data: JSON.stringify({ ID: imageID }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
// creating the element to add
var div = document.createElement("div");
div.setAttribute("id", imageID);
$(image).parent().append(div);
//adding the data here. do this for each data item?
$("#"+imageID).append(data.details.YOUR_PROPERTY_HERE);
}
error: function () {
alert("error!");
}
});
}
The success callback has a parameter named "data". This is a JavaScript object representation of the data you returned in the controller action JsonResult.

Categories