Converting WKNavigationResponse decisionHandler Objective-C to Xamarin C# - xamarin.ios

I need help in converting the following into C#. I have tried several ways but keep failing. I would like to use the following method to get the response cookies for authentication purposes.
(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
decisionHandler(WKNavigationResponsePolicyAllow);
}

Ok, ended up just figuring it out myself, wasnt too bad.
[Foundation.Export("webView:decidePolicyForNavigationResponse:decisionHandler:")]
public virtual void DecidePolicy(WKWebView webView, WKNavigationResponse navigationResponse, Action<WKNavigationResponsePolicy> decisionHandler)
{
NSHttpUrlResponse response;
NSHttpCookie[] cookies_holder;
response = (NSHttpUrlResponse)navigationResponse.Response;
cookies_holder = NSHttpCookie.CookiesWithResponseHeaderFields(response.AllHeaderFields, response.Url);
foreach (var cookie in cookies_holder)
{
NSHttpCookieStorage.SharedStorage.SetCookie(cookie);
}
decisionHandler(WKNavigationResponsePolicy.Allow);
}

Related

Could I Intercept Exit FullScreen event from octane.xam.VideoPlayer plugin (XAMARIN FORMS)?

My application works portait, ma i want fullscreen video playback even in landscape mode using the plugin mentionend above.
For this purpose I create a customrenderer to take access to native AVPlayerViewController Ios Control.
I tried in many many ways, but seems to be impossible to handle exit fullscreen event. In that method i want to force layout portrait. I have the code for reset orientation already implemented but the problem is to put the code in the right place.
Any other that faced the same issue??
I tried to search for something useful in AVPlayerView(not accessible), AVPlayerVideoController, AVPlayerCurrentItem etc
Any ideas?
Thanks you in advance.
I have translated the OC code to C# in this link for you, see the following codes:
using Foundation;
using CoreGraphics;
playerViewController = new AVPlayerViewController();
playerViewController.ContentOverlayView.AddObserver(this, new NSString("bounds"), NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old , IntPtr.Zero);
public override void ObserveValue(NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
{
base.ObserveValue(keyPath, ofObject, change, context);
if(ofObject == playerViewController.ContentOverlayView)
{
if(keyPath == "bounds")
{
NSValue oldRect = change.ValueForKey(new NSString("NSKeyValueChangeOldKey")) as NSValue;
NSValue newRect = change.ValueForKey(new NSString("NSKeyValueChangeNewKey")) as NSValue;
CGRect oldBounds = oldRect.CGRectValue;
CGRect newBounds = newRect.CGRectValue;
bool wasFullscreen = CGRect.Equals(oldBounds, UIScreen.MainScreen.Bounds);
bool isFullscreen = CGRect.Equals(newBounds, UIScreen.MainScreen.Bounds);
if(isFullscreen && !wasFullscreen)
{
if(CGRect.Equals(oldBounds,new CGRect(0,0,newBounds.Size.Height, newBounds.Size.Width)))
{
Console.WriteLine("rotated fullscreen");
}
else
{
Console.WriteLine("entered fullscreen");
}
}
else if(!isFullscreen && wasFullscreen)
{
Console.WriteLine("exited fullscreen");
}
}
}
}

Azure Table Storage Warning - WCF Data Services obsolete

After upgrading to the new storage API version 4.2, I'm getting the following warning that I'm calling obsolete methods on some of my segmented queries.
'Microsoft.WindowsAzure.Storage.Table.CloudTableClient.GetTableServiceContext()'
is obsolete: 'Support for accessing Windows Azure Tables via WCF Data
Services is now obsolete. It's recommended that you use the
Microsoft.WindowsAzure.Storage.Table namespace for working with
tables.'
So far I haven't been able to figure out how to achieve this on the new API, and no examples have been put out that I have been able to find. The legacy code still runs fine, but if the new API supports something better I'd love to check it out and get rid of this warning. Could someone point me in the right direction on how a segmented query like this would look using the new API?
Here is what my code currently looks like with the warning:
public AzureTablePage<T> GetPagedResults<T>(Expression<Func<T, bool>> whereCondition, string ContinuationToken, int PageSize, string TableName) {
TableContinuationToken token = GetToken(ContinuationToken);
var query = AzureTableService.CreateQuery<T>(TableName).Where(whereCondition).Take(PageSize).AsTableServiceQuery(AzureTableClient.GetTableServiceContext());
var results = query.ExecuteSegmented(token, new TableRequestOptions() { PayloadFormat = TablePayloadFormat.JsonNoMetadata });
if (results.ContinuationToken != null) {
return new AzureTablePage<T>() { Results = results.ToList(), HasMoreResults = true, ContinuationToken = string.Join("|", results.ContinuationToken.NextPartitionKey, results.ContinuationToken.NextRowKey) };
} else {
return new AzureTablePage<T>() { Results = results.ToList(), HasMoreResults = false };
}
}
public TableServiceContext AzureTableService {
get {
var context = AzureTableClient.GetTableServiceContext();
context.IgnoreResourceNotFoundException = true;
return context;
}
}
public CloudTableClient AzureTableClient {
get {
return mStorageAccount.CreateCloudTableClient();
}
}
Solution
For anyone with the same question, here is the updated code.
/* Add the following Using Statement */
using Microsoft.WindowsAzure.Storage.Table.Queryable;
public AzureTablePage<T> GetPagedResults<T>(Expression<Func<T, bool>> whereCondition, string ContinuationToken, int PageSize, string TableName) where T : class, ITableEntity, new() {
TableContinuationToken token = GetToken(ContinuationToken);
var query = AzureTableClient.GetTableReference(TableName).CreateQuery<T>().Where(whereCondition).Take(PageSize).AsTableQuery();
var results = query.ExecuteSegmented(token, new TableRequestOptions() { PayloadFormat = TablePayloadFormat.JsonNoMetadata });
if (results.ContinuationToken != null) {
return new AzureTablePage<T>() { Results = results.ToList(), HasMoreResults = true, ContinuationToken = string.Join("|", results.ContinuationToken.NextPartitionKey, results.ContinuationToken.NextRowKey) };
} else {
return new AzureTablePage<T>() { Results = results.ToList(), HasMoreResults = false };
}
}
Please see the Tables Deep Dive blog post that we published when we first introduced the new Table Service Layer. If you need LINQ support, please also see the Azure Storage Client Library 2.1 blog post.
We strongly recommend upgrading to Table Service Layer, because it is optimized for NoSQL scenarios and therefore provides much better performance.

How to update a jira issue summary though the rest api using restsharp

I have been playing around with the jira rest api to eventually replace my soap implementation in a c# app using the 4.0 .net framework. I am also using restsharp.
While i had no problem getting an issue or searching for an issue with the rest api, i have been pulling my hairs with updating a jira issue. These are my execute methods, they work fine to do get or search jira issues. Usual error message i get when i call SetJiraIssue is the following {"errorMessages":["one of 'fields' or 'update' required"],"errors":{}}.
If i pass a simple JSOn string exeample(string jSonContent = #"{""Fields"":{""summary"":"" testing summary update""}}") to the body of the request, then it complains that there is no constructor for it.
Anybody out there as an idea of what i am doing wrong? Comments and suggestion are more then welcome
private string Execute(RestRequest request)
{
var client = new RestClient(_jiraUrl);
client.Authenticator = new HttpBasicAuthenticator(_accountId, _password);
request.AddParameter("AccountSid", _accountId, ParameterType.UrlSegment);
var response = client.Execute(request);
if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var jiraManagerException = new ApplicationException(message, response.ErrorException);
throw jiraManagerException;
}
return response.Content;
}
/// <summary>
/// Executes a jira rest call and retuns the response if any as a business object.
/// </summary>
/// <typeparam name="T">Type of the return type for deserialization.</typeparam>
/// <param name="request">THe reste request.</param>
/// <returns></returns>
private T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient(_jiraUrl);
client.Authenticator = new HttpBasicAuthenticator(_accountId, _password);
request.AddParameter("AccountSid", _accountId, ParameterType.UrlSegment);
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var jiraManagerException = new ApplicationException(message, response.ErrorException);
throw jiraManagerException;
}
return response.Data;
}
public void SetJiraIssue(string issueKey, JiraIssue j)
{
RestRequest request = new RestRequest("issue/{key}", Method.PUT);
request.AddUrlSegment("key", issueKey);
request.RequestFormat = DataFormat.Json;
request.AddHeader("Content-type", "application/json");
j.Summary = "modifiying this issue";
request.AddBody(j);
var response = Execute(request);
Console.WriteLine(response);
}
I finally found a way to make it work, it's not totally how i expected it or would of liked it to work but it's the only way i found yet. Hopefully this will be useful to someone else
public void SetJiraIssue(string issueKey, JiraIssue j)
{
RestRequest request = new RestRequest("issue/{key}", Method.PUT);
request.AddUrlSegment("key", issueKey);
request.RequestFormat = DataFormat.Json;
string jSonContent = #"{""fields"":{""summary"":""test changing summary""}}";
request.AddParameter("application/json", jSonContent, ParameterType.RequestBody);
var response = Execute(request);
Console.WriteLine(response);
}

