简体   繁体   English

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

[英]URL Encoding in c# and Asp.net web api

I have an ASP.NET web api that receives web requests and returns Json data. 我有一个ASP.NET web api ,它接收Web请求并返回Json数据。
browsing to this URL: 浏览到此网址:
http://1.2.3.4/api1/api/values/mypartname will return the following json string: 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"me i get a 404 - File or directory not found. error. 但是当发送包含这样的空格或引号的零件名称时: http://1.2.3.4/api1/api/values/my part na"mehttp://1.2.3.4/api1/api/values/my part na"me得到404 - File or directory not found.错误。
I'm consuming the json with a .NET 4 Console application like so: 我正在使用.NET 4 Console application使用json

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(); 在这一行抛出异常: HttpWebResponse hwr = (HttpWebResponse)wr.GetResponse(); and the exception message is: The remote server returned an error: (404) Not Found. 并且异常消息是: The remote server returned an error: (404) Not Found.

Am i doing something wrong with the mypartname ? 我对mypartname做错了吗? I also tried to manually replace the problematic characters according to this: HTML URL Encoding Reference and using this function: Uri.EscapeDataString(partName) but with no luck. 我还尝试根据以下内容手动替换有问题的字符: 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;
        }

EDIT 10 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 : 对于在搜索中发现它的人,我在这里留下这个答案,但凯文在下面说道Scott Hanselman在这里说

[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)

instead of HttpUtility.UrlEncode(partName) . 而不是HttpUtility.UrlEncode(partName)

Handling the forward slash is more problematic. 处理正斜杠更成问题。 See this post for more details. 有关详细信息,请参阅此帖子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM