Sending array from URL.Action and getting null in controller - javascript

I have a function that after adding items in a for loop calls the controller through the action URL sending the arr parameter (array), I see that it sends the data but null appears in the controller parameter. I wanted to know what could be wrong?
Javscript Function
function Submit() {
QRCodeval.forEach((code) => arr.push(code.innerHTML));
window.location.href = "#Url.Action("ReceivedFromBarCode","PurchaseOrder")?" +arr;
}
Link generated by the controller:
http://localhost:56978/PurchaseOrder/ReceivedFromBarCode?JJJKP,RRPRQ,PPLQR
Controller where I get null in the arr parameter.
public async Task<ActionResult> ReceivedFromBarCode(string[] arr)
{
return View();
}

The MVC model binder expects arrays to be passed in the following format: arr=value1&arr=value2&...
You can use map() and join() to create the correct format. But you'll also need to encode the values since they are parameters in a URL. encodeURIComponent can help with that:
let urlParams = array.map((val) => {
return `arr=${encodeURIComponent(val)}`
}).join('&');
window.location.href = "#Url.Action("ReceivedFromBarCode","PurchaseOrder")?"
+ urlParams;
And append the urlParams to your URL. Example output in snippet below:
let array = ["value1", "http://example.com?x=1", "<script>alert('')</sctipt>"];
let urlParams = array.map((val) => {
return `arr=${encodeURIComponent(val)}`
}).join('&');
console.log(urlParams);

Related

Pasing Javascript result to View

I got a Question, I'm really new in working with Asp.net.
I got a Javascript where I woult like to pass Data to my Controller.
<script type="text/javascript">
$("#SearchButton").on("click", function () {
var $sucheMoped = [];
$("#tab_logic tbody tr")
.each(function () {
var $Item = $(this);
var suchfeld = $Item.find("td > input[name='Suchfeld']").val();
var schluessel = $Item.find("td > select[name='Suchschluessel'] > option:selected").val();
alert(suchfeld + "&&&" + schluessel);
$sucheMoped.push({
Suchfeld: suchfeld,
Suchschluesseltyp: schluessel
});
});
window.open('#Url.Action("MainView","MainView")?SuchObject='+$sucheMoped);
})
</script>
I just would like to pass the "sucheMoped" from my javaScript to my Controller.
My Controller is just expecting a IEnumarable of Objects with Properties Suchfeld and Suchschluesseltyp.
Anyone an idea?
Thanks Guys.
First of all, you need to change the way you invoke the controller action. You should stringify the array using the JSON.stringify() method.
So, this should look like this:
window.open('#Url.Action("MainView","MainView")?SuchObject='+JSON.stringify($sucheMoped));
Then, you need to create a custom model binder to bind your array with the action parameter. This is a simple array model binder for demonstration purposes only, it doesn't take into account failures or whatever, but it works in this scenario, passing the correct data, so please modify it to fit your needs.
public class ArrayModelBinder: DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var rawArray = controllerContext.HttpContext.Request.QueryString["SuchObject"];
var array = JsonConvert.DeserializeObject<IEnumerable<MyObject>>(rawArray);
return array;
}
}
What I do here, is to get the query string submitted through the URL, convert it with JsonConvert.Deserialize<T> method and return it.
You simply need to decorate your parameter in the controller's action with the custom model binder, like this:
[HttpGet]
public ActionResult Search([ModelBinder(typeof(ArrayModelBinder))]IEnumerable<MyObject> SuchObject)
{
return View(SuchObject);
}
Edit
window.open is useful if you want to open a new browser window. You could use it to open a new tab as well.
In order to navigate to another location without opening a new tab or window, use the window.location property like the following:
window.location = '#Url.Action("Search", "Home")?SuchObject=' + JSON.stringify(array);
If you use the jQuery.ajax method, you can pass complex objects as data parameter.
$.ajax({
url: '#Url.Action("MainView", "MainView")',
type: 'GET',
data: { 'SuchObject': $sucheMoped },
success: function (htmlContent) {
// write content to new window (from http://stackoverflow.com/a/23379892/1450855)
var w = window.open('about:blank', 'windowname');
w.document.write(htmlContent);
w.document.close();
}
});
You can use jquery library $.getScript to call the action method in your controller and the return javascriptResult type in your action.
$.getScript("Home","Display")
// Home Controller
private JavaScriptResult Display()
{
string message = "alert('Hello World');";
return new JavaScriptResult { Script = message };
}