ServiceStack: httpReq.GetRawBody() is empty

I have a global requestfilter from where i want to log all http traffic using log4net - company restriction. Problem is that the InputStream is always lenght = 0. The soap envelope is desezerialized correctly and execution of service is succesfull, but inputstream is unavailable after first serialization. Is this wrong approach, if i want to log all ingoing and outgoing http traffic? What should i do to accomplish this? I do not want to log the deserialized requestDto.
this.RequestFilters.Add((httpReq, httpResp, requestDto) =>
{
LogManager.LogFactory.GetLogger(this.GetType()).Info(httpReq.GetRawBody());
});
Error seems to occur in type ServiceStack.WebHost.Endpoints.Support.SoapHandler in method, where using statement closes stream without buffering it:
protected static Message GetRequestMessage(Stream inputStream, MessageVersion msgVersion)
{
using (var sr = new StreamReader(inputStream))
{
var requestXml = sr.ReadToEnd();
var doc = new XmlDocument();
doc.LoadXml(requestXml);
var msg = Message.CreateMessage(new XmlNodeReader(doc), int.MaxValue,
msgVersion);
return msg;
}
}
When i try to access GetRawBody on type ServiceStack.WebHost.Endpoints.Extensions the following logic is executed:
public string GetRawBody()
{
if (bufferedStream != null)
{
return bufferedStream.ToArray().FromUtf8Bytes();
}
using (var reader = new StreamReader(InputStream))
{
return reader.ReadToEnd();
}
}
Here I would expect the inpustream to be buffered, since it Inputstreaem is no longer available (lenght = 0).
Isn't this a bug?
Have you seen Request Logger or IRequiresRequestStream. These might help provide some insight on logging requests. Also, I don't believe InputStream would have a length on GET requests.

