passing Array data dynamically in URL to call webapi method (C#) - c#

below is my json generated data from the backend
{"langs":[{"cisAreaId":100,"area":"Prog","name":"C#"},{"cisAreaId":110,"area":"Prog","name":"Java"},{"cisAreaId":120,"area":"Prog","name":"MS.NET languages(VB.NET,etc)"},{"cisAreaId":130,"area":"Prog","name":"MS Visual Languages (VB, C++, etc)"},{"cisAreaId":140,"area":"Prog","name":"Python"},{"cisAreaId":150,"area":"Prog","name":"Ruby"}]}
above data i copied to $scope.areas.
Now in my view
<div ng-repeat="lang in areas.langs">
<label><input type="checkbox" ng-model="lang.selected" value="{{lang.cisAreaId}}" /> {{lang.name}}</label>
</div>
once user click the submit, I need to capture selected checkbox values and send it as JSON data.
$scope.languageArray = [];
angular.forEach($scope.areas.langs, function (lang) {
if (lang.selected) $scope.languageArray.push({ "cisAreaId": lang.cisAreaId });
});
var data = JSON.stringify({
languages: $scope.languageArray,
});
it is forming the array like after selecting the two of the checkbox values
{"languages":[{"cisAreaId":110},{"cisAreaId":120}]}
From the above code how can I pass the above dynamic array in the URL to call the backend method
Angularjs Controller Code:
XXXService.step2Form(data).then(function (results) {
console.log(results.data);
}, function (error) {
alert(error.data.message);
});
service code:
var _step2Form = function (data) {
return $http.post(serviceBase + 'api/feedback/Step2Data' + data , { headers: { 'Content-Type': 'application/json' } });
};
I have pass the data dynamically to the backend
public HttpResponseMessage Step2Data([FromBody] int[] languages)
but i am getting the error like this
http://localhost:53401/api/XXXX/Step2Data[object%20Object],[object%20Object] 404 (Not Found)
can anyone please tell me how to pass the array values dynamically in the url to call the webapi method.

in $scope.languageArray you need to push just the id :
$scope.languageArray = [];
angular.forEach($scope.areas.langs, function (lang) {
if (lang.selected) $scope.languageArray.push(lang.cisAreaId);
});
var data = JSON.stringify({
languages: $scope.languageArray,
});

Related

Parse JSON from C# to AngularJS

I have an array of file names:
[HttpPost]
public JsonResult GetJSONFilesList()
{
string[] filesArray = Directory.GetFiles("/UploadedFiles/");
for (int i = 0; i < filesArray.Length; i++)
{
filesArray[i] = Path.GetFileName(filesArray[i]);
}
return Json(filesArray);
}
I need this in AngularJS as a list of objects so I can ng-repeat it out and apply filters. I'm unable to figure out how to get the JSON from the MVC controller to AngularJS.
I've tried the following to make it visible to the view for angular to grab, but I don't know how to make the ng-init see the function to return the list. It erros on "SerializeObject(GetJSONFilesList())" saying it doesn't exist in current context.
<div ng-controller="MyController" data-ng-init="init(#Newtonsoft.Json.JsonConvert.SerializeObject(GetJSONFilesList()),
#Newtonsoft.Json.JsonConvert.SerializeObject(Model.Done))" ng-cloak>
</div>
EDIT:
I've tried using http.get.
Test one:
alert('page load');
$scope.hello = 'hello';
$http.get('http://rest-service.guides.spring.io/greeting').
then(function (response) {
$scope.greeting = response.data;
alert($scope.greeting);
});
alert($scope.hello);
The alert in the http.get never fires, the other alerts do however.
Test two:
$http({
url: '/Home/testHello',
method: 'GET'
}).success(function (data, status, headers, config) {
$scope.hello = data;
alert('hi');
});
[HttpPost]
public string testHello()
{
return "hello world";
}
This causes the angular to break and nothing in the .js works.
Test three
alert('page load');
$scope.hello = 'hello';
$scope.GetJSONFilesList = function () {
$http.get('/Home/testHello')
.success(function (result) {
$scope.availableFiles = result;
alert('success');
})
.error(function (data) {
console.log(data);
alert('error');
});
alert('hi');
};
alert($scope.hello);
[HttpPost]
public string testHello()
{
return "hello world";
}
Alerts nothing from within it, other alerts work.
Fixed:
After some googling, I've found that using .success and .error are deprecated and that .then should be used. So by using .then this resulted in the C# being hit via debug.
Then after using console.log on the returned value found that to have anything be returned I needed to return the value from C# using "return Json(myValue, JsonRequestBehavior.AllowGet); "
And by viewing the object in the console in Chrome by using console.log, I could see my values were in the data part of the returned object.
It was stored in data as an array (as I was passing an array).
I could then get the data out of there by assigning the returned value.data to a scope and could call that in the view {{result[1]}} etc.
return Json(filesArray, JsonRequestBehavior.AllowGet);
$scope.fileList;
$http.get("/Home/GetFileList").then(function (result) {
console.log(result)
$scope.fileList = result.data;
})
Imagine that you divide your front end in three layers (MVC or MVVM) whatever you want.
When you need info from server, the best practice is to separate the logic that makes the request and the logic that manipulates the data.
More info about how to make the request you can find it reading about REST APIS in Consuming a RESTful Web Service with AngularJS.
Normally one of the layers requires the use of services and you can have your controllers and your services (the place where you get the raw data from the server and you make the request. For that you need to use the $http service from angularjs.
$http: The $http service is a core AngularJS service that facilitates communication with the remote HTTP servers via the browser's XMLHttpRequest object or via JSONP.
So basically it shows you how to make get, post and put requests. One example from the documentation is :
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Pay attention to the url because there is the place where you let your request knwow which method is going to be hit on the server to take the action. If your request is succesful, then you can use the parameter called response. From there, you can do whatever you want. If you decide to make that request part from your controller, you can assign it directly to a variable on your scope. Pay attention if you need to serialize the data. Something like
$scope.myResponseName = response.name ;
The first documentation link from above shows this example which does exactly what I tell you.
angular.module('demo', [])
.controller('Hello', function($scope, $http) {
$http.get('http://rest-service.guides.spring.io/greeting').
then(function(response) {
$scope.greeting = response.data;
});
});
After all the mentioned above, pay attention to what you want to display. Are you going to display the elements of an object array? The use on your HTML the ng-repeat directive. Are you going to display just a variable (No array nor object) then you use need to use an angular expression {{ }}
In summary:
By making an HTTP request, hit the correct method on server.
Make sure you are sending the JSON correctly and that the data is correct.
Retrieve the data on your response.
Assign the data to a variable on your scope and serialize the data if needed.
Display the data correctly depending if it is within an array, if it´s an object or if its just a variable.
I hope the explanation makes sense and check the documentation if you need more info.
You can build your viewmodel so that it contains the data you'd like to serialize and then pass it to angularJS in your view as follows:
<div ng-controller="MyController" data-ng-init="init(#JsonConvert.SerializeObject(myArrayData),
#Newtonsoft.Json.JsonConvert.SerializeObject(Model.Done))" ng-cloak>
and then in your angular controller have a function to receive the data as follows:
$scope.init = function (myArrayData) {
//do something with data
};
The above assumes you're trying to pass data from mvc to angularjs on page load. If you're trying to hit a controller and get data back to angularjs upon some event such as a button click, then you can write an angularjs function similar to the following (this will be an asynchronous request):
app.controller('MyController', function ($scope, $http, $window) {
$scope.ButtonClick = function () {
var post = $http({
method: "POST",
url: "/SomeController/SomeAjaxMethod",
dataType: 'json',
data: { path: $scope.Path},
headers: { "Content-Type": "application/json" }
});
post.success(function (data, status) {
//do something with your data
});
post.error(function (data, status) {
$window.alert(data.Message);
});
}
}
and your controller action would look something like:
[HttpPost]
public JsonResult SomeAjaxMethod(string path)
{
string[] filesArray = Directory.GetFiles(path);
for (int i = 0; i < filesArray.Length; i++)
{
filesArray[i] = Path.GetFileName(filesArray[i]);
}
return Json(filesArray);
}
other answers say to use .success in the angular function, .success and .error are deprecated, instead .then should be used.
Working result:
MVC:
public JsonResult GetFileList()
{
//form array here
return Json(myArray, JsonRequestBehavior.AllowGet);
}
The function needs to be of type JsonResult, and the returned value of Json using JsonRequestBehavior.AllowGet.
AngularJS:
$scope.fileList;
$http.get("/Home/GetFileList").then(function (result) {
console.log(result)
$scope.fileList = result.data;
})
This is in my AJS controller, using .then instead of .success. If you use console.log the result returned from the mvc controller and view it in the browser inspect you'll see the object with lots of other info and the values you want are in the .data section of the object.
So to access the values you need to do result.data. In my case this gives me and array. I assign this to a scope. Then in my view I can access the values by doing {{fileList[1]}} etc. This can also be used in ng-repeat e.g:
<div ng-repeat="file in fileList">
{{fileList[$index]}}
</div>
Each value in the array in the repeat can be accessed using $index which is the number of the repeat starting at 0.

Need to send a hidden input value to mvc controller using angularjs

I have a hidden input field that contains a value I need to send my mvc controller.
$http({ method: 'GET', url: '/User/GetProjectsList' })
.success(function (data, status, headers, config) {
$scope.workflow = [];
$scope.Projects = data;
})
.error(function (data, status, headers, config) {
alert('error');
});
And the hidden field is:
<input type="hidden" ng-model='ProjectId' value="{{ProjectsObj.IDWorkflow}}"></input>
How can I send the value to the my controller and how do I get it in the controller? This is the method I had on the MVC controller.
[HttpPost]
public JsonResult GetProjectsList()
{
return Json();
}
Have you tried with query string ?
var pID=$scope.ProjectId
$http({ method: 'GET', url: '/User/GetProjectsList?ProjectID='+pID}).
success(function (data, status, headers, config) {
$scope.workflow = [];
$scope.Projects = data;
}).
error(function (data, status, headers, config) {
alert('error');
})
;
I hope this helped you ;)
app.controller("myCtrl", function($scope) {
$scope.formDetails = {};
$scope.sendToApi = function(){
var model = {
id: $scope.formDetails.id //this is my hidden input
name: $scope.formDetails.name,
}
//and then send your model to API
}
})
#Html.HiddenFor(m => m.ProjectId)
You Can Simply Pass Hidden Value To Controller From View By using model value like above syntax.
It seems like AngularJS does not take in consideration hidden input when submitting forms, check this issue for more details. But you can get your value in 2 ways:
classic way:
remove ng-model since has no sens with hidden type as explained above and add id:
<input id="project_id" type="hidden" value="{{ProjectsObj.IDWorkflow}}"/>
in Javascript side you simply do:
var project_id = document.getElementById('45').value;
AngularJS way
since Angular ignores hidden elements, you can replace it with type=text and display:none:
<input type="text" name="project_id" ng-model="projectID" style="display: none;"/>
and your javascript side using two way data-binding you can acces your ng-model variable:
var project_id = $scope.projectID;

Passing an array from javascript to code behind - C#

In my website, i'm declaring an array in javascript and insert them elements dynamically. So now, I want use that array from my C# code. I don't want use ajax to send that element to an web service... I just want use an C# event, like OnClick and access the array that was build in javascript.
I searched for an answer but I just found the oposite.
Thanks
The easiest way is AJAX call and i don't understand why you are avoiding that ?
Make an AJAX call from your button click.
look here a demo :
Ajax call is not calling to the server side and in httpfox shows error as "Error loading content (NS_ERROR_DOCUMENT_NOT_CACHED)" in ajax post call
for example : covert your array to a json string and call a web client in your c# code. Here i have a button . on button click i want to send my GRIDVIEW data to c# method(web method).
you need to remember that while sending json data using stringfy() method,
in server side we need to define the parameter as object.
not any other format like string/int/bla bla.....
use Scripts/jquery-1.8.3.min.js
http://code.jquery.com/ui/1.10.3/jquery-ui.js
$('#btnResult').on('click', function () {
var mydata = [];
$("#<%=GridProjectDetails.ClientID %> tr").each(function () {
var myObject = new Object();
var id = $(this).find("input[name*='ID']").val();
var locationcode = $(this).find("input[name*='TextLocationCode']").val();
var Location = $(this).find("input[name*='TextLocation']").val();
myObject.id = id;
myObject.locationcode = locationcode;
myObject.Location = Location;
mydata.push(myObject);
});
var myString = JSON.stringify({ details: JSON.stringify(mydata) });
alert(myString);
var exportdata = myString;
$.ajax({
type: "POST",
url: "Default.aspx/ExportToExcel",
data: exportdata,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#Result").text(data.d);
},
error: function () { alert(arguments[2]); }
});
});
});
and server side method should be
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ExportToExcel(object details)
{
return "Message : Success";
}
It's a kinda weird thing to do, but if you have to do it, you can do it by creating a form, inside the form have a hidden text field and call a function when submitting to update the value of this field.
The markup:
<form id="yourForm" method="post" >
<input type="text" name="hiddenFieldName" id="hiddenFieldName" hidden="hidden" />
</form>
The javascript:
void yourProcedure() {
var yourArray = ["Value1", "Value2", "Value3", "Value4"];
document.getElementById('hiddenFieldName').value = yourArray.join();
document.getElementById("yourForm").submit();
}
Then in the server, the form variable will contain "Value1,Value2,Value3,Value4".

