Iterate on a JSON in JavaScript Asp.net - javascript

I have following data that I have serialized as JSON from my code behind file.
public class PieModel {
public string label { get; set; }
public double data { get; set; }
}
var data = new List<PieModel> {
new PieModel { label = "Pending", data = 10d }
new PieModel { label = "New", data = 40d }
new PieModel { label = "Overdue", data = 50d }
};
hdnData.Value = new JavaScriptSerializer().Serialize(data);
I read this serialized data in JavaScript like this
var tempHdnData = $("#hdnData");
But now I want to iterate on tempHdnData and get label and data members separately in JavaScript code. How can I achieve that?

You could write your code like this in the code behind:
protected List<PieModel> GetData() {
return new List<PieModel> {
new PieModel { label = "Pending", data = 10d }
new PieModel { label = "New", data = 40d }
new PieModel { label = "Overdue", data = 50d }
};
}
And in your webform:
var tempHdnData = <%= new JavaScriptSerializer().Serialize(GetData()) %>
Now you can write
$.each(tempHdnData, function (_, data) {
console.log(data)
})

Related

How to post list data to .net mvc using Axios with out [FromBody] model binding

I am try to post object list to backend using Axios.
But backend couldn't get any object list parameters.
Code:
<div class="text-center">
<button onclick="postData()">Post Data</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.js"></script>
<script>
function postData() {
let mockData = [];
mockData.push({ ID: 0, Name: "John" });
mockData.push({ ID: 1, Name: "Mary" });
mockData.push({ ID: 2, Name: "Alex" });
mockData.push({ ID: 3, Name: "July" });
mockData.push({ ID: 4, Name: "Steve" });
console.log(mockData);
const formData = new FormData();
formData.append('model', mockData);
axios.post('/Home/Receive', formData)
.then(res => console.log(res.data))
.catch((error) => { console.error(error) });
}
</script>
[HttpPost]
public IActionResult Receive(List<MemberInfo> model)
{
var itemList = model;
return View();
}
public class MemberInfo
{
public int ID { get; set; }
public string Name { get; set; }
}
The above code, backend always get null.
Result:
Awayls get null when post to this function.
Even I add [FromQuery] or [FromForm] in function.
I know I can use [FromBody] to get object list. So how can I get object list without [FromBody] ?
Based on the code of your controller action and model class, to post data and bind value to properties of the model, you can try:
Approach 1: generate and post formdata like below on your JavaScript client side.
function postData() {
let mockData = [];
mockData.push({ ID: 0, Name: "John" });
mockData.push({ ID: 1, Name: "Mary" });
mockData.push({ ID: 2, Name: "Alex" });
mockData.push({ ID: 3, Name: "July" });
mockData.push({ ID: 4, Name: "Steve" });
console.log(mockData);
const formData = new FormData();
//formData.append('model', JSON.stringify(mockData));
for (var i = 0; i < mockData.length; i++) {
formData.append(`model[${i}].ID`, mockData[i].ID);
formData.append(`model[${i}].Name`, mockData[i].Name);
}
axios.post('/Home/Receive', formData)
.then(res => console.log(res.data))
.catch((error) => { console.error(error) });
}
Approach 2: implement and use your own custom model binder, like below.
MemberInfoModelBinder class
public class MemberInfoModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// ...
// implement it based on your actual requirement
// code logic here
// ...
//var options = new JsonSerializerOptions
//{
// PropertyNameCaseInsensitive = true
//};
var model = JsonSerializer.Deserialize<List<MemberInfo>>(bindingContext.ValueProvider.GetValue("model").FirstOrDefault());
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
Receive action
[HttpPost]
public IActionResult Receive(
[ModelBinder(BinderType = typeof(MemberInfoModelBinder))]List<MemberInfo> model)
{
var itemList = model;
return View();
}
On JavaScript client side
const formData = new FormData();
formData.append('model', JSON.stringify(mockData));
Test Result
Invoking you post action like this:
axios.post('/Home/Receive', formData)
Will always put the data in the body of the request.
If you wish to get it for example from query, you would have to adjust both the backend and the client javascript call:
[HttpGet]
public IActionResult Receive([FromQuery]List<MemberInfo> model)
{
var itemList = model;
return View();
}
... JS
axios.get('/Home/Receive', formData)
.then(res => console.log(res.data))
.catch((error) => { console.error(error) });
Update:
If you want it as a POST action, without the [FromBody] attribute, you can add a [ApiController] attribute to your controller - that's the second option you could use

JQuery Ajax File Ypload Causes complete page Reload