How to list Management Certificate In windows azure using REST Api

I am tring to list all the management certificates in a windows azure subcription. And I tried with the following code. But it gives me an exception. And I could find that response is null and the exception message is "The remote server returned an error: (403) Forbidden."
Please help me with this. Msdn doesn't provide an example for this :(
using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.Xml.Linq;
class ManagemenCertificateViewer
{
public static void Runme()
{
string msVersion = "2012-03-01";
string subscriptionId = "I used the subscription Id here";
try
{
ListManagementCertificates(subscriptionId, msVersion);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: ");
Console.WriteLine(ex.Message);
}
}
private static void ListManagementCertificates(string subscriptionId, string version)
{
string uriFormat = "https://management.core.windows.net/{0}/certificates";
Uri uri = new Uri(string.Format(uriFormat, subscriptionId));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "GET";
request.Headers.Add("x-ms-version", version);
request.ContentType = "application/xml";
XDocument responseBody = null;
HttpStatusCode statusCode;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
// GetResponse throws a WebException for 400 and 500 status codes
response = (HttpWebResponse)ex.Response;
}
statusCode = response.StatusCode;
if (response.ContentLength > 0)
{
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
{
responseBody = XDocument.Load(reader);
}
}
response.Close();
if (statusCode.Equals(HttpStatusCode.OK))
{
XNamespace wa = "http://schemas.microsoft.com/windowsazure";
XElement storageServices = responseBody.Element(wa + "SubscriptionCertificates");
int mngmntCertificateCount = 0;
foreach (XElement storageService in storageServices.Elements(wa + "SubscriptionCertificate"))
{
string publicKey = storageService.Element(wa + "SubscriptionCertificatePublicKey").Value;
string thumbprint = storageService.Element(wa + "SubscriptionCertificateThumbprint").Value;
string certificateData = storageService.Element(wa + "SubscriptionCertificateData").Value;
string timeCreated = storageService.Element(wa + "TimeCreated").Value;
Console.WriteLine(
"Certificate[{0}]{1} SubscriptionCertificatePublicKey: {2}{1} SubscriptionCertificateThumbprint: {3}{1} certificateData{4}{1} timeCreated{5}{1}",
mngmntCertificateCount++, Environment.NewLine, publicKey, thumbprint, certificateData, timeCreated);
}
}
else
{
Console.WriteLine("List Management certificates returned an error:");
Console.WriteLine("Status Code: {0} ({1}):{2}{3}",
(int)statusCode, statusCode, Environment.NewLine,
responseBody.ToString(SaveOptions.OmitDuplicateNamespaces));
}
return;
}
}
Thanks it's working as I expected. I just add the following line and the Method 'GetCertificate(arg1)'
request.ClientCertificates.Add(GetCertificate(certThumbprint));
One more thing, in Msdn help guide there's a tag in respond body called
<TimeCreated>time-created</TimeCreated>
But the api responds not the TimeCreated its just created.
<Created> ..... </Created>
403 error means something wrong with your management certificate used to authenticate your Service Management API requests. I don't see you attaching a management certificate along with your request in your code. You may find this link useful for authenticating service management API requests: http://msdn.microsoft.com/en-us/library/windowsazure/ee460782.
HTH.

Resources