display json data from controller inside view

Inside my controller there is JsonResult action which returns me a list of House object.
I want onclick using ajax to retrieve these data and to display json data inside my view.
Inside firebug I'm able to see proper Response and Json result but I dont know how to display inside my view.
function GetTabData(xdata) {
$.ajax({
url: ('/Home/GetTabData'),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ id: xdata }),
success: function (result) {
// tried with these but it doesnt work
// result = jQuery.parseJSON(result);
// alert(result.Title);
},
error: function () { alert("error"); }
});
}
public JsonResult GetTabData()
{
...
var temp = getMyData...
return Json(temp, JsonRequestBehavior.AllowGet);
}
// View page
<div id="showContent">
// Json data should appear here
</div>
Inside firebug JSON tab when success:function(result) is empty
I have following data:
Id 149
PropertyType "Apartment"
StreetNumber "202B"
CityName "Sidney"
Title "My test data"
success: function (json) {
var data = null;
$.each(json.items,function(item,i){
data = '<div>'+item.Id+ ' ' + item.CityName +'</div>';
$("#showContent").append(data);
});
}
First of all, you can specify the dataType attribute in your ajax call to 'json' and then don't have to decode the json response again -
dataType: 'json'
Then, you don't need to use parseJSON. Simply use result.Title etc.
success: function (result) {
alert(result.Title);
var showContent = $('#showContent');
showContent.html(result.Id+','+result.Title);
},
EDIT: As Mukesh said, you can have the ajax function return json without using any extra decoding.
The ajax call result is already an object. You can do whatever you want with it it inside the success function.
For example you could create a table of the information dynamically inside the function, or send the data to another function by calling the function inside that success function. Once you leave the success function, the data is not usable anymore.
Access the data object like any object (data.someProperty).

