none
TweetSharp : NullReferenceException lors de l'appel d'AuthenticateWith RRS feed

  • Discussion générale

  • Bonjour !

    Je développe actuellement une application pour Windows Phone 7.1 et je veux donner la possibilité à l'utilisateur de partager via Twitter un lien. 
    Malheureusement je bloque lors de l'authentification. J'ai suivi les instructions de ce site sauf que j'ai utilisé un WebBrowser Control au lieu du WebBrowserTask pour une meilleure expérience utilisateur.

    J'ai simplifié pour le moment mon application avec une page d'accueil, une page Connexion.xaml, qui contient le WebBrowser, un TextBox Pin et un bouton Connect, et enfin la page Composition.xaml pour créer et envoyer le tweet.
    service, Request et Access sont déclarés et initialisés dans App.xaml.cs comme un TwitterService, un OAuthRequestToken et un OAuthAccessToken.

    Code de Connexion.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using TweetSharp;
    
    namespace CeCertainMoment
    {
        public partial class Connexion : PhoneApplicationPage
        {
            public Connexion()
            {
                InitializeComponent();
                //Ask the Token and display the Twitter web page for the authorization
                App.service.GetRequestToken((request, Response) =>
                {
                    if (Response.StatusCode == HttpStatusCode.OK)
                    {
                        App.Request = request;
                        Uri uri = App.service.GetAuthorizationUri(request);
                        System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                            { LoginBrowser.Navigate(uri); });
                    }
                });
            }
    
            private void Connect_Click(object sender, RoutedEventArgs e)
            {
                //Verify the entry of the user
                App.service.GetAccessToken(App.Request, Pin.Text, (access, Response) =>
                {
                    if (Response.StatusCode == HttpStatusCode.OK)
                    {
                        App.Access = access;
                        System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                            { NavigationService.Navigate(new Uri("/Composition.xaml", UriKind.Relative)); });
                    }
                });
            }
        }
    }

    Quand je mets un mauvais Pin, rien ne se passe (ce qui est normal), mais si je mets le bon Pin ou que je laisse le TextBox vide, je suis redirigée vers Composition.xaml and "Here comes trouble".

    Code de Composition.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using TweetSharp;
    
    namespace CeCertainMoment
    {
        public partial class Com
        {
            public Composition()
            {
                InitializeComponent();
            }
    
            private void Envoi_Click(object sender, RoutedEventArgs e)
            {
                App.service.AuthenticateWith(App.Access.Token, App.Access.TokenSecret);
                App.service.SendTweet((Intro.Text + tweet.Text), (Status, Response) =>
                {
                    if (Response.StatusCode == HttpStatusCode.OK)
                    {
                        MessageBox.Show("Tweet Sent !");
                    }
                });
            }
        }
    }

    Lorsque j'arrive à la ligne où AuthenticateWith est appelée l'exception NullReferenceException est levée :

    L'exception System.NullReferenceException n'a pas été gérée   Message=NullReferenceException   StackTrace:        at CeCertainMoment.Composition.Envoi_Click(Object sender, RoutedEventArgs e)        at System.Windows.Controls.Primitives.ButtonBase.OnClick()        at System.Windows.Controls.Button.OnClick()        at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)        at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)        at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)

    Je pense que le App.Access.Token et le App.Access.TokenSecret sont à null mais pourquoi ? Est-ce une erreur au niveau de App.service.GetRequestToken ou de App.service.GetAccessToken ? Comment puis-je déboguer tout ça ? Je dois vous avouer que je suis un peu perdue !

    Merci pour votre aide ou vos commentaires sur mon code et bonne journée ou soirée ou nuit (c'est selon)

    mercredi 2 mai 2012 17:03

Toutes les réponses

  • voila un article qui peut  vous aidez a resoudre ton problem

    http://www.clr-namespace.com/post/Using-TweetSharp-in-a-Windows-Phone-7-app.aspx

    crt.

    jeudi 3 mai 2012 09:27
  • J'ai copié-collé les codes de ce site dans mon appli et la recherche fonctionne correctement donc le problème ne vient pas des clés fournies par Twitter ou de l'initialisation du TwitterService service, si c'est ce que vous vouliez dire.

    Cordialement

    jeudi 3 mai 2012 11:17
  • D'après ce lien on peut voir que dans la StackTrace, on a aussi le fameux "JoltHelper".

    Peut-être est un soucis dû aux performance performé par ton code.


    Et aussi, d'après ce lien, qui indique la réponse à l'autre, sa serait peut-être dû à la non-instanciation de la longueur et/ou de la largeur de certains composants.
    As tu fixés ces valeurs pour ta textbox appelé "Intro"? Ou d'autre composants? Sait-on jamais ^^

    jeudi 3 mai 2012 12:43
  • oui c bien ce la mais enleve l'ancien code et essaye de travailler avec la meme maniere, puis verifie avec la methode

    SendTweet

    a la place de search.

    jeudi 3 mai 2012 12:55
  • J'ai encore simplifié l'appli : juste une page de connexion et si tout fonctionne bien, un tweet inclus dans le code est envoyé. J'ai aussi réécrit le code dans la manière du lien fourni par Didouqen (ce qui fait plus propre) et vérifié si les tailles des éléments étaient bien spécifiés comme suggéré par Mafyou. 

    Mais j'ai toujours NullReferenceException qui bloque à App.service.AuthenticateWith :

    L'exception System.NullReferenceException n'a pas été gérée
      Message=NullReferenceException
      StackTrace:
           at CeCertainMoment.Connexion.<AccessToken>b__3()
           at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
           at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
           at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
           at System.Delegate.DynamicInvokeOne(Object[] args)
           at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
           at System.Delegate.DynamicInvoke(Object[] args)
           at System.Windows.Threading.DispatcherOperation.Invoke()
           at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
           at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
           at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
           at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
           at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
    

    L'exception est un peu différente : il n'y a plus le "JoltHelper".

    Code de Connexion.xaml.cs :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using TweetSharp;
    
    namespace CeCertainMoment
    {
        public partial class Connexion : PhoneApplicationPage
        {
            public Connexion()
            {
                InitializeComponent();
                App.service.GetRequestToken(RequestToken);
            }
    
            private void Connect_Click(object sender, RoutedEventArgs e)
            {
                App.service.GetAccessToken(App.Request, Pin.Text, AccessToken);
            }
    
            private void RequestToken(OAuthRequestToken request, TwitterResponse response)
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    App.Request = request;
                    Uri uri = App.service.GetAuthorizationUri(request);
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    { LoginBrowser.Navigate(uri); });
                }
            }
    
            private void AccessToken (OAuthAccessToken access, TwitterResponse response)
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    App.Access = access;
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        App.service.AuthenticateWith(App.Access.Token, App.Access.TokenSecret);
                        App.service.SendTweet(("#CeCertainMoment où ça marche enfin au son du ronronnement de l'ordinateur !"), EnvoiTweet);
                    });
                }
            }
    
            private void EnvoiTweet(TwitterStatus status, TwitterResponse response) 
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    MessageBox.Show("Tweet envoyé !");
                }
            }
        }
    }
    

    Cordialement

    jeudi 3 mai 2012 18:08
  • Mon problème persiste malgré le fait que j'en ai découvert une des causes : Pin.Text n'était pas accessible. J'ai donc modifié le code afin qu'il le soit et fait le test avec AuthenticateWith avant de rediriger vers Composition.xaml. Voilà le résultat :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using TweetSharp;
    
    namespace CeCertainMoment
    {
        public partial class Connexion : PhoneApplicationPage
        {
            public Connexion()
            {
                InitializeComponent();
                App.service.GetRequestToken(RequestToken);
            }
    
            private void Connect_Click(object sender, RoutedEventArgs e)
            {
                this.Dispatcher.BeginInvoke(delegate()
                {
                    App.service.GetAccessToken(App.Request, Pin.Text, AccessToken);
                });
            }
    
            private void RequestToken(OAuthRequestToken request, TwitterResponse response)
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    App.Request = request;
                    Uri uri = App.service.GetAuthorizationUri(request);
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    { LoginBrowser.Navigate(uri); });
                }
            }
    
            private void AccessToken (OAuthAccessToken access, TwitterResponse response)
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    App.Access = access;
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        App.service.AuthenticateWith(access.Token, access.TokenSecret);
                        NavigationService.Navigate(new Uri("/Composition.xaml", UriKind.Relative));
                    });
                }
            }
        }
    }

    J'ai aussi exploré les variables locales durant l’exécution du code, le GetRequestToken retourne bien un OAuthRequestToken, c'est sur GetAccessToken que ça bug puisque l'OAuthAccessToken access reste null.

    Cordialement et merci pour votre aide ou vos commentaires

    EDIT : Description de l'exception qui ressemble beaucoup à la dernière :

    L'exception System.NullReferenceException n'a pas été gérée
      Message=NullReferenceException
      StackTrace:
           at CeCertainMoment.Connexion.<>c__DisplayClass6.<AccessToken>b__4()
           at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
           at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
           at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
           at System.Delegate.DynamicInvokeOne(Object[] args)
           at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
           at System.Delegate.DynamicInvoke(Object[] args)
           at System.Windows.Threading.DispatcherOperation.Invoke()
           at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
           at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
           at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
           at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
           at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
    

    • Modifié LucileGR vendredi 4 mai 2012 10:54 Oubli de la description de l'exception
    vendredi 4 mai 2012 10:52
  • @LucileGR :

    Je vais prendre le problème autrement, pourquoi n'utilises tu pas les fonctions natives de Windows phone pour faire le partage ? Ainsi, pas de login/password a gérer, bien plus simple et en plus tu peux partager sur facebook, etc... 

    Voila un exemple : 

    ShareLinkTask shareLinkTask = new ShareLinkTask();
    
    shareLinkTask.Title = "Code Samples";
    shareLinkTask.LinkUri = new Uri("http://msdn.microsoft.com/en-us/library/ff431744(v=VS.92).aspx", UriKind.Absolute);
    shareLinkTask.Message = "Here are some great code samples for Windows Phone.";
    
    shareLinkTask.Show();


    S'il vous plaît n'oublier pas de marquer la ou les réponses qui aident à résoudre votre problème. Pour que la discussion puisse être marquée comme résolue


    vendredi 4 mai 2012 11:59
    Modérateur
  • Sinon je viens de vérifier le code source de tweetsharp :

    if (response.StatusCode == HttpStatusCode.OK) {

    indique que la requête à bien eu une réponse, mais cette réponse peut très bien être négative, donc si

    OAuthAccessTokenaccess est null c'est que ton authentification n'est pas bonne

    Regarde dans response.Response ce que twitter t'a retourné comme message



    S'il vous plaît n'oublier pas de marquer la ou les réponses qui aident à résoudre votre problème. Pour que la discussion puisse être marquée comme résolue

    vendredi 4 mai 2012 12:08
    Modérateur
  • @rudyhuyn : le problème des ShareLinkTask est qu'ils ne permettent pas d'envoyer une géolocalisation en plus (j'aurais du le préciser que c'était une autre option laissée à l'utilisateur).

    Quant au message de Twitter il m'est quelque peu obscur : 

    Response
    "�\b\0\0\0\0\0�D�K�0@��031-(\f�@�`��QS�*�\n��^f,�+�8Td�5\b[G���#��or~a���Ȼ���l<��8�����\n�V5͡&��(`=\fv����0����^�yf��ԝ�\aF���tID��\nz‹���X-A[�9m�ud��\a\0\0��\0�\0\b��\0\0\0"

    Et si je l'affiche dans l'appli, il fait dans le concis :

    Capture d'écran en cas d'erreur

    vendredi 4 mai 2012 14:34
  • Ca ressemble à un contenu gzippé ta réponse

    En fait, il faut pas que tu prennes la tête avec l'authentification via PIN, tu peux très bien la faire façon web (c'est ce que je fais pour tvshow et fuse par exemple) : en affectant Callback URL à une vrai uri dans ton interface twitter. 

    Ceci dit, là ca va être difficile de t'aider, tu as mon mail, envoie moi le code de ton application minimum (vire tout ce qui est confidentiel ou autre, juste l'essentiel)


    S'il vous plaît n'oublier pas de marquer la ou les réponses qui aident à résoudre votre problème. Pour que la discussion puisse être marquée comme résolue

    vendredi 4 mai 2012 15:04
    Modérateur
  • Le truc c'est que je sens que la solution est toute bête. Je viens de faire un nouveau test : j'ai mis un point d'arrêt sur App.service.GetAccessToken(App.Request, Pin.Text, AccessToken); et quand je relance l'appli rapidement ça me fait une erreur mais si je lui laisse le temps ça fonctionne, bon faut compter bien 20s !

    EDIT : Avec juste le code suivant de changé  :

    private void Connect_Click(object sender, RoutedEventArgs e)
            {
                string pin = "";
                pin = Pin.Text;
                App.service.GetAccessToken(App.Request, pin, AccessToken);
            }

    En mettant un point d'arrêt sur string pin = ""; et en laissant obligatoirement passer une vingtaine de secondes avant de relancer ça fonctionne. Cette erreur me laisse perplexe !

    • Modifié LucileGR samedi 5 mai 2012 13:48 Info supplémentaire
    vendredi 4 mai 2012 20:04
  • Salut,

    ne cherches pas plus loin, cette erreur est due à une récente mise à jour du côté de Twitter : article sur le blog de Twitter. Cela concerne notamment le SSL.

    J'ai testé avec la library LinqToTwitter et TweetSharp, et les deux ne fonctionnent plus.

    Les auteurs ont l'air au courant, mais ils n'ont toujours pas proposé de mise à jour de leur library. Sur cette discussion, Joe Mayo, l'auteur de LinqToTwitter indique qu'il a un souci, mais pas de réponse en vue : https://dev.twitter.com/discussions/7531

    Rudy, j'ai testé la connexion à Twitter sur TVShow, et ça ne fonctionne pas non plus. Je suis redirigé, et un point d'interrogation dans un losange apparaît dans ton messageBox, puis le progress indicator tourne en boucle et je reste sur la page de login Twitter.

    Donc malheureusement on ne peut rien faire pour le moment, si ce n'est attendre que les libraries soient mises à jour.


    • Modifié nicol3a jeudi 10 mai 2012 06:46
    jeudi 10 mai 2012 06:44
  • Une mise à jour de TweetSharp est sortie il y a 2 jours sur Github : https://github.com/danielcrenna/tweetsharp.

    Le problème a l'air réglé visiblement.

    samedi 26 mai 2012 18:30