I have a problem when upload a file via Ajax , after de call is completed the page reloads , here is the code
function Save() {
var files1 = $("#file1").get(0).files;
var data = new FormData();
data.append("Data", JSON.stringify(GetData()));
for (i = 0; i < files1.length; i++) {
data.append("file" + i, files1[i]);
}
var resp =
{
service: "File/SaveFile",
sender: data,
progress: null,
funct: null,
antes: null,
despues: null
};
var response = CallServiceUpload(resp);
response.done(function (responseData, textStatus) {
var controlInput = $("#file1");
controlInput.replaceWith(controlInput = controlInput.val('').clone(true));
});
return response;
}
function GetData() {
x =
{
ID: 1
}
return x;
}
this.CallServiceUpload = function (obj) {
return $.ajax({
type: "POST",
url: "api/" + obj.service,
data: obj.sender,
contentType: false,
processData: false,
error: function (message) {
alert(message.responseText);
}
});
}
and here is the server code using ASP.NET Web Api
using DataManager.Estruct.DTO;
using DataManager.Logic;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace WebApp.Controllers
{
public class FileController : ApiController
{
#region
[HttpPost]
[ActionName("SaveFile")]
public async Task<JObject> SaveFile()
{
// Check if the request contains multipart/form-data.
var httpContent = Request.Content;
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
var provider = new CustomMultipartFormDataStreamProvider(root);
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
string jsonData = provider.FormData.GetValues("Data")[0];
List<string> deletefiles = new List<string>();
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
//Process File
}
provider.FileData.Clear();
foreach (string deletefile in deletefiles)
{
try
{
File.Delete(deletefile);
}
catch (Exception ex)
{
string error = ex.InnerException.Message;
}
}
object x = new { data = "ok"};
return JObject.FromObject(x);
}
catch (Exception ex)
{
// string Mensaje = LCuenta.LogError(null, ex, System.Reflection.MethodBase.GetCurrentMethod().Name);
var error = new { error = ex.Message };
return JObject.FromObject(error);
}
}
#endregion
}
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
}
I Alredy use this code for another app , but in this case after the executing the javascript method Save , the complete page reloads , if the file is small o the call has no files only data y does not reload , the page html is on asp web view using mvc , but is only a container all the code is on javascript.
thanks!;
On button click use preventDefault
Ex
$("#buttonID").click(function(event){
event.preventDefault();
});

$.post always getting null values into server

Ok, this might be simple, I'm having a simple $.post call to server sending string array as parameters..
$.get('/home/ReadCalPacTagValue', data, function (data) {
data = $.parseJSON(data);
if (data.length != 0) {
var ReadFromDb = data[0]["PushToDb"].replace('PushToDb','ReadFromDb');
var DBAckno = ReadFromDb.replace('ReadFromDb', 'DataAck');
var FIdTag = ReadFromDb.replace('ReadFromDb', 'FluidTypeId');
var UserIdTag = ReadFromDb.replace('ReadFromDb', 'UserId');
var UniqueIdTag = ReadFromDb.replace('ReadFromDb', 'UniqueRecordId');
var dbconnTag = ReadFromDb.replace('ReadFromDb', 'DatabaseConnectionString');
updateTags = [dbconnTag,FIdTag,ReadFromDb, UserIdTag,UniqueIdTag];
actionvalue = ["", fluidtypeid, '1', userid, uniqueID];
var data_Tags = { updateTags: updateTags, actionvalue: actionvalue }
$.post('/home/WriteCalPacTagValue', data_Tags, function (response) {
//var Path = "Config/16_CalPac/" + FluidType + "/" + metername + "/" + FileName
//$.cookie('FileName', FileName, { expires: 7, path: '/' });
//$.cookie('FilePath', Path, { expires: 7, path: '/' });
//$.cookie('ModuleName', "CalPac", { expires: 7, path: '/' });
//window.open('../home/CalPac', '_blank');
});
} else {
swal("Error !", "Data operation tag not binded for this product", "warning");
}
})
my problem is, every time it makes $.post call, server is getting null values int prarameters..
public void WriteCalPacTagValue(string[] updateTags, string[] actionValue)
{
string[] writetags = { };
DanpacUIRepository objNewTag = new DanpacUIRepository();
if (updateTags.Count() > 0)
{
actionValue[0] = ConfigurationManager.AppSettings["DBString"].ToString();
for (int i = 0; i < updateTags.Count(); i++)
{
writetags = updateTags[i].Replace("<", "").Replace(">", ">").Split('>');
objNewTag.WriteTag(writetags, actionValue[i]);
}
}
}
I'm not getting what I've done wrong here.. whereas same function is working from another JS file with some difference string into array updateTags.
any help?
Having
public class DataTags
{
public string[] UpdateTags { get; set; }
public string[] ActionValue { get; set; }
}
At the server: Change the method to this
[HttpPost()]
public void WriteCalPacTagValue([FromBody]DataTags data_Tags)
{
}
At the client: call it
$.ajax({
type: 'POST',
url: '/home/WriteCalPacTagValue',
data: data_Tags,
success: function (response) {
//your code
}
});
Also you can send the whole data as json string using data: JSON.stringify(data_Tags), in javascript code the change the WriteCalPacTagValue to accept a single string at the parameter and deserialize it in C# code at the server side.
EDIT if you cannot change the server side code, you may follow this as stated in the comments.

Jquery JTable Load from 2 Tables

