JavaScriptSerializer to serialize a javascript function name - asp.net

I am using Flexigrid in my project to add a button on the grid toolbar I can use code like this:
...
"buttons":[
{"name":"Modifica","bclass":"edit","onpress":"doCommand"},
{"name":"Elimina","bclass":"delete","onpress":"doCommand"}
],
...
Anyway the "onpress" attribute shall contain a reference to a js callback and so this field shall not be enclosed within quotation marks.
I am using the class JavaScriptSerializer (in the System.Web.Script.Serialization namespace) to do the serialization.
How I have to declare the variable to make JavaScriptSerializer serialize like this?
...
"buttons":[
{"name":"Modifica","bclass":"edit","onpress":doCommand},
{"name":"Elimina","bclass":"delete","onpress":doCommand}
],
...
Thanks for helping!

How about this trick ?
var param = new Dictionary<string,string>();
param["onpress"] = "%doCommand%";
return new JavaScriptSerializer().Serialize( param ).Replace( "\"%", "" ).Replace( "%\"", "" );

To the best of my knowledge, there is not a native way to do this with the .NET serializer, but you could execute the following code on the client-side to turn the onpress JSON string into a callback...
var buttons = []; // Your JSON array
for(var i = 0; i < buttons.length; i++) {
var b = buttons[i];
b.onpress = window[b.onpress];
}

JavaScriptSerializer is meant for serializing to JSON, and JSON can not represent functions; it also can't refer to previously defined variables. So I don't believe this is possible.

You can store the function name as a string
...
"buttons":[
{"name":"Modifica","bclass":"edit","onpress":"doCommand"},
{"name":"Elimina","bclass":"delete","onpress":"doCommand"}
],
...

Related

Json format of data which is having HTML tags in Web API in C#

I have an object Example
Class Event
{
string country{get;set}
}
Events test = new Evnts();
test.country="<P>India<P>"
How i need to Json format for the above.
I used the method
System.Web.Script.Serialization.JavaScriptSerializer oSerializer = new
System.Web.Script.Serialization.JavaScriptSerializer();
StringContent sc = new StringContent(oSerializer.Serialize(list));
sc.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return sc;
But this is giving output result as "City": "\u003cp\u003eIndia\u003cp\u003e",
Please comment on this .
Thank you
That's encoded <> tag representation. You shouldn't return specific html element in JSON response. Also, no need to use JavaScriptSerializer class. You can simply return your "Event" class as a result of your svc web api service.
Actually I am fetching Rich text from Sitecore Item,
I used Regex to remove the HTML tags and Replace Method to replace the "’" and Replace(" ",""). I am directly sending the List of events not using JavaScriptSerializer class.
((Regex.Replace(eve["text"].ToString(), "<[^>]*>", "").Replace("’", "'")).Replace(" ","")).Replace("\n","");
Thank you Pravin and Ivan Sivak

changing the Request.QueryString value

