Reputation: 1033
I try to make some abstract class for all my grid view controllers. Since all controllers will have the same GridViewPartial Action but with different parameters I decided to create struct ActionParams with Args property to keep all input parameters there. So here is my struct:
public struct ActionParams
{
public Dictionary<string, object> Args { get; set; }
}
And controller action
public ActionResult GridViewPartial(ActionParams input) { }
The problem is in JS onBeginCallback function. I tried to perform this task in 2 ways:
1)
function onBeginCallback(s, e)
{
e.customArgs["Args"]={"value1":1,"value2":2};
}
Instead of getting string key and int value, I got string key and string[] value. As I understand this is serialization problem.
2)
function onBeginCallback(s, e)
{
var editorsNames = {"value1":1 ),"value2":2}
e.customArgs["Args"] = $.toJSON(editorsNames);
}
In this way I got empty Args. But object is in Request.Params so I got in following way:
public ActionResult GridViewPartial(ActionParams input)
{
string jsonText = Request.Params["Args"];
if (string.IsNullOrEmpty(jsonText))
{ }
else
{
ActionParams data = new ActionParams>();
try
{
data.Args = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Dictionary<string,int>>(jsonText);
}
catch
{
ViewData["ErrorMessage"] = "Incorrect data";
}
}
}
Now I'm wondering if is possible to send this JSON object directly to input.Args like it was in case 1? ( for simple jquery ajax everything works fine).
Hope someone with great devexpress MVC control expressions will give me some good advice.
Upvotes: 2
Views: 886
Reputation: 24957
According to How to pass complex types to the server with a callback customArgs argument:
When you create an object and pass it to the
e.customArgs
argument, our code does not serialize the object to a string, and thus you do not get the client-side object on the server side correctly.
The first effort to reveal how raw JSON object passed to controller by using console.log(e.customArgs)
shows this object structure in console:
Object { Args: Object {"value1": 1, "value2": 2}}
When the input Args
parameter assigned as Dictionary<String, int>
, seems I was able to capture both keys and values in JSON object by this code:
public ActionResult GridViewPartial(Dictionary<String, int> Args)
{
// Args parameter contains 2 arrays with Count = 2
// Args.Keys contains "value1" and "value2"
// Args.Values contains 1 and 2
foreach (String key in Args.Keys)
{
// do something to pass keys
}
foreach (int value in Args.Values)
{
// do something to pass values
}
}
Result:
Variable: Args
Count: 2
Content:
0x0000 {["value1", 1]}
0x0001 {["value2", 2]}
However, when I changed the value part to Dictionary<String, Object>
, I found same thing as your problem: the Value
part changed to System.String[]
array which contains number 1 or 2 as string.
Variable: Args
Count: 2
Content:
0x0000 {["value1", System.String[]]} => Value: String[1] => 0x0000 = "1"
0x0001 {["value2", System.String[]]} => Value: String[1] => 0x0000 = "2"
Attempt to change input variable type into Dictionary<String, String>
returns this:
Variable: Args
Count: 2
Content:
0x0000 {["value1", "1"]}
0x0001 {["value2", "2"]}
The second case uses jQuery JSON plugin which converts the object given by editorsNames
to JSON-formatted string, then passed to response as a plain string which recognizable by deserializer on controller side. This approach fulfills how client-side objects should be passed to:
- A custom object should be serialized to a string;
- This string will be obtained on the server side using the
Request.Params
collection. If you deserialize the string, you will be able to create your custom object on the server side.
Hence, I concluded that you can pass raw JSON object by 2 ways:
By using customArgs
directly, you can declare a Dictionary
as input parameter and passing values using numeric value type or String
. Avoid using Object
type which seems creating array of string as value part.
By using Request.Params
, convert JSON object to encoded string and pass it into customArgs
, then use deserialization to reveal key and values.
NB: Instead of using a struct contains Dictionary as single input parameter, you can write several GridViewPartial
method overloads with different amount of input parameters to handle grid partial view.
Any suggestions or erratas welcome.
Additional reference:
How to pass complex objects to a callback Action as callback arguments
Upvotes: 1