asp.net mvc2 select value from database according to listbox value

I am using asp.net mvc2.I have a listbox and textbox when i select an item from listbox corresponding value to that item should appear in textbox from database.please help
You should use JavaScript for handle listbox selection changes.
And read about Ajax, it neads to get the data from DB without reloadin page.
Add
Example how can you handle listbox selection changes.
#Html.ListBox("nam",new SelectList(new string[]{"opt1","opt2"}),new {onchange = "javaScript:actch()", id = "namid"})
<script type="text/javascript">
function actch() {
alert(document.getElementById("namid").value);
}
</script>
Value "document.getElementById("namid").value" contains option that you select.
You should send this value to the server and recieve request
#Html.ListBox("nam",new SelectList(new string[]{"opt1","opt2"}),new {onchange = "javaScript:actch()", id = "namid"})
<script type="text/javascript">
function actch() {
$.ajax({
url: "your url",
type: "POST",
data: "id = " + document.getElementById("namid").value,
success: function (data) {
// action on success
document.getElementById("TextBoxId").value = data;
},
error: function (jqXhr, textStatus, errorThrown) {
// action on fail
},
complete: function () {
}
});
}
</script>
You have to write a server request part, and configure ajax.
(I had use jQuery)
Added: Server request part (example)
[HttpPost]
public MvcHtmlString Detail(string id)
{
var d = _db.GetVehicle(Convert.ToInt32(id));
var sb = new StringBuilder();
sb.AppendLine(string.Format("Type: {0}</br>", d.Type));
sb.AppendLine(string.Format("Brand: {0}</br>", d.Brand));
sb.AppendLine(string.Format("Model: {0}</br>", d.Model));
sb.AppendLine(string.Format("Number: {0}</br>", d.Number));
sb.AppendLine(string.Format("Year: {0}</br>", d.Year));
sb.AppendLine(string.Format("Cost: {0}</br>", d.Cost));
return new MvcHtmlString(sb.ToString());
}
URL looks like: MyController/Detail/
DATA for ajax: "id=" + document.getElementById("namid").value
P.S. Some one edit/spoil my ansver and it's not marked(
Your question is a little vague but this is basically how it can be done:
You can post the value of the listbox in the change event by using jquery (or any other JS library of your preference). Then the controller gives a value back, which you then put in the textbox.
Check out http://api.jquery.com/jQuery.post/

Categories