How to capture Result from InvokeAsync - asynchronous

I'm trying to make async call with WSDL that belongs to SIRI (SIRI
Service Interface for Real Time Information), How can I "catch" the response if I call "GetStopMonitoringServiceAsync" ?
Relevant part from the WSDL:
public void GetStopMonitoringServiceAsync(ServiceRequestStructure Request) {
this.GetStopMonitoringServiceAsync(Request, null);
}
/// <remarks/>
public void GetStopMonitoringServiceAsync(ServiceRequestStructure Request, object userState) {
if ((this.GetStopMonitoringServiceOperationCompleted == null)) {
this.GetStopMonitoringServiceOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetStopMonitoringServiceOperationCompleted);
}
this.InvokeAsync("GetStopMonitoringService", new object[] {
Request}, this.GetStopMonitoringServiceOperationCompleted, userState);
}
private void OnGetStopMonitoringServiceOperationCompleted(object arg) {
if ((this.GetStopMonitoringServiceCompleted != null)) {
System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
this.GetStopMonitoringServiceCompleted(this, new GetStopMonitoringServiceCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
}
}
/// <remarks/>
public new void CancelAsync(object userState) {
base.CancelAsync(userState);
}

Managed..
SS.GetStopMonitoringServiceCompleted += new GetStopMonitoringServiceCompletedEventHandler(GetStopMonitoringServiceCompletedEventHandler);
static void GetStopMonitoringServiceCompletedEventHandler(object sender, GetStopMonitoringServiceCompletedEventArgs e)
{
ServiceDeliveryStructure Response = new ServiceDeliveryStructure();
Response = e.Result;
}

Related

Pass JWT token as header in Xamarin WebView

I'm using Xamarin forms WebView control to display a page that uses Authentication JWT token. I could not find any samples that does this either in Microsoft site or any blogs.
Most closest answer I found is to create a renderer for the control in each platform (iOS and Droid). But I'm not sure on which event I should override the request and the format in which the auth header can be passed. Appreciate any help.
You could try the method below:
For Android:
public class FormsWebViewRenderer : ViewRenderer<Xamarin.Forms.WebView, Android.Webkit.WebView>
{
Android.Content.Context _localContext;
public FormsWebViewRenderer(Context context) : base(context)
{
_localContext = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
Dictionary<string, string> headers = new Dictionary<string, string>
{
["A-custom-header"] = "a custom value"
};
Android.Webkit.WebView webView = Control as Android.Webkit.WebView;
if (Control == null) {
webView = new Android.Webkit.WebView(_localContext);
SetNativeControl(webView);
}
webView.Settings.JavaScriptEnabled = true;
webView.Settings.BuiltInZoomControls = true;
webView.Settings.SetSupportZoom(true);
webView.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
webView.ScrollbarFadingEnabled = false;
webView.SetWebViewClient(new FormsWebViewClient(headers));
UrlWebViewSource source = Element.Source as UrlWebViewSource;
webView.LoadUrl(source.Url, headers);
}
}
public class FormsWebViewClient : Android.Webkit.WebViewClient
{
public Dictionary<string, string> headers { get; set; }
public FormsWebViewClient(Dictionary<string, string> requestHeaders)
{
headers = requestHeaders;
}
public override void OnPageStarted(Android.Webkit.WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
System.Diagnostics.Debug.WriteLine("Loading website...");
}
public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
base.OnPageFinished(view, url);
System.Diagnostics.Debug.WriteLine("Load finished.");
}
public override void OnReceivedError(Android.Webkit.WebView view, IWebResourceRequest request, WebResourceError error)
{
base.OnReceivedError(view, request, error);
}
}
For ios:
public class FormsWebViewRenderer : ViewRenderer<WebView, UIWebView>
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
var webView = Control as UIWebView;
if (webView == null) {
webView = new UIWebView();
SetNativeControl(webView);
}
webView.ScalesPageToFit = true;
webView.LoadStarted += (object sender, System.EventArgs evtArgs) => {
System.Diagnostics.Debug.WriteLine("Loading...");
};
webView.LoadFinished += (object sender, System.EventArgs evtArgs) => {
System.Diagnostics.Debug.WriteLine("Load finished.");
};
if (e.NewElement != null) {
UrlWebViewSource source = (Xamarin.Forms.UrlWebViewSource)Element.Source;
var webRequest = new NSMutableUrlRequest(new NSUrl(source.Url));
var headerKey = new NSString("A-custom-header");
var headerValue = new NSString("a custom value");
var dictionary = new NSDictionary(headerKey, headerValue);
webRequest.Headers = dictionary;
this.Control.LoadRequest(webRequest);
}
}
}

