在 C# Monodevelop 中创建 Uri 时出错

Posted

技术标签:

【中文标题】在 C# Monodevelop 中创建 Uri 时出错【英文标题】:Error creating Uri in C# Monodevelop 【发布时间】:2017-11-12 10:33:58 【问题描述】:

我正在尝试做一个与 API REST 通信的桌面应用程序,然后我决定在我的 xubuntu 中使用 MonoDevelop 来做。我尝试使用构造函数从字符串创建 Uri,但是当创建对象 Uri 时,它会出现在我的 MonoDevelop 调试器中:

stationUri System.Uri System.Uri AbsolutePath System.NullReferenceException:对象 引用未设置为对象 AbsoluteUri 的实例 System.NullReferenceException:对象引用未设置为 对象权限 System.NullReferenceException 的实例: 对象引用未设置为对象 DnsSafeHost 的实例 System.NullReferenceException:对象引用未设置为 对象片段 System.NullReferenceException 的实例: 对象引用未设置为对象 Host 的实例 System.NullReferenceException:对象引用未设置为 对象 HostNameType System.NullReferenceException 的实例: 对象引用未设置为对象的实例

urlConParametros https://api.thingspeak.com/channels/***/fields/4.json?api_key=***&results=2 字符串 由于安全原因,我没有显示完整的 URL。

以及与此错误相关的相应代码:

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();

如果我完全运行代码,则抛出下一个相关的 stackTrace(我删除了敏感数据):

Gtk# 回调委托中的异常 注意:应用程序可以使用 GLib.ExceptionManager.UnhandledException 来处理异常。 System.Reflection.TargetInvocationException:调用的目标已引发异常。 ---> System.NullReferenceException:对象引用未设置为对象的实例 在 System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] in :0 在 MainWindow.GetResponse_GET(System.String url,System.Collections.Generic.Dictionary`2 参数)[0x0002b] 在 /home//MonoDevelop Projects///MainWindow.cs:92 在 MainWindow.showAct (System.Object sender, System.EventArgs e) [0x0003f] 在 /home//MonoDevelop Projects///MainWindow.cs:34 在(包装器托管到本机) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) 在 System.Reflection.MonoMethod.Invoke(System.Object obj,BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object[] 参数,System.Globalization.CultureInfo 文化)[0x00038] 中:0 --- 内部异常堆栈跟踪结束 --- 在 System.Reflection.MonoMethod.Invoke(System.Object obj,BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object[] 参数,System.Globalization.CultureInfo 文化)[0x00053] 中:0 在 System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] 参数) [0x00000] in :0 在 System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x0010d] in :0 在 System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x0000b] in :0 在 System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in :0 在 GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x00067] in :0 在 GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x0000c] 中:0 在 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 在 GLib.ExceptionManager.RaiseUnhandledException (System.Exception e, Boolean is_terminal) [0x00000] in :0 在 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 在 Gtk.Application.gtk_main () [0x00000] in :0 在 Gtk.Application.Run () [0x00000] in :0 在 .MainClass.Main (System.String[] args) [0x00012] 在 /home//MonoDevelop Projects///Program.cs:13

我不知道为什么不能从字符串中正确建立 Uri...然后如果我传递不正确的 Uri 来创建 WebRequest 也会引发错误...

有谁知道我在这里做错了什么。

【问题讨论】:

向我们展示 urlConParametros 的前 10 个字符。 我已编辑,现在显示前 10 个字符 @NikashaVoncarstein 查询字符串中的值可能需要进行 url 编码。但由于您没有显示传递值的示例,这只是猜测。 好的,不显示您的 api 密钥(当然是安全性的),您应该检查以确保它不包含任何对 url 不友好的字符,否则您需要对其进行 url 编码。 @Nkosi 非常感谢您的帮助,我尝试了: urlEncoded = HttpServerUtility.htmlEncode (url);但是当我尝试构建时,下一个错误出现在前一行: An object Reference is required to access non-static member System.Web.HttpServerUtility.HtmlEncode (string) 【参考方案1】:

检查以确保查询字符串不包含任何对 url 不友好的字符,否则您需要对其进行 url 编码。为避免必须自己编码,您可以在构建 url 时使用 UriBuilder

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

它将根据需要对任何值进行 url 编码。

【讨论】:

嗨!谢谢您的帮助。我为此更改了之前的代码行: //urlGET = "api.thingspeak.com/channels/__/fields/4.json" Uri uri = new Uri(urlGET); var uriBuilder = 新的 UriBuilder(uri); uriBuilder.Query = ConcatParams(参数); Uri stationUri = uriBuilder.Uri; if(stationUri.IsWellFormedOriginalString()) 但在行 var uriBuilder = new UriBuilder(uri);全部出现错误:uri 和 uriBuilder 处的“对象引用未设置为对象的实例”【参考方案2】:

非常感谢您的帮助,我解决了它复制cs文件并在monodevelop中创建一个空的proyect C#并将旧文件放入新项目并重新加载引用,然后new Uri(string)工作......在我之前将项目创建为 gtk#2.0,现在就像是空的并且可以工作...我不知道原因...

【讨论】:

以上是关于在 C# Monodevelop 中创建 Uri 时出错的主要内容,如果未能解决你的问题,请参考以下文章

发布使用 MonoDevelop 制作的应用程序

如何在 spotify 应用程序 API 中创建播放列表并获取其 URI?

通过 monotouch 绑定在 Interface Builder 中创建为 UIView 的自定义控件

如何在 C# 中创建别名

在 C# 中创建 Json 的问题 [关闭]

在c#中创建一个json请求对象