ASMX Service and Lack of Crossdomain.xml file - apache-flex

I have an issue with an asmx service I am trying to access. No crossdomain file. I read there is a way around this using HTTPService instead of a webservice. Still cannot load the wsdl. See code below. Any help would be greatly appreciated:
var dataService:HTTPService = new HTTPService();
dataService.url =
"http://flexmappers.com/proxy.php?url=http://www.server.net/carbon.asmx";
dataService.method = "POST";
dataService.addEventListener("result", onCarbonCalcResult);
dataService.addEventListener("fault", onCarbonCalcFault);
//dataService.resultFormat = "xml"
var params:Object = new Object();
params["call"] = "getCarbon";
params.area = carbonarea;
params.geojson = geojson;
dataService.send(params);

No crossdomain file. I read there is a
way around this using HTTPService
instead of a webservice
It sounds like you were misinformed.
In browser based applications, neither HTTPService, WebService, and RemoteObject tags are not allowed to access content on a remote server unless a crossdomain.xml file exists allowing such access. They can all access content on the same domain as the SWF without a crossdomain.xml file in place.
To get around this, you can use an HTTP Proxy on the same server that serves your SWF. You could also use an AIR app which does not run in a browser, and therefore exists in a different security sandbox.

You can create your own proxy with BlazeDS or Apache HTTP.

Related

Upload large file to Cloud Service in Web Api

After read below posts.
How to increase the temp folder size of web role.
Too small temp folder size of web role.
I understood there is a limitation for uploading large file to cloud service. And seems like windows azure doesn't allocate large size of space for web role by default.
So I was trying to find a way to break it. One of the ways I have been testing successfully is grasp the stream of post request and read it through block by block without reading it from the temp folder. Below is what I done. please review it .
CloudBlobClient blobClient = CreateBlobClient(account);
BlobRequestOptions options = CreateBlobRequestOpt();
CloudBlobContainer container = blobClient.GetContainerReference(sContainerName);
bool b = container.CreateIfNotExist();
CloudBlob blob = container.GetBlobReference(sBlobName);
blob.UploadFromStream(postFileStream, options);
I just passed the postFileStream which I got from Request.Files[0].InputStream in the controller of Asp.net MVC to the CloudBlobClient. and the CloudBlobClient which from Azure Storage Library SDK will read the stream block by block. In this way this will support the large file post. In my test. Even the 2GB file can works fine.
But I also want to make it work in the Asp.net Web Api. and I found the Request in Api controller is System.Net.Http.HttpRequestMessage. It is different from the one in MVC controller named with System.Web.HttpRequestBase. So How can I get the post request file stream in Web Api Controller like in the MVC controller? thanks.
You can get file content(s) using Request.Content.ReadAsMultipartAsync() method.
You can try something like this:
IEnumerable<HttpContent> contents = Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).Result.Contents;
foreach (var content in contents)
{
//...
//create your blob object...
//...
blob.UploadFromStream(content.ReadAsStreamAsync().Result);
}

Invoking HTTPS webservice from flex

I have an https .net webservice. Invoking web methods using tools like soap UI works fine. I am unable to invoke the webmethod from flex. My WSDL loads up fine in flex.
On deployment my flex application and the webservice are on the same server. When use the machine url and access from within the server it works fine, but not when I use the https url for the flex application.
Eg - http://machinename/flex/flexApp.html works fine with https://publicname/wservice/ws.asmx but https://publicname/flex/flexapp.html fails to work.
I have the crossdomain policy in place with full access and also I have a valid SSL certificate on the server.
When I make the call from my local machine in debug mode I see the following in Fiddler-
The WSDL call goes fine and returns back correctly and the Protocol is shown as HTTPS where as the webmethod call following it shows the protocol as HTTP and returns back with the error -
I have been stuck on this for quite some time. Any help is greatly appreciated.
Thanks,
Nikhil.
Here is my Flex code that calls it:
//business delegate
public function BusinessDelegate(responder : IResponder):void
{
_responder = responder;
_service = ServiceLocator.getInstance().getService("sqlWebService");
_service.loadWSDL();
}
//Login User
public function Login(userId:String,password:String):void
{
var asyncToken:AsyncToken = _service.LoginUser(userId,password);
asyncToken.addResponder(_responder);
}
and the service locator has the following tag where I set the URL from outside as https://....
<mx:WebService
id="sqlWebService"
useProxy="false"
concurrency="multiple"
showBusyCursor="true"
wsdl="{Url}"/>
I finally was able to resolve this problem by replacing the code where I call the Flex WebService object with the specific generated classes for the webservice.
I generated classes for the webservice using Import WebService(WSDL) and was setting the url on the main class on run time as https://.....
and it works like a charm...and I see that in fiddler it shows me correctly going out as HTTPS instead of the HTTP.
Here is what helped me -
http://livedocs.adobe.com/flex/3/html/help.html?content=security2_15.html
Comment by nated.
Thanks Flextras.com for pointing me to right direction.
Resolved.
If using WCF service and WebService in Flex, use
service.svc?wsdl for HTTP and
service.svc/wsdl?wsdl for HTTPS,

RemoteObjecting to BlazeDS in Flex