Multiple Query Params with Asyncronous Call Retrofit

UPDATE:
I have learned what I am looking to do is to use the Async within Retrofit with multiple queries too. I have updated my code, but I cannot get the async with the queries.
I am using Retrofit to make my data calls to a movie database and need to change the sort order depending on user settings. I am not clear how I could add this functionality to my interface.
sort_by=highest_rating.desc
or
sort_by=popularity.desc
Interface:
public interface MovieDatabaseApiCient {
#GET("/3/discover/movie")
void getData(#Query("api_key") String apiKey, #Query("sort_by") String sortByValue, Callback<MovieDbModel> response);
}
UPDATED API INTERFACE:
public interface MovieDatabaseApiCient {
#GET("/3/discover/movie?sort_by=popularity.desc&api_key=xxxxxxx")
void getMoviesByPopularityDesc(Callback<MovieDbModel> response);
#GET("/3/discover/movie?sort_by=vote_average_desc&api_key=xxxxxxxx")
void getMoviesByVotingDesc(Callback<MovieDbModel> response);
}
UPDATED DATA CALL THAT WORKS:
private void makeDataCall(String sortPreference) {
final RestAdapter restadapter = new RestAdapter.Builder().setEndpoint(ENDPOINT_URL).build();
MovieDatabaseApiCient apiLocation = restadapter.create(MovieDatabaseApiCient.class);
if (sortPreference.equals(this.getString(R.string.sort_order_popularity)) ){
apiLocation.getMoviesByPopularityDesc (new Callback<MovieDbModel>() {
#Override
public void success(MovieDbModel movieModels, Response response) {
movieDbResultsList = movieModels.getResults();
MoviesGridViewAdapter adapter = new MoviesGridViewAdapter(getApplicationContext(), R.layout.movie_gridview_item, movieDbResultsList);
gridView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
} else {
apiLocation.getMoviesByVotingDesc( new Callback<MovieDbModel>() {
#Override
public void success(MovieDbModel movieModels, Response response) {
movieDbResultsList = movieModels.getResults();
MoviesGridViewAdapter adapter = new MoviesGridViewAdapter(getApplicationContext(), R.layout.movie_gridview_item, movieDbResultsList);
gridView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
}
}
My call for the data:
private void makeDataCall (String apiKey, String sortPreference) {
final RestAdapter restadapter = new RestAdapter.Builder().setEndpoint(ENDPOINT_URL).build();
MovieDatabaseApiCient apiLocation = restadapter.create(MovieDatabaseApiCient.class);
apiLocation.getData(apiKey, sortPreference, new Callback<MovieDbModel>){
#Override
public void success(MovieDbModel movieModels, Response response) {
movieDbResultsList = movieModels.getResults();
MoviesGridViewAdapter adapter = new MoviesGridViewAdapter(getApplicationContext(), R.layout.movie_gridview_item, movieDbResultsList);
gridView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
Log.d("ERROR", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
}
I found a way to do Synchronously, but not asynchronously.
From your question and comment, IHMO, you should import retrofit.Callback; instead of import com.squareup.okhttp.Callback;
My code as the following has no compile error:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// creating a RestAdapter using the custom client
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL_BASE)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(mOkHttpClient))
.build();
WebService webService = restAdapter.create(WebService.class);
retrofit.Callback<GetRoleData> callback = new Callback<GetRoleData>() {
#Override
public void success(GetRoleData getRoleData, retrofit.client.Response response) {
}
#Override
public void failure(RetrofitError error) {
}
};
webService.getData("api_key", "sort_by", callback);
}
Interface:
public interface WebService {
#GET("/3/discover/movie")
void getData(#Query("api_key") String apiKey, #Query("sort_by") String sortByValue, Callback<GetRoleData> response);
}
So, please check your code again

Unit Testing Generic Handlers

How can i test return value of "ProcessRequest" method in a generic handler with unit Test?
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable
{
get
{
return false;
}
}
}
Instead of using mock, try to create test HttpContext with SimpleWorkerRequest like this:
SimpleWorkerRequest testRequest = new SimpleWorkerRequest("","","", null, new StringWriter());
HttpContext testContext = new HttpContext(testRequest);
HttpContext.Current = testContext;
Then you could create your handler and provide testContext to the ProcessRequest method:
var handler = new Handler1();
handler.ProcessRequest(testContext);
Then you could check HttpContext.Current.Response to make assertion about your test.
UPDATE:
I am attaching the full example of working unit-test(implementation of OutputFilterStream was taken from here):
[TestFixture]
[Category("Unit")]
public class WhenProcessingRequest
{
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable
{
get
{
return false;
}
}
}
public class OutputFilterStream : Stream
{
private readonly Stream InnerStream;
private readonly MemoryStream CopyStream;
public OutputFilterStream(Stream inner)
{
this.InnerStream = inner;
this.CopyStream = new MemoryStream();
}
public string ReadStream()
{
lock (this.InnerStream)
{
if (this.CopyStream.Length <= 0L ||
!this.CopyStream.CanRead ||
!this.CopyStream.CanSeek)
{
return String.Empty;
}
long pos = this.CopyStream.Position;
this.CopyStream.Position = 0L;
try
{
return new StreamReader(this.CopyStream).ReadToEnd();
}
finally
{
try
{
this.CopyStream.Position = pos;
}
catch { }
}
}
}
public override bool CanRead
{
get { return this.InnerStream.CanRead; }
}
public override bool CanSeek
{
get { return this.InnerStream.CanSeek; }
}
public override bool CanWrite
{
get { return this.InnerStream.CanWrite; }
}
public override void Flush()
{
this.InnerStream.Flush();
}
public override long Length
{
get { return this.InnerStream.Length; }
}
public override long Position
{
get { return this.InnerStream.Position; }
set { this.CopyStream.Position = this.InnerStream.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.InnerStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
this.CopyStream.Seek(offset, origin);
return this.InnerStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
this.CopyStream.SetLength(value);
this.InnerStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
this.CopyStream.Write(buffer, offset, count);
this.InnerStream.Write(buffer, offset, count);
}
}
[Test]
public void should_write_response()
{
//arrange
SimpleWorkerRequest testRequest = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext testContext = new HttpContext(testRequest);
testContext.Response.Filter = new OutputFilterStream(testContext.Response.Filter);
//act
var handler = new Handler1();
handler.ProcessRequest(testContext);
testContext.Response.End();//end request here(if it is not done in your Handler1)
//assert
var result = ((OutputFilterStream)testContext.Response.Filter).ReadStream();
Assert.AreEqual("Hello World", result);
}
}

Multicast networking app with Windows Phone 8 emulator

I'm implementing a multiplayer card game for windows phone 8 using multicast networking.
However, when I try to link a windows phone and the emulator nothing happens (no errors as well).
I can surf the web using internet explorer so my emulator is connected to the internet.
Do I have to make a special operation on the emulator in order to enable it to do multicast operations?
Or is there something missing in the code?
Here is the code:
Initialization
channel = new UdpChannel(IPAddress.Parse("224.109.108.106"), 3000);
this.channel.OnAfterOpened += new EventHandler<UdpPacketEventArgs>(channel_OnAfterOpen);
this.channel.OnPacketReceived += new EventHandler<UdpPacketEventArgs(Channel_PacketReceived);
this.channel.Open();
My multicast operating class:
public UdpChannel(IPAddress address, int port)
{
groupAddress = address;
localPort = port;
client = new UdpAnySourceMulticastClient(groupAddress, localPort);
}
public void Open()
{
if (!isJoined)
{
this.client.BeginJoinGroup(
result =>
{
try
{
this.client.EndJoinGroup(result);
isJoined = true;
this.AfterOpened();
this.Receive();
}
catch (Exception e)
{
throw e;
}
}, null);
}
}
private void AfterOpened()
{
EventHandler<UdpPacketEventArgs> handler = this.OnAfterOpened;
if (handler != null)
handler(this, new UdpPacketEventArgs(string.Empty, string.Empty));
}
private void Receive()
{
if (isJoined)
{
Array.Clear(this.buffer, 0, this.buffer.Length);
this.client.BeginReceiveFromGroup(this.buffer, 0, this.buffer.Length, result =>
{
if (!isDisposed)
{
IPEndPoint source;
try
{
this.client.EndReceiveFromGroup(result, out source);
this.AfterReceived(source, this.buffer);
this.Receive();
}
catch
{
isJoined = false;
this.Open();
}
}
}, null);
}
}
public void SendTo(int cardId)
{
byte[] data = Encoding.UTF8.GetBytes(cardId.ToString());
if (isJoined)
{
this.client.BeginSendToGroup(data, 0, data.Length,
result =>
{
this.client.EndSendToGroup(result);
}, null);
}
}
private void AfterReceived(IPEndPoint source, byte[] p)
{
EventHandler<UdpPacketEventArgs> handler = this.OnPacketReceived;
if (handler != null)
handler(this, new UdpPacketEventArgs(source.Address.ToString(), Encoding.UTF8.GetString(p, 0, p.Length)));
}
private void BeforeClose()
{
EventHandler<UdpPacketEventArgs> handler = this.OnBeforeClosing;
if (handler != null)
handler(this, new UdpPacketEventArgs(string.Empty, string.Empty));
}
#region IDisposable
public void Dispose()
{
if (!isDisposed)
{
Dispose(true);
GC.SuppressFinalize(this);
}
isDisposed = true;
}
~UdpChannel()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (disposing)
{
client.Dispose();
}
}
My events
public class UdpPacketEventArgs : EventArgs
{
public string Message { get; private set; }
public string Source { get; private set; }
public UdpPacketEventArgs(string source, string data)
{
this.Message = data;
this.Source = source;
}
}
My events handlers
private void Channel_PacketReceived(object sender, UdpPacketEventArgs e)
{
MessageBox.Show("Something Received");
}
private void channel_OnAfterOpen(object sender, UdpPacketEventArgs e)
{
this.Status.Text = "Connected";
}

Excpetion Handling with a NativeAcitivity

I'm using a NativeActivity with a child activity called Body and a ActivityAction called OnFault, this is my code:
[Designer(typeof(RetryDesigner))]
public sealed class Retry : NativeActivity {
public Activity Body { get; set; }
public ActivityAction<Exception> OnFault { get; set; }
protected override void CacheMetadata(NativeActivityMetadata metadata) {
metadata.AddChild(Body);
metadata.AddDelegate(OnFault);
base.CacheMetadata(metadata);
}
protected override void Execute(NativeActivityContext context) {
context.ScheduleActivity(Body, OnBodyCompleted, OnBodyFaulted);
}
void OnFaultCompleted(NativeActivityContext context, ActivityInstance instance) {
context.ScheduleActivity(Body);
}
void OnBodyCompleted(NativeActivityContext context, ActivityInstance instance) {
}
void OnBodyFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom) {
faultContext.HandleFault();
if (OnFault != null) {
faultContext.ScheduleAction<Exception>(OnFault, propagatedException, OnFaultCompleted);
}
}
}
and my main looks like this:
static void Main(string[] args) {
Variable<Exception> ex = new Variable<Exception>();
DelegateInArgument<Exception> exception = new DelegateInArgument<Exception>();
Retry retry = new Retry {
Body = new Sequence {
Variables = { ex },
Activities = {
new Assign<Exception> {
To = new OutArgument<Exception>(ex),
Value = new InArgument<Exception>((env) => new Exception("test"))
},
new Throw {
Exception = ex
}
}
},
OnFault = new ActivityAction<Exception> {
Argument = exception,
Handler = new Sequence {
Activities = {
new WriteLine{
Text = new InArgument<string>(env =>
exception.Get(env).Message)
}
}
}
}
};
var workflow = new WorkflowInvoker(retry);
workflow.Invoke();
Console.WriteLine();
}
The problem is that the exception don't stop in the OnBodyFaulted callback and appear on the main as an unhedled expetion.
How can I stop the Exception inside the OnBodyFault callback, is there any state or property on the workflow to do that?
The problem is that in the OnFaultCompleted() you are calling context.ScheduleActivity(Body) again. This time without a fault handler so that causes the same fault to occur again and the complete workflow to fault.

Resources