0

I'm trying to do a desktop application which communicates with an API REST, then I decided to do it with MonoDevelop in my xubuntu. I tried to Create a Uri from string with the constructor but, when the object Uri is created, it appears in my MonoDevelop debugger:

stationUri {System.Uri}
System.Uri AbsolutePath System.NullReferenceException: Object reference not set to an instance of an object AbsoluteUri System.NullReferenceException: Object reference not set to an instance of an object Authority System.NullReferenceException: Object reference not set to an instance of an object DnsSafeHost System.NullReferenceException: Object reference not set to an instance of an object Fragment System.NullReferenceException: Object reference not set to an instance of an object Host
System.NullReferenceException: Object reference not set to an instance of an object HostNameType System.NullReferenceException: Object reference not set to an instance of an object

urlConParametros https://api.thingspeak.com/channels/***/fields/4.json?api_key=***&results=2 string Because of security reasons I didn't show the full URL.

And the respective code associated with this error:

public string GetResponse_GET(string url, Dictionary<string, string> parameters)
{
    try
    {
        //Concatenamos los parametros, OJO: antes del primero debe estar el caracter "?"
        string parametrosConcatenados = ConcatParams(parameters);
        string urlConParametros = url + "?" + parametrosConcatenados;
        string responseFromServer = null;
        Uri stationUri = new Uri(urlConParametros);
        if(!stationUri.IsWellFormedOriginalString())
        {
            System.Console.WriteLine("Url Vacía");
        }
        else
        {
            System.Net.HttpWebRequest wr = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(stationUri);
            wr.Method = "GET";

            wr.ContentType = "application/x-www-form-urlencoded";

            System.IO.Stream newStream;
            // Obtiene la respuesta
            System.Net.WebResponse response = wr.GetResponse();
            // Stream con el contenido recibido del servidor
            newStream = response.GetResponseStream();
            System.IO.StreamReader reader = new System.IO.StreamReader(newStream);
            // Leemos el contenido
            responseFromServer = reader.ReadToEnd();

            // Cerramos los streams
            reader.Close();
            newStream.Close();
            response.Close();
        }
        return responseFromServer;
    }
    catch (System.Web.HttpException ex)
    {
        if (ex.ErrorCode == 404)
            throw new Exception("Servicio Remoto No Encontrado: " + url);
        else throw ex;
    }
}

private string ConcatParams(Dictionary<string, string> parameters)
{
    bool FirstParam = true;
    string Parametros = null;

    if (parameters != null)
    {
        Parametros = "";
        foreach (KeyValuePair<string, string> param in parameters)
        {
            if(!FirstParam)
                Parametros+="&";
            Parametros+= param.Key + "=" + param.Value;
            FirstParam = false;
        }
    }

    return Parametros == null ? String.Empty : Parametros.ToString();
}

If I run completely the code, throws the next stackTrace associated (I removed the sensitive data):

Exception in Gtk# callback delegate Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object at System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] in :0 at MainWindow.GetResponse_GET (System.String url, System.Collections.Generic.Dictionary`2 parameters) [0x0002b] in /home//MonoDevelop Projects///MainWindow.cs:92 at MainWindow.showAct (System.Object sender, System.EventArgs e) [0x0003f] in /home//MonoDevelop Projects///MainWindow.cs:34 at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00038] in :0 --- End of inner exception stack trace --- at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00053] in :0 at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in :0 at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x0010d] in :0 at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x0000b] in :0 at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in :0 at GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x00067] in :0 at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x0000c] in :0 at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x00086] in :0 at GLib.ExceptionManager.RaiseUnhandledException (System.Exception e, Boolean is_terminal) [0x00000] in :0 at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x00000] in :0 at Gtk.Application.gtk_main () [0x00000] in :0 at Gtk.Application.Run () [0x00000] in :0 at .MainClass.Main (System.String[] args) [0x00012] in /home//MonoDevelop Projects///Program.cs:13

I don't know why can't establish correctly the Uri from string... Then if I pass the incorrect Uri to create the WebRequest throws an error too...

Does anyone know what I am doing wrong here.

  • Show us the first 10 characters of urlConParametros . – mjwills Jun 10 '17 at 14:05
  • I edited and I show the first 10 characters now – Nikasha Von carstein Jun 10 '17 at 15:19
  • @NikashaVoncarstein The values in the query string probably need to be url encoded. But since you have not shown an example of the values being passed, that would just be a guess. – Nkosi Jun 10 '17 at 16:30
  • Ok without showing your api key (security of course), you should check to make sure that it does not contain any characters that are not url friendly otherwise you need to url encode it. – Nkosi Jun 10 '17 at 16:47
  • @Nkosi Thank you so mucho for your help, I tried with: urlEncoded = HttpServerUtility.HtmlEncode (url); But when I tried to build, the next error appears in before line: An object Reference is required to access non-static member System.Web.HttpServerUtility.HtmlEncode (string) – Nikasha Von carstein Jun 10 '17 at 16:50
  • When those messages appear in the debugger, does the code continue as if there was no exception? If so, it is likely a first chance exception and you should ignore it - https://stackoverflow.com/questions/564681/what-is-a-first-chance-exception . – mjwills Jun 10 '17 at 22:17

2 Answers2

1

Thank you so much for the help, I solved it copying cs files and creating an empty proyect C# in monodevelop and putting the old files in the new project and reloading references, then new Uri(string) works... Before I created the project as gtk#2.0 and now like empty and works... I dnt know the reason...

0

check to make sure that query string does not contain any characters that are not url friendly otherwise you need to url encode it. To avoid having to encode it yourself you can use the UriBuilder class when contructing the url

var uriBuilder = new UriBuilder(uri);
uriBuilder.Query = ConcatParams(parameters);
Uri stationUri = uriBuilder.Uri;
//if NOT well formed 
if(!stationUri.IsWellFormedOriginalString()) { //Note the `!` exclamation mark
    //...code removed for brevity
} else {
    //...code removed for brevity
}

It will url encode any values as necessary.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Hi! Thank you for your help. I changed the before code lines for this: //urlGET = "https://api.thingspeak.com/channels/__/fields/4.json" Uri uri = new Uri(urlGET); var uriBuilder = new UriBuilder(uri); uriBuilder.Query = ConcatParams(parameters); Uri stationUri = uriBuilder.Uri; if(stationUri.IsWellFormedOriginalString()) But at line var uriBuilder = new UriBuilder(uri); All appears with error: "Object reference not set to an instance of an object" at uri and uriBuilder – Nikasha Von carstein Jun 10 '17 at 17:18