0

I created a custom webViewRenderer in Xamarin in this way.

This is the class in Xamarin 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];
    }

and this is the custom renderer in Android project

[assembly: ExportRenderer(typeof(PostWebView), typeof(PostWebViewRenderer))]
namespace AppWebView.Droid {

    //Custom renderer on the native project
    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 ctlWebView = (Android.Webkit.WebView)Control;
                var view = Element as PostWebView;
                ctlWebView.PostUrl(view.PostUrl, view.PostData);
            }
        }
    }

}

So, now I'm trying to do the same in the iOS project

[assembly: ExportRenderer(typeof(WebView), typeof(AppWebView.iOS.PostWebViewRenderer))]
namespace AppWebView.iOS {
    // Xamarin.Forms.Platform.iOS.WebViewRenderer
    public class PostWebViewRenderer : ViewRenderer<PostWebView, WKWebView> {

        private WKWebView wkWebView;

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == PostWebView.PostUrlProperty.PropertyName)
            {
                var aWebView = Element as PostWebView;

                if (aWebView.PostUrl != "")
                {
                    if (Control == null)
                    {
                        var config = new WKWebViewConfiguration();
                        wkWebView = new WKWebView(Frame, config);
                        SetNativeControl(wkWebView);
                    }

                    var request = new NSMutableUrlRequest(new NSUrl(new NSString(aWebView.PostUrl)));
                    //request.Body = NSData.FromData(NSData.FromArray(aWebView.PostData));
                    request.Body = NSData.FromString(aWebView.StringData);
                    request.HttpMethod = "POST";
                    // enable?...
                    //request["Content-Length"] = request.Body.Length.ToString();
                    //request["Content-Type"] = "application/x-www-form-urlencoded charset=utf-8";
                    Control.LoadRequest(request);
                }
                
            }
        }
    }

}

So, in XAML I put my own control

<local:PostWebView x:Name="postWebView1" Source="" HeightRequest="600" WidthRequest="100" /> 

in code-behind (it's only a test...) I create my request with parameters

            byte[] byteParams = await GetParamsAsync();

            postWebView1.PostData = byteParams;
            postWebView1.StringData = HttpUtility.UrlEncode(byteParams);
            postWebView1.PostUrl = "https://..../DispatcherServlet";

and this is GetParamsAsync

        public async Task<byte[]> GetParamsAsync() {

            var dataContent = new FormUrlEncodedContent(new[] {
                new KeyValuePair<string, string>("a", "avalue"),
                new KeyValuePair<string, string>("b", "bvalue",
                new KeyValuePair<string, string>("c", "cvalue"),
                new KeyValuePair<string, string>("d", "dvalue")
            });

            var s = await dataContent.ReadAsByteArrayAsync();

            return s;
        }

In Android emulator all works fine using PostData property. In iOS emulator the webView is showing the page but the the way I "post" the parameters doesn't work... I tried in several different way (such as a new property StringData) with no luck.... I don't understand how can I do...

6
  • Have you tried this : Is there a way i can use the webview.postURL on xamarin.forms?. and to access unsecure sites may configure or disable ATS.
    – Felix Shen
    Commented May 18, 2023 at 7:40
  • You may also try using a UTF8 encoding: NSString stringData = new NSString(aWebView.StringData);request.Body = stringData.Encode(NSStringEncoding.UTF8);
    – Felix Shen
    Commented May 18, 2023 at 8:25
  • Thank you @LiqunShen-MSFT : your 2nd suggestion works but... server receive only one parameter, a string value. I can't modify the application server-side, so I have to send the parameters in another way...
    – davides77
    Commented May 18, 2023 at 12:11
  • So what kind of data you want the server to receive?
    – Felix Shen
    Commented May 18, 2023 at 12:20
  • Well, I solved in this way var request = new NSMutableUrlRequest(new NSUrl(new NSString(aWebView.PostUrl))); request.Body = NSData.FromArray(aWebView.PostBytesData); request.HttpMethod = "POST"; request["Content-Length"] = request.Body.Length.ToString(); request["Content-Type"] = "application/x-www-form-urlencoded charset=utf-8";
    – davides77
    Commented May 18, 2023 at 12:35

1 Answer 1

1

Finally I solved in this way

var request = new NSMutableUrlRequest(
    new NSUrl(new NSString(aWebView.PostUrl))
);                     
request.Body = NSData.FromArray(aWebView.PostBytesData);
request.HttpMethod = "POST";                     
request["Content-Length"] = request.Body.Length.ToString();   
request["Content-Type"] = "application/x-www-form-urlencoded charset=utf-8";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.