I have an ASP.NET web api
that receives web requests and returns Json
data.
browsing to this URL:
http://1.2.3.4/api1/api/values/mypartname
will return the following json string:
{
\"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.
I'm consuming the json
with a .NET 4 Console application
like so:
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.
Am i doing something wrong with the 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.
EDIT
this is the routeConfig definition:
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:
// 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:
I am leaving this answer here for anyone who finds it in a search, however as Kevin states below and Scott Hanselman says here:
I think your problem has more to do with the forward slash in the part name. You can handle the spaces and quotes using
instead of
HttpUtility.UrlEncode(partName)
.Handling the forward slash is more problematic. See this post for more details.