How to build a javascript function as an object in C#? - javascript

I want to build an object in C# like this.
public JsonResult GetMyObject(){
var MyObject =
new
{
Myfunction = "function (params) {
var res = params[0].seriesName + ' ' + params[0].name;
res += '<br/> Start : ' + params[0].value[0] + ' Max : ' + params[0].value[3];
res += '<br/> End : ' + params[0].value[1] + ' Min : ' + params[0].value[2];
return res;
}",
Element1 = "Test Element",
Element2 = 123
};
return Json(MyObject);
}
But when I return the json object to javascript, the "Myfunction" element in MyObject is just a string, not a javascript function.
How can I build a javascript function as an object in C#?

If you want return object, better you can create a class, populate and send class as return item, it will send you JSON format.
public class MyFucntion
{
public string SeriesName { get; set; }
public string Start { get; set; }
public string End { get; set; }
public string Max { get; set; }
public string Min { get; set; }
}
public class MyObject {
public MyFucntion myFun { get; set; }
public string Element1 { get; set; }
public string Element2 { get; set; }
}
public JsonResult GetMyObject()
{
var fun = new MyFucntion
{
SeriesName =params[0].name,
Max = params[0].value[3],
Min = params[0].value[2],
Start =params[0].value[0],
End = params[0].value[1]
};
var obj = new MyObject {
myFun = fun,
Element1 ="ElE",
Element2 = "ELE2"
};
return JSON(obj);
}
If you are using asp.net website you can use web Mehtod and you need to change the code.
[System.Web.Services.WebMethod]
public static MyObject GetMyObject()
{
var fun = new MyFucntion
{
SeriesName =params[0].name,
Max = params[0].value[3],
Min = params[0].value[2],
Start =params[0].value[0],
End = params[0].value[1]
};
var obj = new MyObject {
myFun = fun,
Element1 ="ElE",
Element2 = "ELE2"
};
return obj;
}

Related

large file attachment via Angularjs

