Specifying multiple parameters of the same name using HTTPService - apache-flex

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?

Related

Moq - Using MockRepository.Verify() With Times

I'm looking to see if it's at all possible to specify a Times enum value in the setup of a mocked property that can then be exercised by the MockRepository.Verify() method at the Assert block of my AAA-style test. My current code reads like so:
// Arrange
var repository = new MockRepository(MockBehavior.Default);
var mockLogin = repository.Create<Login>();
mockLogin.SetupProperty(d => d.LoginID, 1515254);
var mockIApplicationEventLogService = repository.Create<IApplicationEventLogService>();
mockIApplicationEventLogService.Setup(d => d.InsertApplicationEventLog(It.IsAny<ApplicationEventLog>())).Verifiable();
var mockILoginResetFailedService = repository.Create<ILoginResetFailedService>();
mockILoginResetFailedService.Setup(d => d.GetLoginResetFailedByLoginID(It.IsAny<int>())).Returns((LoginResetFailed)null);
var mockApplicationEventLog = repository.Create<ApplicationEventLog>();
mockApplicationEventLog.SetupAllProperties();
var LoginWorkflowService = new LoginWorkflowService()
{
ApplicationEventLogService = mockIApplicationEventLogService.Object,
ApplicationEventLog = mockApplicationEventLog.Object,
LoginResetFailedService = mockILoginResetFailedService.Object
};
// Act
var result = LoginWorkflowService.CheckLoginResetFailuresLock(mockLogin.Object, It.IsAny<Guid>(), It.IsAny<SecurityPolicy_Aggregate>(), It.IsAny<string>(), It.IsAny<string>());
// Assert
result.Should().BeTrue();
mockIApplicationEventLogService.Verify(d => d.InsertApplicationEventLog(It.IsAny<ApplicationEventLog>()), Times.Never);
What I'd like to be able to do is call repository.Verify() at the end, but with my current code the Verify() call will expect InsertApplicationEventLog to have been called when in fact I expect it to never have been called. I have tried passing Times.Never into the Setup method for mockIApplicationEventLogService but it doesn't seem that there's a method override that takes it. Am I limited to individual Verify() calls if I have mocks in my repository that should never be called, or is there a way around this?
It appears as Nkosi said, it's not currently possible to do this. There is a request for this at the following URL:
https://github.com/moq/moq4/issues/373

Get List of Localized Items

I need to get the list of localized items of a publication programatically using coreservice in tridion. Could any one suggest me.
I would use the GetListXml method and specify a BluePrintChainFilterData filter object.
var subjectId = "[TCM Uri of your item]";
var filter = new BluePrintChainFilterData
{
Direction = BluePrintChainDirection.Down
};
var subjectBluePrintChainList = coreServiceClient.GetListXml(subjectId, filter);
You then still need to verify the localized items from the received list.
This wasn't in my original answer, and probably isn't complete because I don't take into account namespaces, but the following would work to select the localized (not shared) items.
var localizedItems = subjectBluePrintChainList.Elements("Item")
.Where(element => "false".Equals(element.Attribute("IsShared").Value, StringComparison.OrdinalIgnoreCase));
The only way I know is to use search functionality:
var searchQuery = new SearchQueryData();
searchQuery.BlueprintStatus = SearchBlueprintStatus.Localized;
searchQuery.FromRepository = new LinkToRepositoryData{IdRef = "tcm:0-5-1"};
var resultXml = ClientAdmin.GetSearchResultsXml(searchQuery);
var result = ClientAdmin.GetSearchResults(searchQuery);

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
}

how can i retrieve the variable i am getting through urlRequest in Flex

Hi I am sending userID through urlRequest like below code,
var urlStr:String = "http://[server]/main.jsp";
var urlReqest:URLRequest= new URLRequest(urlStr);
var variables:URLVariables = new URLVariables();
variables.userID = 12;
urlReqest.method = URLRequestMethod.POST;
urlReqest.data = variables;
navigateToURL(urlReqest,"_blank");
Now when new window is opening in that new swf is opening(new project) that is also in flex only. There I need to retrieve userID when initializing only. How can I retrieve?
If any one can help it would be helpful.
Thanks in advance.
In Flex 4 you can use
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty("userID"))
{
userID = FlexGlobals.topLevelApplication.parameters.userID;
}
In Flex 3 you can use
if (mx.core.Application.application.parameters.hasOwnProperty("userID"))
{
userID = mx.core.Application.application.parameters.userID;
}
You would have to rewrite the JSP page to write the POST values to the flashVars parameter. The POST variables are not accessible to the Flex app.
Once they are passed in through flashVars on the page, you would use Jason W's method for reading them:
if (mx.core.Application.application.parameters.hasOwnProperty("userID"))
{
userID = mx.core.Application.application.parameters.userID;
}

Resources