I am using Jquery-JTable in my website to load details in a grid view and to let user be able to modify, delete app accordingly.
I am loading data successfully from 2 tables and then display them in my div. Now the user would like to modify a record accordingly to his/her wish.
I would like to let the user choose from a dropdown list obtained from another table. Can this be done?
Code Below: As you can see I am loading data from multiple tables using InnerJoin. For example I would like to let the user choose another Category or Language etc.
$queryString = "SELECT `app_id`,`app_name`,`app_type`,`app_url`,`AppAccepted`,`BenefitApp`, application_ageGroup.ageGroup,application_category.category, application_Country.country,application_Language.language FROM application INNER JOIN application_ageGroup ON application.ageGroup_id = application_ageGroup.ageGroup_id INNER JOIN application_category ON application.Category = application_category.category_id INNER JOIN application_Country ON application.country_id = application_Country.country_id INNER JOIN application_Language ON application.language_id = application_Language.language_id ORDER BY $jtSorting LIMIT $jtStartIndex,$jtPageSize";
Regards,
Make the Category column as dropdown and bind it with your query dataset :
$('#Table').jtable({
paging: true,
pageSize: 200,
sorting: true,
defaultSorting: 'Category ASC',
selecting: false,
multiselect: false,
selectingCheckboxes: false,
actions: {
listAction: '/Application/GetData',
updateAction: '/Application/EditData'
},
fields: {
Category: {
title: 'Category',
width: '10%',
list: false,
sorting: true,
options: '/Application/GetCategories'
}
});
In your controller action, fetch Category lists:
[HttpPost]
public JsonResult GetCategories()
{
try
{
DataTable dtCategories = new DataTable();
string query = "SELECT .....";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
dtCategories.Load(command.ExecuteReader());
}
List<Store> categoryList = DatatableToGenericList(dtCategories);
var categories = categoryList.Select(category => new { DisplayText = category.Name , Value = category.Id }).OrderBy(s => s.DisplayText);
return Json(new { Result = "OK", Options = categories });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
private static List<Store> DatatableToGenericList(DataTable table)
{
var categoryList = new List<Category>(table.Rows.Count);
foreach (DataRow row in table.Rows)
{
var values = row.ItemArray;
var store = new Category()
{
Id = values[0].ToString(),
Name = values[1].ToString()
};
categoryList.Add(store);
}
return categoryList;
}
Category Model
public class Category
{
public string Id { get; set; }
[Required]
public string Name { get; set; }
}
Hope this helps..

Web API string parameters and POST values

I am using a jQuery plugin, jTable. The plugin has the following function to load the table:
$('#PersonTable').jtable('load', { CityId: 2, Name: 'Halil' });
The values in the load function is send as POST data. The plugin also sends two query string parameters (jtStartIndex, jtPageSize) through the URL for paging the table.
An example in the documentation shows a function on how to handle this in ASP.NET MVC but not in Web API Example :
[HttpPost]
public JsonResult StudentListByFiter(string name = "", int cityId = 0, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
//Get data from database
var studentCount = _repository.StudentRepository.GetStudentCountByFilter(name, cityId);
var students = _repository.StudentRepository.GetStudentsByFilter(name, cityId, jtStartIndex, jtPageSize, jtSorting);
//Return result to jTable
return Json(new { Result = "OK", Records = students, TotalRecordCount = studentCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
How my function currently looks: It works fine except that I can't manage to read the POST data (name param):
public dynamic ProductsList(string name = "", int jtStartIndex = 0, int jtPageSize = 0 )
{
try
{
int count = db.Products.Count();
var products = from a in db.Products where a.ProductName.Contains(name) select a;
List<Product> prods = products.OrderBy(x => x.ProductID).ToList();
return (new { Result = "OK", Records = prods, TotalRecordCount = count });
}
catch (Exception ex)
{
return (new { Result = "ERROR", Message = ex.Message });
}
}
My jTable load: (This get called when the user enters text in a input)
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
I would appreciate any help with how to read both the string parameters in the URL and the POST data in a Web API function.
EDIT:
I used an alternative way to send the data to the API. Instead of sending it in the load function formatted as JSON I used a function for the listAction and sent the data through the URL (See jTable API reference for details):
listAction: function (postData, jtParams) {
return $.Deferred(function ($dfd) {
$.ajax({
url: 'http://localhost:53756/api/Product/ProductsList?jtStartIndex=' + jtParams.jtStartIndex + '&jtPageSize=' + jtParams.jtPageSize + '&name=' + $('#prodFilter').val(),
type: 'POST',
dataType: 'json',
data: postData,
success: function (data) {
$dfd.resolve(data);
},
error: function () {
$dfd.reject();
}
});
});
}
To reload the table based on your filtered results:
$('#ProductTable').jtable('load');
Instead of this:
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
Try applying the [FromBody] attribute to the name parameter
public dynamic GetProductList([FromBody]string name = "", int jtStartIndex = 0, jtPageSize = 0)
{
...
}
The default binder in Web API will look in the URI for simple types like string, specifying the FromBody attribute will force it to look in the body.

Categories