how can i modified the querystring?
I have capture the query string like this
qs = Request.QueryString["flag"].ToString();
and then rebuilt the query string with modified values
and response.redirect(url & qs) to it
While I'm not sure I'd suggest using this approach liberally, if you wanted to reconstruct the path and query string with a few changes... you could convert the query string to an editable collection, modify it, then rebuild it from your new collection.
Goofy example...
// create dictionary (editable collection) of querystring
var qs = Request.QueryString.AllKeys
.ToDictionary(k => k, k => Request.QueryString[k]);
// modify querystring
qs["flag"] = "2";
// rebuild querystring
var redir = string.Format("{0}{1}", Request.Path,
qs.Aggregate(new StringBuilder(),
(sb, arg) => sb.AppendFormat("{0}{1}={2}",
sb.Length > 0 ? "&" : "?", arg.Key, arg.Value)));
// do something with it
Response.Redirect(redir);
While I definitely wouldn't recommend the below for production code, for testing purposes you can use reflection to make the querystring collection editable.
// Get the protected "IsReadOnly" property of the collection
System.Reflection.PropertyInfo prop = Request.QueryString.GetType()
.GetProperty("IsReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
// Set the property false (writable)
prop.SetValue(Request.QueryString, false, null);
// Have your way with it.
Request.QueryString.Add("flag", "2");
To combine the required destination URL based on the Request’s properties, use something like this:
string destUrl = string.Format("{0}://{1}{2}/", Request.Url.Scheme, Request.Url.Authority, Request.Url.AbsolutePath);
if (destUrl.EndsWith("/"))
destUrl = destUrl.TrimEnd(new char[] { '/' });
if (!string.IsNullOrEmpty(Request.QueryString["paramName"])) {
destUrl = string.Format("{0}?paramName={1}", destUrl, "paramValueHere");
Response.Redirect(destUrl);
}
i am not sure if I understand your question. You can just alter the string qs and use.
qs = qs + "modification"
Response.Redirect("this.aspx?flag=" + qs )
The stuff in the Request class deals with the request that got you to the page. You can't edit it because the client constructed it, not the server.

Combine/merge Dynamic Objects in AS3

I have 2 dynamic objects and I want to build one to contain all the properties:
var o1:Object = {prop1:val1,prop2:val2,prop3:val3};
var o2:Object = {prop3:val3a,prop4:val4};
and I need to obtain a third object that looks like that:
{prop1:val1, prop2:val2, prop3:val3a, prop4:val4};
Basically I need a way to iterate through the object properties and to add new properties to the third object. I have to mention I'm quite new to AS3/Flash/Flex.
First question, do you really mean to have prop3 in both objects? you will need to decide what to do in case of a collision like that, which object has precedence.
Secondly, check out the introspection apis: http://livedocs.adobe.com/flex/3/html/help.html?content=usingas_8.html
something like this should work:
public function mergeDynamicObjects ( objectA:Object, objectB:Object ) : Object
{
var objectC:Object = new Object();
var p:String;
for (p in objectA) {
objectC[p] = objectA[p];
}
for (p in objectB) {
objectC[p] = objectB[p];
}
return objectC;
}
If the property exists in A and B, B's will overwrite A's. Also note that if the values of a property is an object, it will pass a reference, not a copy of the value. You might need to clone the object in those cases, depending on your needs.
Note: I haven't actually tested the above, but it should be close. Let me know if it doesn't work.
Updated to fix the errors. Glad it works for you though.
You can dynamically access/set properties on objects with the index operator. The for loop will itterate over the property names, so if you put it all together, the following test passes:
[Test]
public function merge_objects():void {
var o1:Object = {prop1:"one", prop2:"two", prop3:"three"};
var o2:Object = {prop3:"threeA", prop4:"four"};
var o3:Object = new Object();
for (var prop in o1) o3[prop] = o1[prop];
for (var prop in o2) o3[prop] = o2[prop];
assertThat(o3.prop1, equalTo("one"));
assertThat(o3.prop2, equalTo("two"));
assertThat(o3.prop3, equalTo("threeA"));
assertThat(o3.prop4, equalTo("four"));
}
you can iterate over the object properties like:
var obj1:Object = new Object();
for(var str:String in obj2){
obj1[str] = "any value"; // insert the property from obj2 to obj1
}

Change Single URL query string value

I have an ASP.NET page which takes a number of parameters in the query string:
search.aspx?q=123&source=WebSearch
This would display the first page of search results. Now within the rendering of that page, I want to display a set of links that allow the user to jump to different pages within the search results. I can do this simply by append &page=1 or &page=2 etc.
Where it gets complicated is that I want to preserve the input query string from the original page for every parameter except the one that I'm trying to change. There may be other parameters in the url used by other components and the value I'm trying to replace may or may not already be defined:
search.aspx?q=123&source=WebSearch&page=1&Theme=Blue
In this case to generate a link to the next page of results, I want to change page=1 to page=2 while leaving the rest of the query string unchanged.
Is there a builtin way to do this, or do I need to do all of the string parsing/recombining manually?
You can't modify the QueryString directly as it is readonly. You will need to get the values, modify them, then put them back together. Try this:
var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
nameValues.Set("page", "2");
string url = Request.Url.AbsolutePath;
string updatedQueryString = "?" + nameValues.ToString();
Response.Redirect(url + updatedQueryString);
The ParseQueryString method returns a NameValueCollection (actually it really returns a HttpValueCollection which encodes the results, as I mention in an answer to another question). You can then use the Set method to update a value. You can also use the Add method to add a new one, or Remove to remove a value. Finally, calling ToString() on the name NameValueCollection returns the name value pairs in a name1=value1&name2=value2 querystring ready format. Once you have that append it to the URL and redirect.
Alternately, you can add a new key, or modify an existing one, using the indexer:
nameValues["temp"] = "hello!"; // add "temp" if it didn't exist
nameValues["temp"] = "hello, world!"; // overwrite "temp"
nameValues.Remove("temp"); // can't remove via indexer
You may need to add a using System.Collections.Specialized; to make use of the NameValueCollection class.
You can do this without all the overhead of redirection (which is not inconsiderable). My personal preference is to work with a NameValueCollection which a querystring really is, but using reflection:
// reflect to readonly property
PropertyInfo isReadOnly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
// make collection editable
isReadOnly.SetValue(this.Request.QueryString, false, null);
// remove
this.Request.QueryString.Remove("foo");
// modify
this.Request.QueryString.Set("bar", "123");
// make collection readonly again
isReadOnly.SetValue(this.Request.QueryString, true, null);
Using this QueryStringBuilder helper class, you can grab the current QueryString and call the Add method to change an existing key/value pair...
//before: "?id=123&page=1&sessionId=ABC"
string newQueryString = QueryString.Current.Add("page", "2");
//after: "?id=123&page=2&sessionId=ABC"
Use the URIBuilder Specifically the link textQuery property
I believe that does what you need.
This is pretty arbitrary, in .NET Core at least. And it all boils down to asp-all-route-data
Consider the following trivial example (taken from the "paginator" view model I use in virtually every project):
public class SomeViewModel
{
public Dictionary<string, string> NextPageLink(IQueryCollection query)
{
/*
* NOTE: how you derive the "2" is fully up to you
*/
return ParseQueryCollection(query, "page", "2");
}
Dictionary<string, string> ParseQueryCollection(IQueryCollection query, string replacementKey, string replacementValue)
{
var dict = new Dictionary<string, string>()
{
{ replacementKey, replacementValue }
};
foreach (var q in query)
{
if (!string.Equals(q.Key, replacementKey, StringComparison.OrdinalIgnoreCase))
{
dict.Add(q.Key, q.Value);
}
}
return dict;
}
}
Then to use in your view, simply pass the method the current request query collection from Context.Request:
<a asp-all-route-data="#Model.NextPageLink(Context.Request.Query)">Next</a>

Specifying multiple parameters of the same name using HTTPService

Ruby on Rails controllers will automatically convert parameters to an array if they have a specific format, like so:
http://foo.com?x[]=1&x[]=5&x[]=bar
This would get converted into the following array:
['1','5','bar']
Is there any way I can do this with an ActionScript 3 HTTPService object, by using the request parameter? For example, It would be nice to do something like the following:
var s:HTTPService = new HTTPService();
s.request['x[]'] = 1;
s.request['x[]'] = 5;
s.request['x[]'] = 'bar';
However, that will simply overwrite each value, resulting in only the last value being sent. Anyone have a better idea? I know I could just append stuff to the query string, but I'd like to do it in the POST body.
I was working on this same problem as well. Fortunatly, Flex supports this out of the box.
Just use an Array for the field value:
var service:HTTPService = new HTTPService();
service.useProxy = true;
service.destination = "myservicet";
service.resultFormat = HTTPService.RESULT_FORMAT_XML;
var fields:Array = ["categories", "organisation"];
var params:Object = new Object();
params.q = "stackoverflow";
params.rows = 0;
params.facet = "true";
params["facet.field"] = fields;
service.send(params);
The HTTPService will convert this t0 the url parameters:
facet=true&q=stackoverflow&facet%2Efield=categories&facet%2Efield=organisation&rows=0
Hope this helps!
Added for more clarity. When there is only 1 argument in the array, do not pass the fields as an array. For some reason, flex will not send this to the http service
I usually do something like this...
var s:HTTPService = new HTTPService();
s.url = "http://foo.com";
s.method = "post";
// add listeners...
s.addEventListenser(ResultEvent.RESULT,function(event:ResultEvent){
mx.controls.Alert.show(event.result.toString());
});
// send the data...
s.send({
a: 1,
b: 5,
c: "bar"
});
which would result in the HTTP Get / POST of:
http://foo.com?a=1&b=5&c=bar
You could also just create an associative array and pass it to the HTTPService send method, that would be something like:
var postdata:Object = {};
postdata["a"] = 1;
postdata["b"] = 5;
postdata["c"] = "bar";
// s is the HTTPService from above...
s.send(postdata);
You mentioned that All POST parameters must have the same name.
Elements that have the same name will overwrite each other in an associative array.
However, I have dealt with calendar cells before, and all 31 cells belong to the Date category.
What I did was:
var params:Object = new Object;
for (var i:uint=0; i<31; i++){
params["Date"+(jj.toString())] = date[i];
}
HTTPService....etc.
HTTPService.send(params);
So, on the POST receiving side, it would be interpreted as Date0...Date31.
Don't know if this was what you wanted, and the post was so long ago.
Come to think about it.
Why don't you do an array push of all of the elements under the same index name?
However, this means you are sending an array to the receiving side.
If you are POST-ing this, how will this be URL-referenced?

Resources