Firstly, I apologise in advance for any incorrect terminology! I've gone snow blind reading so many blog posts and articles on how I might do this and have come to an impasse.
I've been successfully passing parameters via AJAX to an MVC action in a controller, which returns the SQL datatable in JSON format for me to consume in my page. An example set of parameters I send looks like this;
var parameters = {
pSQL: "SELECT * FROM v_MyTable",
pSQLServer: "SERVER01",
};
My Client Side Script looks like this;
$.ajax({
type: 'POST',
url: '/ControllerName/GiveMeJSON',
data: JSON.stringify(parameters),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
...
});
My Controller Action simply works like this;
public string GiveMeJSON(string pSQL, string pSQLServer)
{
var SQL = pSQL
var SQLSERVER = pSQLServer
// do stuff and return JSON
}
This has been working great for me. I send JSON request data as POST and receive JSON data in return. Brilliant.
Now, I'd like to extend the functionality of my action so that I can pass it an additional set of variables as an array, something like this;
var parameters = {
pSQL: "SELECT * FROM v_MyTable",
pSQLServer: "SERVER01",
pMoreParams: {
pParameter1: "ABC",
pParameter2: "XYZ",
}
};
...where the parameter names in MoreParams could be called anything, with any type of value. That's important, as I think that rules out using models?
This results in the POST request BODY looking like this Valid JSON;
{"pSQL":"SELECT * FROM v_MyTable","pSQLSERVER":"SERVER01","pMoreParams":{"pParameter1":"ABC","pParameter2":"XYZ"}}
So the data I need is clearly going to the server, but yet I am really struggling with enumerating/accessing those additional items in the pMoreParams array. I seem to be getting close, I've played around with using...
public string GiveMeJSON(string pSQL, string pSQLServer, List<string> pMoreParams)
...and I've had a foreach loop in the controller run for however many items are in the pMoreParams list (2, in the above example) but just can't seem to work out how to access/read those values in that list in the controller action.
I'm at a loss now as to how to loop through and read the extra data I am sending. I sense I'm close, with using the List<string>
or IEnumerable
- but the solution evades me.
I have had more success getting the controller reading those extra parameters when I send them as a simple valid JSON string, like so;
var parameters = {
pSQL: "SELECT * FROM v_MyTable",
pSQLServer: "SERVER01",
pMoreParams: '[{"name": "pParameter1", "value": "ABC" },{"name": "pParameter2", "value": "XYZ"}]'
};
...and using a controller actions which look something like this;
public class SQLParam
{
public string name { get; set; }
public string value { get; set; }
}
if (string.IsNullOrEmpty(pMoreParams) == false)
{
var sqlparameters = JsonConvert.DeserializeObject<SQLParam[]>(pMoreParams);
foreach (var sqlparameter in sqlparameters)
{
Debug.WriteLine(sqlparameter.name, sqlparameter.value);
}
};
...BUT I then lose the ability to easily read and modify those values in client-side jquery/javascript, and I'd MUCH prefer/desire to keep the way I define the parameters as it is, so that I can easily read and modify the values using a one-liner, something like;
parameters.pMoreParams[0].pParameter1 = "NEW VALUE";
...as I can then simply trigger the AJAX call again and it POSTS with the new parameter values.
Any help and advice is much appreciated, thanks!
When you send in:
"pMoreParams":{"pParameter1":"ABC","pParameter2":"XYZ"}
You are sending in an object called pMoreParams
that has two properties.
If you want to get these from the controller, you would need to create a C# object which mirrors the JSON you are sending in.
public class MoreParams
{
public string pParameter1 {get;set;}
public string pParameter2 {get;set;}
}
And then update your action method:
public string GiveMeJSON(string pSQL, string pSQLServer, MoreParams pMoreParams)
{
var param1 = pMoreParams.pParameter1;
var param2 = pMoreParams.pParameter2;
}
SIDE NOTE
You are sending in SQL for the the server to execute. I know it is convinient, but this is a HUGE security issue that will lead to SQL Injections that will allow an attacker to control your SQL server.
OK, after a good sleep, I think I have come up with a solution which meets my requirements to not have to define all my possible and future parameters in a class and also satisfies some of the SQL injection concerns, having read up on using parameterisation;
Here's the data I JSON.stringify and pass via AJAX to the controller;
var chart01Params = {
pSQLCon: "ConnectionString",
pSQL: "MySQLFile.sql", // accessible only by the server from MapPath
pMoreParams :
[
{
"name" : "pParameterXYZ",
"value": "12345ABC"
},
],
};
...which looks like this in POST request body;
{"pSQLCon":"ConnectionString","pSQL":"MySQLFile.sql","pMoreParams":[{"name":"pParameterXYZ","value":"12345ABC"}]}
Here's my class;
public class SQLParam
{
public string name { get; set; }
public string value { get; set; }
}
Here's my controller head;
public string GETMYJSON(string pSQLCon, string pSQL, List<SQLParam> pMoreParams)
...before my controller executes the SQL command it will add any parameters and values to the SQL query, which I hope will make it more secure from SQL Injection attack;
foreach (SQLParam parameter in pMoreParams)
{
cmd.Parameters.Add(parameter.name, SqlDbType.Char);
cmd.Parameters[parameter.name].Value = parameter.value;
}
And it works great! If I want to send up parameters that a query expects, I can do so without having to include them in a class and I can also, still, use local client-side scripting to take choices/input from the DOM and set parameter values as long as I know the Index in the object of the parameter value I want to change.
Thanks for reading! Before you down-vote someones question, please keep in mind that not everyone is a coding expert who is fully language articulate and has read every book, blog and MSDN article in existence before coming here for help - sometimes all they just came here for what little clarity anyone can offer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.