I have a blazeds amf url, which is https://..../afm/MessageBrok. Actually im not sure if it's what is referred to as the amf gateway or what. But basically, how do I do a remoteobject call to a blazeds location, for a service/destination and then use it like a web service, without having to set an xml file or anything on the flex side. The BlazeDS side is working fine, but basically, I need to know the code in the mxml file i need to use to get to that...
a) Create your remote object (you can do it from mxml or as):
<mx:RemoteObject id="remoteObject" destination="campaignRemoteServices">
<mx:method name="method1" result="createResult1(event)" fault="createFault1(event)"/>
<mx:method name="method2" result="createResult2(event)" fault="createFault2(event)"/>
<mx:.......
</mx:RemoteObject>
Before doing that you need to know the destination name and the exposed methods.
b) Configure the channels for your remote object:
var channelSet:ChannelSet = new ChannelSet();
var channel:AMFChannel = new AMFChannel("amf", "blazeds amf endpoint , for example http://localhost:8080/myapp/messagebroker/amf");
channelSet.addChannel(channel);
remoteObject.channelSet = channelSet;
c)Invoke the methods:
remoteObject.method1("test");

Posting base64 encoded files to an asp.net 1.1 page

We are making an automated patching application and would like to post files on production server through asp.net page (or maybe a web service), since we can only access production server via http. The page should accept files and store them to appropriate location. The path to files will be declared in external XML file.
So, is it possible posting a base64 encoded files within body tag and HOW? maybe even any better approach?
If you plan to use Base64 encoding.
Take a look at
System.Convert.ToBase64String()
System.Convert.FromBase64String()
System.Convert.ToBase64CharArray()
System.Convert.FromBase64CharArray()
See Using XML CDATA nodes to send files via a Web Service
why not create a webservice which accepts an object like:
class postfile
{
public byte[] fileByte;
public string fileName;
}
Then add a web reference in your client app.
.net will serialize the object for you.
You will need to secure this using wse security and might require the service use impersonation to write the file on the server.

How to set an HTTP header while using a Flex RemoteObject method?

I am running blazeds on the server side. I would like to filter http requests using an http header. My goal is to send extra parameters to the server without changing the signatures of my blazeds services.
On the client side, I am using Flex RemoteObject methods.
With Flex WebService components, it is possible to set an http header using the property httpHeaders. I have not found anything similar on the RemoteObject class...
I couldnt modify http request from flex, instead I can add custom headers to the mx.messaging.messages.IMessage that RemoteObject sends to the server and there, extending flex.messaging.services.remoting.adapters.JavaAdapter (used for accessing Spring beans), it's posible to read the header parameters and put them into the HTTPRequest.
In the flex part, I had to extend mx.rpc.AsyncRequest:
declares a new property "header" and overwrites invoke method that checks if there is a not null value for set the msg.headers.
and mx.rpc.remoting.mxml.RemoteObject:
the constructor creates a new instance of our custom AsyncRequest and overwrite old AsyncRequest and it defines a setHeaders method that set the argument to the custom AsyncRequest.
com.asfusion.mate.actions.builders.RemoteObjectInvoker (extra :P):
this one reads the param declared in the Mate's map RemoteObjectInvoker and puts in the RemoteObject header.
I hope it will be understandable (with my apache english xDDD)
Bye. Agur!
This worked for me using BlazeDS and Spring-Flex 1.5.2
Flex:
use namespace mx_internal;
var service:RemoteObject = new RemoteObject(destination);
var operation:Operation = service[functionName];
operation.asyncRequest.defaultHeaders = {company:'company'};
var token:AsyncToken = operation.send();
Java Spring-Flex:
public class FlexJavaCustomAdapter extends JavaAdapter{
#Override
public Object invoke(Message message) {
String locale = (String) message.getHeader("com.foo.locale");
return super.invoke(message);
}
}
dispatcher-servlet.xml
<bean id="customAdapter" class="org.springframework.flex.core.ManageableComponentFactoryBean">
<constructor-arg value="com.codefish.model.flex.FlexJavaCustomAdapter"/>
</bean>
<flex:message-broker id="_messageBroker" services-config-path="classpath*:/com/codefish/resources/spring/services-config.xml" >
<flex:remoting-service default-adapter-id="customAdapter"
default-channels="my-amf, my-secure-amf" />
</flex:message-broker>
</bean>
RemoteObject uses AMF as the data channel, and is managed in a completely different way than HttpService or WebService (which use Http).
What you can do, is call setCredentials(username,password) and then capture this on the server side using the FlexLoginCommand (either the standard one for your container, or derive your own).
Lookup setCredentials and how you should handle this on both sides (client and server).
I have similar problem, and I afraid there is no simple way to set HTTP header when using AMF. But I've designed following solution.
Flex uses HTTP to transfer AMF, but invokes it through browser interfaces, this allows you to set cookie. Just in document containing application invoke following JavaScript
document.cookie="clientVersion=1.0;expires=2100-01-01;path=/";
Browser should transfer it to server, and you can filter (problem will be if the user will have cookies turned off).
Much more you can invoke JavaScript functions from Flex (more is here: http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_4.html).
You might be trying to re-invent the wheel. Is there a reason you can't use the standard HTTP(s) authentication?
A reason I was thinking too to use http headers was for the server to be able to 'recognize' the flex client in the a context of service versionning.
On the server I can always build an indirection/proxy that would allow the different clients to only use 1 end point and route to the right adapter depending on the client version.
The question is on the client side. How would the server identify the flex client token or 'version'. One way is certainly via authentication. But, assuming there is not authentication involved?
We recently run into the same issue and this is how we added our custom headers without creating a subclass:
var operation:AbstractOperation = _remoteSession.getOperation('myRemoteOperation');
var async:AsyncRequest = operation.mx_internal::asyncRequest;
async.defaultHeaders = {my_header:'my_value'};
The AsyncRequest object is actually accessible via the operation object via the mx_internal namespace.
You can debug the $GLOBALS in PHP to see that.
I think this is in the
$GLOBALS['HTTP_RAW_POST_DATA'];
or you can simple do
file_get_contents('php://input');

Resources