URL parameters on javascript

I´m making a call using javascript and I would like to send an array:
var selected = [];
selected=getAllEnginesIdsSelected();
console.log("selected: "+selected);
$.getJSON('/call/' + selected,
function(myList) {
The funcion that I use in Javascript to retrieve array is:
function getAllEnginesIdsSelected() {
var selected = [];
$("input:checkbox[id^='engine_']:checked").each(function(){
var ele=$(this)[0].id;
selected.push(ele);
});
return selected;
}
Console.log retrieves selected: 2,5
In MVC Controller I have
#RequestMapping(method = RequestMethod.GET, value = "/call/{selected}")
public List<List<myList>> myCall(#RequestParam(value="selected[]") String[] selected){
I gives an error. I don´t want to use AJAX. This is posible to send?
selected is an array, which you are joining to a string in the URL. Try something like $.getJSON('/call/?selected=[' + selected.join(',')]

Angular 2 - Http Get request - pass json Object

How can I do a http get request and pass an json Object
This is my json-Object
{{firstname:"Peter", lastname:"Test"}
and this Object I want to pass in the http request to get a list Of matched persons.
how is it possible? This example just shows a simple get request with a json result. How do I have to modify it?
//Component:
person:Person;
persons:Person [];
....
//Whre can I pass the person, here in the service??
getMatchedPersons(){
this.httpService.getMatchedPersons().subscribe(
data => this.persons = data,
error => aller(error)
);
);
//SERVICE
//pass parameters?? how to send the person object here?
getMatchedPersons(){
return this.http.get('url').map(res => res.json());
}
The Http.get method takes an object that implements RequestOptionsArgs as a second parameter.
The search field of that object can be used to set a string or a URLSearchParams object.
An example:
// Parameters obj-
let params: URLSearchParams = new URLSearchParams();
params.set('firstname', yourFirstNameData);
params.set('lastname', yourLastNameData);
//Http request-
return this.http.get('url', {
search: params
}).subscribe(
(response) => //some manipulation with response
);
For pure javascript:
You must serialize your json to a list of parameters:
?firstname=peter&lastname=test
and append it to the URL because GET requests have no body.
There are a few ways of converting JSON to QueryParameters.
They are addressed in this question: Is there any native function to convert json to url parameters?
There you can choose the poison of your liking, mine was:
function obj_to_query(obj) {
var parts = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
}
}
return "?" + parts.join('&');
}
But mind you that GET requests must obbey the URL limit that based on this answer is recomended to stay under 2000 characters to be safe:
RFC says 8000
IE8 and IE9 go as far as 2083
Search engines only read to 2048
Using Angular2 URLSearchParams
With the same method of converting a plain JSON to arguments one could use URLSearchParams as suggested by Рома Скидан:
let params: URLSearchParams = objToSearchParams(obj);
return this.http.get('url', {
search: params
}).subscribe(
(response) => //some manipulation with response
);
function objToSearchParams(obj): URLSearchParams{
let params: URLSearchParams = new URLSearchParams();
for (var key in obj) {
if (obj.hasOwnProperty(key))
params.set(key, obj[key]);
}
return params;
}
Maybe you want to stringify the json object
var json = JSON.stringify(myObj);
this.http.get('url'+'?myobj='+encodeURIComponent(json))
Use a POST request to pass objects to the server:
//SERVICE
getMatchedPersons(searchObj: any){
return this.http.post('url', JSON.stringify(searchObj))
.map(res => res.json());
}
Then you can pass whatever JS object you want and send it to the server in your http request.
getMatchedPersons(searchObj: any){
this.httpService.getMatchedPersons(searchObj: any).subscribe(
data => this.persons = data,
error => alert(error);
);
);
Similar to AngJobs' but maybe more up-to-date?? Calling encodeURIComponent is not necessary. Here's the Angular:
const stringifiedParams = JSON.stringify(this.filterParams);
return this.http.get<any[]>(`persons`, {params: {filter: stringifiedParams}});
On the server Node deserializes the params with JSON.parse:
filter = JSON.parse(req.query.filter.toString());
Actually there's an easier way for flushing parameters
getMatchedPersons(myObject: any): Observable<Person[]> {
return this.http.get<Person[]>('url', { params: { ...myObject } });
}
The above code represents a function that accepts a JSON object myObject as a parameter.
HttpClient.get method accepts an options paramter as its second paramter.
The options parameter contains many useful keys, but we're only interested with the params key in our case.
the value of params is { ...myObject }, that is- we're using the spread operator to pass all key:value pairs from an object.
Refer that this will do the job, and will not make the URL look ugly with all those ? and key=value and & characters, of course in either case those parameters won't be shown for the user since it's just an HTTP call, but still, if anyone is using a logger interceptor, they will have a clean log.

pass collection of objects through http post in angular js

I have pass a collection of objects through http post in angular js.
The code is as follows:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data.ContentId, { Selected: true }); // I could able to get all the selected objects here, No problem with it
var jsonData = angular.toJson(contents); //It is not able to convert to Json if there are more than 5 records
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent?jsonData=' + jsonData, {});
promise.success(function () {
window.location.reload();
});
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(string jsonData)
{
var contents = JsonConvert.DeserializeObject<List<ContentNodeInWorkFlow>>(jsonData);
foreach (var content in contents)
{
_contentService.PublishContent(content.ContentId, userId);
}
}
}
The above code works fine if there are 5 records or less. If there are more records, I could able to get all the selected record
objects in the variable 'contents'. But the problem is occuring when converting to Json for all those objects. I
have about 500 records to pass through. How can do I it?
There is no specific reason to convert to JSON data. I just need to extract the ids of all the selected items. I have modified the above code as below:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var abc = [];
angular.forEach(contents, function(content)
{
abc.push(content.ContentId); // got all the ids in the array now
});
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,{contents : abc});
promise.success(function () {
window.location.reload();
});
}
I have just took an array and pushed all the content ids into it. I could able to see all the ids in the array now. I tried to pass the array as above.
How to retrieve those array in the code behind.
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(int[] abc)
{}
I do not see any values obtained under int[] abc. What will be the datatype for the parameter in the method call above.
You need second argument of $http.post method. You have to send such data by POST requests, not in query of url. You can put some data into body of the post request.
You need this:
var postBodyWithHugeAmountOFData = {data: [1,2,3,4,5...500]};
$http.post(url, postBodyWithHugeAmountOFData).success(function () {});
Also, you must be ready to handle this request in your backend.
is there any specific reason u want to pass this data as a JSON?.
if u r using Web API in that case u can pass the object as it is but only make sure that collection in web API method contains all the property in javascript collection
Thank you for all your posts. It's working fine without converting to Json. The code is as below.
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,contents);
promise.success(function () {
window.location.reload();
});
}
and the signature would be
public void CmsPublishApprovedContent(List<ContentNodeInWorkFlow> abc)
{
}

Pass multiple array as parameters to Home Controller using getJSON

I have to make a json call to home controller where I need to pass multiple arrays.
var assetids = new Array(N);
var faultTimes = new Array(N);
var messages = new Array(N);
var curtailments = new Array(N);
//populate above arrays with values then make a JSON call
$.getJSON('Home/AcknowledgeMany', {
assetid: assetids,
loggedBy: $("#UserName").text(),
faultTime: faultTimes,
message: messages,
curtailment: curtailments
}, function (result) {
alert(result);
}
The homecontroller has following action result
public string AcknowledgeMany(int[] assetId, string loggedBy, string[] faultTime, string[] message, string[] curtailment)
{
return("Acknowledged");
}
I receive null values for all the arrays when I make this call. Can someone help me passing arrays.
Try setting the traditional flag
For detail help see this question

Categories

Resources