Issue
I am working on a mobile application developed with Xamarin and I have encountered a problem when trying to display a Website in a WebView.
<WebView Grid.Column="0" Grid.Row="1" x:Name="webView" source="https://ecommerce.netpay.com.mx/a-webapp3/e-commerce/web-authorizer?checkoutTokenId=fc912ec2-5f20-4533-91cf-95db61d26822" WidthRequest="700" HeightRequest="700" />
When running the application it shows me the following error. I understand that this happens when the method I am using is not correct.
Then I tried the following in the code behind:
private async Task urlAsync()
{
var client = new HttpClient();
var url = "https://ecommerce.netpay.com.mx/a-webapp3/e-commerce/web-authorizer?checkoutTokenId=fc912ec2-5f20-4533-91cf-95db61d26822";
var req = new HttpRequestMessage(HttpMethod.Post, url);
var response = await client.SendAsync(req);
var readAsStringAsync = response.Content.ReadAsStringAsync();
var stringHtml = readAsStringAsync.Result;
var html = new HtmlWebViewSource
{
Html = stringHtml
};
webView.Source = html;
}
And I removed the "source" property from the WebView tag. But this did not work properly because the site does not fully load.
Finally I create a Web project and this works:
<html>
<body>
<form action="https://ecommerce.netpay.com.mx/a-webapp3/e-commerce/web-authorizer?checkoutTokenId=0a377ca8-e26c-4f22-a751-52719acf9019&checkoutDetail=true&MerchantResponseURL=aHR0cHM6Ly9nb29nbGUuY29t" method="POST" target="_blank">
JWT: <input type="text" name="jwt"><br>
<input type="submit" value="Submit">
</form>
<p>Haga clic en el botón Enviar y la entrada se enviará a una página del servidor llamada "/action_page.php".</p>
</body>
</html>
Any ideas how to implement it in Xamarin? Thank you.
Solution
You need to acces the PostUrl
method of the underliying Android WebView. As it's not exposed by the default WebView you need to create a derived webview and a custom renderer:
//Derived class in your forms project
public class PostWebView : WebView
{
public static readonly BindableProperty PostUrlProperty =
BindableProperty.Create(nameof(PostUrl), typeof(string), typeof(PostWebView), string.Empty, BindingMode.OneWay);
public string PostUrl
{
get { return (string)GetValue(PostUrlProperty); }
set { SetValue(PostUrlProperty, value); }
}
public byte[] PostData { get; set; } = new byte[0];
}
//Custom renderer on the native project
[assembly: ExportRenderer(typeof(PostWebView), typeof(PostWebViewRenderer))]
namespace (your project namespace).Droid
{
public class PostWebViewRenderer : WebViewRenderer
{
public PostWebViewRenderer(Context ctx) : base(ctx) { }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "PostUrl")
{
if (Control == null)
return;
var web = (Android.Webkit.WebView)Control;
var view = Element as PostWebView;
web.PostUrl(view.PostUrl, view.PostData);
}
}
}
}
Now you can POST navigate using the new property PostUrl
, also, you can add any data you need to POST to the server using PostData
.
//You can set it to new byte[0] if you don't need to send any data.
postView.PostData = Encoding.ASCII.GetBytes("param1=1¶m2=2");
//Now set tyhe URL to navigate
postView.PostUrl = "http://myserver.com/my/post/url";
If you need to bind this with XAML or set PostUrl
before the control has been created you will need to hook the ElementChanged
event, check if the PostUrl
property and if it has been set call the PostUrl
method of the Android WebView.
Answered By - Gusman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.