xamarin iOS webView post

huangapple go评论63阅读模式
英文:

xamarin iOS webView post

问题

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 way I "post" the parameters doesn't work... I tried in several different ways (such as a new property StringData) with no luck.... I don't understand how can I do...

英文:

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 == &quot;PostUrl&quot;) {
                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&lt;PostWebView, WKWebView&gt; {

        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 != &quot;&quot;)
                {
                    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 = &quot;POST&quot;;
                    // enable?...
                    //request[&quot;Content-Length&quot;] = request.Body.Length.ToString();
                    //request[&quot;Content-Type&quot;] = &quot;application/x-www-form-urlencoded charset=utf-8&quot;;
                    Control.LoadRequest(request);
                }
                
            }
        }
    }

}

So, in XAML I put my own control

&lt;local:PostWebView x:Name=&quot;postWebView1&quot; Source=&quot;&quot; HeightRequest=&quot;600&quot; WidthRequest=&quot;100&quot; /&gt; 

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 = &quot;https://..../DispatcherServlet&quot;;

and this is GetParamsAsync

        public async Task&lt;byte[]&gt; GetParamsAsync() {

            var dataContent = new FormUrlEncodedContent(new[] {
                new KeyValuePair&lt;string, string&gt;(&quot;a&quot;, &quot;avalue&quot;),
                new KeyValuePair&lt;string, string&gt;(&quot;b&quot;, &quot;bvalue&quot;,
                new KeyValuePair&lt;string, string&gt;(&quot;c&quot;, &quot;cvalue&quot;),
                new KeyValuePair&lt;string, string&gt;(&quot;d&quot;, &quot;dvalue&quot;)
            });

            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...

答案1

得分: 1

最后我以这种方式解决了问题:

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";
英文:

Finally I solved in this way

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

huangapple
  • 本文由 发表于 2023年5月17日 22:58:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76273492.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定