Below code has been generated and connected to a controller called "streaming" in .net core. The code works well and attaches large files perfectly.
The code needs to be used in another html page to upload files for different purpose. However, when upload button is pressed, below error is displayed:
Failed to load resource: the server responded with a status of 400 (Bad Request)
This is the case that if I attach a file from the original page, the process gets completed and then I can attach any file from the copied page!
But if I close the browser and try to attach a file from the copied page the error is displayed.
<div class="panel-body" ng-app="myApp">
#*Attachment*#
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div>
#if (ViewBag.Attachments != null)
{
foreach (var a in ViewBag.Attachments)
{
var id = #a.AttachmentId;
#lastattachid = id;
<div class="row">
<div class="col-xs-12 left">
<a asp-action="Download" asp-route-path="#a.FilePath\\#a.FileName">#a.FileName</a>
<div style=" position: absolute;top: 2px;right: 2px;">
#if (ViewBag.recepient.Equals(#a.CreatedBy))
{
var FilePath = #a.FilePath.Replace("\\", "\\\\");
<a onclick='deleteattachment(#a.AttachmentId, "#a.FileName", "#FilePath")'>✘</a>
}
</div>
</div>
</div>
}
}
</div>
<hr />
<div>
<div>
<div>
<input name="attachedfile" type="file" file-model="attachedfile" />
</div>
</div>
<br />
<div>
<button ng-click="uploadAttachment()">Upload</button>
</div>
</div>
</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js">
</script>
<script>
var Attachment = (function () {
function Attachment(customer, invoice, name, dwg, attachedfile) {
this.attachmentid = #lastattachid + 1;
this.customer = customer;
this.jobInv = invoice;
this.jobName = name;
this.jobDwg = dwg;
this.path = "\\#ViewBag.customerId\\" + invoice + ";" + name + ";" + dwg + "\\";
this.fileName = attachedfile.name;
this.attachedfile = attachedfile;
}
return Attachment;
}());
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function () {
scope.$apply(function () {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('attachmentService', ['$http', function ($http) {
this.uploadAttachment = function (attachment) {
var fd = new FormData();
fd.append('AttachmentId', attachment.attachmentid);
fd.append('Customer', attachment.customer);
fd.append('JobInv', attachment.jobInv);
fd.append('JobName', attachment.jobName);
fd.append('JobDwg', attachment.jobDwg);
fd.append('Name', attachment.fileName);
fd.append('Path', attachment.path);
fd.append('attachedfile', attachment.attachedfile);
return $http.post('/Streaming/Upload', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
});
};
}]);
myApp.controller('myCtrl', ['$scope', 'attachmentService', function ($scope, attachmentService) {
$scope.uploadAttachment = function () {
$scope.showUploadStatus = false;
$scope.showUploadedData = false;
var attachment = new Attachment("#customerid","#inv", " ", " ", $scope.attachedfile);
attachmentService.uploadAttachment(attachment).then(function (response) { // success
if (response.status === 200) {
var inv = "#inv";
inv = inv.replace("&", "%26");
var job = "#job";
job = job.replace("&", "%26");
var dwg = "#dwg";
dwg = dwg.replace("&", "%26");
window.location.href = "/Quote/Details/#ViewBag.customerId?quoteno=" + inv;
}
},
function (response) { // failure
$scope.uploadStatus = "Attachment upload failed with status code: " + response.status;
$scope.showUploadStatus = true;
$scope.showUploadedData = false;
$scope.errors = [];
$scope.errors = parseErrors(response);
});
};
}]);
function parseErrors(response) {
var errors = [];
for (var key in response.data) {
for (var i = 0; i < response.data[key].length; i++) {
errors.push(key + ': ' + response.data[key][i]);
}
}
return errors;
}
</script>
Updated:
Server-side code is as below:
[HttpPost]
[DisableFormValueModelBinding]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Upload()
{
if (string.IsNullOrEmpty(userManager.GetUserName(User)))
return RedirectToAction(actionName: "Login", controllerName: "Account");
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
{
return BadRequest($"Expected a multipart request, but got {Request.ContentType}");
}
// Used to accumulate all the form url encoded key value pairs in the
// request.
var formAccumulator = new KeyValueAccumulator();
string targetFilePath = Directory.GetCurrentDirectory() + "\\wwwroot\\Attachment";
string fileName = "";
var boundary = MultipartRequestHelper.GetBoundary(
MediaTypeHeaderValue.Parse(Request.ContentType),
_defaultFormOptions.MultipartBoundaryLengthLimit);
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
while (section != null)
{
ContentDispositionHeaderValue contentDisposition;
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
if (hasContentDispositionHeader)
{
if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
{
using (var targetStream = System.IO.File.Create(targetFilePath + fileName))
{
await section.Body.CopyToAsync(targetStream);
_logger.LogInformation($"Copied the uploaded file '{targetFilePath + fileName}'");
}
}
else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
{
// Content-Disposition: form-data; name="key"
//
// value
// Do not limit the key name length here because the
// multipart headers length limit is already in effect.
var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
var encoding = GetEncoding(section);
using (var streamReader = new StreamReader(
section.Body,
encoding,
detectEncodingFromByteOrderMarks: true,
bufferSize: 1024,
leaveOpen: true))
{
// The value length limit is enforced by MultipartBodyLengthLimit
var value = await streamReader.ReadToEndAsync();
value = value.Replace("&", "&");
if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
{
value = String.Empty;
}
formAccumulator.Append(key, value);
if (key.Equals("Path"))
{
targetFilePath += value;
Directory.CreateDirectory(targetFilePath);
}
if (key.Equals("Name"))
fileName = value;
if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
{
throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
}
}
}
}
// Drains any remaining section body that has not been consumed and
// reads the headers for the next section.
section = await reader.ReadNextSectionAsync();
}
// Bind form data to a model
var attachment = new AttachFile();
var formValueProvider = new FormValueProvider(
BindingSource.Form,
new FormCollection(formAccumulator.GetResults()),
CultureInfo.CurrentCulture);
var bindingSuccessful = await TryUpdateModelAsync(attachment, prefix: "",
valueProvider: formValueProvider);
if (!bindingSuccessful)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
}
var user = userManager.GetUserName(User);
// Add attachmnet to a jason file
// ...
var uploadedData = new UploadedData()
{
Invoice = attachment.JobInv,
Name = attachment.JobName,
Dwg = attachment.JobDwg,
FileName = attachment.FileName,
FilePath = targetFilePath,
CreatedBy = user,
CreatedDate = DateTime.Now
};
return Json(uploadedData);
}
public class AttachFile
{
public int AttachmentId { get; set; }
public string Customer { get; set; }
public string JobInv { get; set; }
public string JobName { get; set; }
public string JobDwg { get; set; }
public string FileName { get; set; }
public string FilePath { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
}
public class UploadedData
{
public string Invoice { get; set; }
public string Name { get; set; }
public string Dwg { get; set; }
public string FileName { get; set; }
public string FilePath { get; set; }
public string Path { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
}

Can't pass a list of objects to the view using JSON

The data is passed from the controller to the view using AJAX call
but for some reason I am not able to retrieve it using JavaScript
the data shows an list on empty object!
public class Ville {
string wilPop { get; set; }// = null;
int identifiant { get; set; }// = -1;
bool affectedD { get; set; } //= false;
public Ville(string ewilPop, int eidentifiant, bool eaffectedD)
{
this.wilPop = ewilPop;
this.identifiant = eidentifiant;
this.affectedD = eaffectedD;
}
}
[Authorize]
[HttpPost]
public ActionResult GetWilByRegion(int? Wil)
{
if (Wil != null)
{
string wilPop = null;
int identifiant = -1;
bool affectedD = false;
//Get info from DB
List<city> ListWil = new List<city>();
ListWil = db.city.Where(m => m.idReg == Wil).OrderByDescending(m => m.population).ToList();
List<Ville> mylist = new List<Ville>();
foreach (city item in ListWil)
{
// Description in the DB
wilPop = item.city + " (" + item.population + ")";
// id value in the DB
identifiant = item.city_id;
// if checked or not
affectedD = CheckifWilAffected(item.city_id);
mylist.Add(new Ville(wilPop, identifiant, affectedD));
}
return Json(mylist, "Ville");
}
else return Json("Error");
}
mylist is not empty, it contains all the data (after debugging the controller)
This is my AJAX call :
$.ajax({
url: url,
data: { Wil: _idr },
cache: false,
type: "POST",
success: function (data) {
var markup = "";
for (var x = 0; x < data.length; x++) {
markup += '<input type=' + '"checkbox"' + ' name=' + data[x].wilPop + ' value=' + data[x].identifiant + '>' + data[x].wilPop + '</input>' + '<br/>';
}
$("#chWil").html(markup).show();
},
error: function () {
alert("Error - can't do the ajax call - please check your code..." );
}
});
}
You are getting an array of empty objects(without any properties) because your Ville class does not have any public properties.
You need to make your properties public
public class Ville
{
public string wilPop { get; set; }
public int identifiant { get; set; }
public bool affectedD { get; set; }
public Ville(string ewilPop, int eidentifiant, bool eaffectedD)
{
this.wilPop = ewilPop;
this.identifiant = eidentifiant;
this.affectedD = eaffectedD;
}
}
Now the JavaScript serializer will be able to use the values of those properties when creating a JSON string representation of your list.
I personally like to use PascalCasing for class property names.( WilPop instead of wilPop)

JSON data null in controller

I am working to send multiple email/SMS by selecting the checkbox. And When I am receiving in my javascript function it's getting with data. But when I pass it to action method record count shows but all data are null. Below is my code with screenshot here
Here it is my Model:
public class BulkEmailSendViewModel
{
public BulkEmailSendViewModel()
{
Candidates = new List<CandidateData>();
}
public List<CandidateData> Candidates { get; set; }
public string Body { get; set; }
public string Subject { get; set; }
}
public class CandidateData
{
public string Email { get; set; }
public string CandidateId { get; set; }
public string Phone { get; set; }
public string CandidateName { get; internal set; }
}
//Select all selected checkbox
$("#bulkAction").change(function () {
var ddlId = $("#bulkAction").val();//to get sms or email
var chk_arr = $('.checkCandidate:checkbox:checked');
var chklength = chk_arr.length;
var json = '';
$('.checkCandidate:checkbox:checked').each(function () {
if (this.checked) {
var Phone = $(this).attr("candidatePhone");
var CandidateId = $(this).attr("candidateId");
var Email = $(this).attr("candidatEmail");
var item = '{\"Phone\":\"' + Phone + '\","CandidateId\":\"' + CandidateId + '\",\"Email\":\"' + Email + '\",\"CandidateName\":\"\"},';
json += item;
}
});
json = "[" + json.substr(0, json.length - 1) + "]";
SendBulkEmail(json);
});
My Javascript:
function SendBulkEmail(jsonObj) {
alert(jsonObj);
if (jsonObj.length > 0) {
var send = "/Utility/Notifications/BulkEmail";
$(".modal-title").text("Send Email");
//var data = {
// Candidates: eval(jsonObj)
//};
$.get(send, { bulkEmailSendViewModel: eval(jsonObj) }, function (result) {
$("#C_modal_body").html("");
$("#C_modal_body").html(result);
});
}
else {
$.alert("Email not found for this candidate.");
// e.stopPropagation();
}
}
My Controller:
public PartialViewResult BulkEmail(List<CandidateData> bulkEmailSendViewModel)
{
BulkEmailSendViewModel bulkDetail = new BulkEmailSendViewModel();
return PartialView(bulkDetail);
}
Why my all values are null even I am getting in javascript function?
change your javascript codes to this:
$("#bulkAction").change(function () {
var ddlId = $("#bulkAction").val();//to get sms or email
var chk_arr = $('.checkCandidate:checkbox:checked');
var chklength = chk_arr.length;
var data = [];
$('.checkCandidate:checkbox:checked').each(function () {
if (this.checked) {
var Phone = $(this).attr("candidatePhone");
var CandidateId = $(this).attr("candidateId");
var Email = $(this).attr("candidatEmail");
var item = {Phone: Phone,
CandidateId: CandidateId,
Email : Email,
CandidateName : ""};
data.push(item);
}
});
SendBulkEmail(data);
});
and the SendBulkEmail to:
function SendBulkEmail(data) {
if (data.length > 0) {
var send = "/Utility/Notifications/BulkEmail";
$(".modal-title").text("Send Email");
//var data = {
// Candidates: eval(jsonObj)
//};
$.post(send, { bulkEmailSendViewModel: JSON.stringify(data) }, function (result) {
$("#C_modal_body").html("");
$("#C_modal_body").html(result);
});
}
else {
$.alert("Email not found for this candidate.");
// e.stopPropagation();
}
}
and finally:
[HttpPost]
public PartialViewResult BulkEmail(List<CandidateData> bulkEmailSendViewModel)
{
BulkEmailSendViewModel bulkDetail = new BulkEmailSendViewModel();
return PartialView(bulkDetail);
}
In your controller, I don't see any use of the bulkEmailSendViewModel input parameter.
Maybe, you could propagate the candidate list as follow:
public PartialViewResult BulkEmail(List<CandidateData> candidates)
{
BulkEmailSendViewModel bulkDetail=new BulkEmailSendViewModel();
bulkDetail.candidates = candidates;
return PartialView(bulkDetail);
}

Converting JSON object into C# list

Before posting this question I tried other related posts but it didn't work out, so posting here.
I have got a Json stored in a hidden field that I am accessing in code behind file of my Mark-up page. I need to convert this Json into List and bind it to a grid, but while de-serializing it throws error saying "Unexpected error encountered while parsing values ''".
Script for getting data from grid and making a Json object.
function BeforeSorting() {
var list = UpdateDataSource();
$("#SortingField").val(list);
}
function UpdateDataSource() {
var list="";
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
for(var i =0 ; i<rows.get_length();i++){
var name = rows.get_row(i).get_cellByColumnKey("Name").get_value();
var country = rows.get_row(i).get_cellByColumnKey("Country").get_value();
var gender = rows.get_row(i).get_cellByColumnKey("Gender").get_value();
var age = rows.get_row(i).get_cellByColumnKey("Age").get_value();
var uniqueKey = rows.get_row(i).get_cellByColumnKey("UniqueKey").get_value();
list = list + '{"Name":"' + name + '", "Country":"' + country + '", "Gender":"' + gender + '", "Age":' + age + ', "UniqueKey":' + uniqueKey + '},';
}
list = "["+list.substr(0, list.length - 1)+"]";
return JSON.parse(list);
}
The model class:
public class Details
{
public string Name { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
public int UniqueKey { get; set; }
public int Age { get; set; }
}
The code for de-serializing the json and retrieving data as a list of the model class.
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e)
{
var dataSource = SortingField.Value;
List<Details> result = (List<Details>)Newtonsoft.Json.JsonConvert.DeserializeObject(dataSource, typeof(List<Details>));
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
The json string as obtained:
"[{"Name":"Jerry", "Country":"U.S.A.", "Gender":"Male", "Age":20, "UniqueKey":1},{"Name":"Tom", "Country":"U.K", "Gender":"Male", "Age":10, "UniqueKey":2},{"Name":"George", "Country":"Gremany", "Gender":"Male", "Age":38, "UniqueKey":3},{"Name":"Kate", "Country":"France", "Gender":"Female", "Age":40, "UniqueKey":4},{"Name":"Jenny", "Country":"Poland", "Gender":"Female", "Age":25, "UniqueKey":5}]"
create list as an array and add items as JavaScript objects and then convert it to JSON using JSON.stringify
function UpdateDataSource() {
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
var list = [];
for(var i =0 ; i < rows.get_length(); i++){
var item = {
Name : rows.get_row(i).get_cellByColumnKey("Name").get_value(),
Country : rows.get_row(i).get_cellByColumnKey("Country").get_value(),
Gender : rows.get_row(i).get_cellByColumnKey("Gender").get_value(),
Age : rows.get_row(i).get_cellByColumnKey("Age").get_value(),
UniqueKey : rows.get_row(i).get_cellByColumnKey("UniqueKey").get_value()
};
list.push(item);
}
return JSON.stringify(list);
}
The code for de-serializing the json and retrieving data as a list of the model class can be refactored to
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e) {
var dataSource = SortingField.Value;
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Details>>(dataSource);
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
UPDATE as suggested by #Adnreas should produce the same result.
function UpdateDataSource() {
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
var list = rows.map(function(row) {
return {
Name: row.get_cellByColumnKey("Name").get_value(),
Country: row.get_cellByColumnKey("Country").get_value(),
Gender: row.get_cellByColumnKey("Gender").get_value(),
Age: row.get_cellByColumnKey("Age").get_value(),
UniqueKey: row.get_cellByColumnKey("UniqueKey").get_value()
};
});
return JSON.stringify(list);
}
I think this will do
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e)
{
var dataSource = SortingField.Value;
List<Details> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Details>>(dataSource);
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}

Pass JSON object list to action

I have a Model like this in my ASP.NET MVC 2 project,
public class HomeModel
{
public string Name { get; set; }
public int HomeCount { get; set; }
private List<string> _list;
public List<string> List
{
get
{
if (_list == null)
{
_list = new List<string>();
}
return _list;
}
set
{
_list = value;
}
}
private List<ChildModel> _children;
public List<ChildModel> Children
{
get
{
if (_children == null)
{
_children = new List<ChildModel>();
}
return _children;
}
set
{
_children = value;
}
}
}
public class ChildModel
{
public string Address { get; set; }
}
and the script as
var obj = new Object();
obj.Name = "MyName";
obj.HomeCount = 56;
obj.List = new Array();
obj.List[0] = "AAA";
obj.List[1] = "bbb";
var child = new Object();
child.Address = "ccc";
obj.Children = new Array();
obj.Children[0] = child;
var child2 = new Object();
child.Address = "ddd";
obj.Children[1] = child2;
jQuery.ajaxSettings.traditional = true
$.post('/Home/Test',obj, function (data) { });
My problem is even the string list is generated at the controller's action, the object list's count is 0. Can anyone tell how to do this?
When you submit an object as jQuery's ajax payload, it's converted to key/value pairs of data. If this were $.get instead of $.post for example, you'd wind up with
?name=MyName&etc.
This article should get you what you're looking for:
http://www.intelligrape.com/blog/2010/06/11/jquery-send-json-object-with-an-ajax-request/
I'd also recommend json/object literal notation here:
var obj = {
Name: "MyName",
HomeCount: 56,
List:["AAA","bbb"],
child:{
Address: "ccc",
Children:[
//etc
]
}
}
see json.org for specs, and jslint.com/jshint.com for validation.

Categories

Resources