c#和Asp.net web api中的URL编码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15244697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:37:23  来源:igfitidea点击:

URL Encoding in c# and Asp.net web api

c#url.net-4.0asp.net-web-apiconsole-application

提问by Yoav

I have an ASP.NET web apithat receives web requests and returns Jsondata.
browsing to this URL:
http://1.2.3.4/api1/api/values/mypartnamewill return the following json string:

我有一个ASP.NET web api接收网络请求并返回Json数据的。
浏览到此 URL:
http://1.2.3.4/api1/api/values/mypartname将返回以下 json 字符串:

{
    \"PartName\": \"mypartname\",
    \"PartDes\": \"53.6X53.6APA/ALIM1NOTPAK\",
    \"PartLocation\": \"A36\"
}

but when sending a part name that contains spaces or quotes like this: http://1.2.3.4/api1/api/values/my part na"mei get a 404 - File or directory not found.error.
I'm consuming the jsonwith a .NET 4 Console applicationlike so:

但是当发送包含空格或引号的零件名称时:http://1.2.3.4/api1/api/values/my part na"me我收到一个404 - File or directory not found.错误。
我正在json.NET 4 Console application这样的方式消费:

static void Main(string[] args)
    {
        try
        {
            string partName = "TAPE 56 3M 3/4\"";
            WebRequest wr = WebRequest.Create("http://1.2.3.4/api1/api/values/" +
                HttpUtility.UrlEncode(partName));
            wr.Credentials = CredentialCache.DefaultCredentials;
            HttpWebResponse hwr = (HttpWebResponse)wr.GetResponse();
            Stream dataStream = hwr.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string json = reader.ReadToEnd();
            //some json parsing function
            des(json);
            reader.Close();
            dataStream.Close();
            hwr.Close();

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.ReadKey();
        }
    }

the exception is thrown at this line:HttpWebResponse hwr = (HttpWebResponse)wr.GetResponse();and the exception message is: The remote server returned an error: (404) Not Found.

在这一行抛出异常:HttpWebResponse hwr = (HttpWebResponse)wr.GetResponse();并且异常消息是:The remote server returned an error: (404) Not Found.

Am i doing something wrong with the mypartname? I also tried to manually replace the problematic characters according to this: HTML URL Encoding Referenceand using this function:Uri.EscapeDataString(partName)but with no luck.

我做错了mypartname什么吗?我还尝试根据以下内容手动替换有问题的字符:HTML URL 编码参考并使用此功能:Uri.EscapeDataString(partName)但没有运气。

EDIT
this is the routeConfig definition:

编辑
这是 routeConfig 定义:

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );  

and the api GET method:

和 api GET 方法:

// GET api/values/5
    public string Get(string id)
    {

        List<dummy> dummies = new List<dummy>();
        string con = "user id=sa;" +
                     "password=1234" +
                     "server=someServer\someInstance;" +
                     "database=game; " +
                     "connection timeout=30";

        //SqlConnection sqlConn = new SqlConnection(con);
        using (SqlConnection sqlconn = new SqlConnection(con))
        {
            sqlconn.Open();
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT PART.PARTNAME,PART.PARTDES, PARTPARAMA.LOCATION ");
            sb.Append("FROM PART LEFT JOIN PARTPARAMA ");
            sb.Append("ON PART.PART = PARTPARAMA.PARTPARAM ");
            sb.Append("WHERE PART.PARTNAME = @part");


            using (SqlCommand cmd = new SqlCommand(sb.ToString(), sqlconn))
            {
                cmd.Parameters.AddWithValue("part", id);
                SqlDataReader sdr = cmd.ExecuteReader();
                while (sdr.Read())
                {

                    dummies.Add(new dummy
                    {
                        PartName = sdr.IsDBNull(0) ? "Unknown" : sdr.GetString(0),
                        PartDes = sdr.IsDBNull(1) ? "Unknown" : sdr.GetString(1),
                        PartLocation = sdr.IsDBNull(2) ? "Unknown" : sdr.GetString(2)
                    });
                }
            }
        }

        if (dummies.Count() > 0)
        {
            string json = JsonConvert.SerializeObject(dummies[0]);
            return json;
        }
        else
        {
            string json = JsonConvert.SerializeObject(null);
            return json;
        }

采纳答案by Jon Susiak

EDIT10 Apr 2015:

2015 年 4 月 10 日编辑

I am leaving this answer here for anyone who finds it in a search, however as Kevin states below and Scott Hanselman says here:

我将这个答案留在这里给任何在搜索中找到它的人,但是正如凯文在下面所说的斯科特汉塞尔曼在这里说

[UrlPathEncode] doesn't do what you think it does ... This method was very specific, poorly named, and is now totally obsolete.

[UrlPathEncode] 并没有像你想象的那样做......这个方法非常具体,名字很糟糕,现在已经完全过时了。



I think your problem has more to do with the forward slash in the part name. You can handle the spaces and quotes using

我认为您的问题与零件名称中的正斜杠有关。您可以使用处理空格和引号

HttpUtility.UrlPathEncode(partName)

HttpUtility.UrlPathEncode(partName)

instead of HttpUtility.UrlEncode(partName).

而不是 HttpUtility.UrlEncode(partName).

Handling the forward slash is more problematic. See this postfor more details.

处理正斜杠更成问题。有关更多详细信息,请参阅此帖子