Hi, I can get the list of targets from my cloud database with no problems, but I still cannot post a new target. It always returns the error 401 Unauthorized. This is my full code, it may have parts I got from this forum:
public class VWSConnection
{
private static string access_key = "29c69dee45700a1bbc018b9bd70158b14844fd2e";
private static string secret_key = "77ec8c649bb66fb97876644e16c9b51278fb7b80";
private static string targetName = "MyTarget";
private static string imageLocation = @"/blah/blah/blah/myFile.jpg";
private static byte[] requestBytesArray;
private static void PostNewTargets()
{
WebResponse response = null;
try
{
string requestPath = "/targets";
string serviceURI = url + requestPath;
string httpAction = "POST";
string contentType = "application/json";
string date = string.Format("{0:r}", DateTime.Now.AddHours(+3)); // I added 3 because my location is GMT-3
var imageFile = File.Open(imageLocation, FileMode.Open);
byte[] image = StreamUtils.StreamToByteArray(imageFile);
string metadataStr = "Vuforia test metadata";
byte[] metadata = System.Text.ASCIIEncoding.ASCII.GetBytes(metadataStr);
PostNewTrackableRequest model = new PostNewTrackableRequest();
model.name = targetName;
model.width = "64.0";
model.image = System.Convert.ToBase64String(image);
model.active_flag = "1";
model.application_metadata = System.Convert.ToBase64String(metadata);
string requestBody = JsonWriter.Serialize(model);
HttpWebRequest httpWReq = (HttpWebRequest)HttpWebRequest.Create(serviceURI);
httpWReq.Method = httpAction;
MethodInfo priMethod = httpWReq.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
priMethod.Invoke(httpWReq.Headers, new[] { "Date", date });
httpWReq.ContentType = contentType;
MD5 md5 = MD5.Create();
var contentMD5bytes = md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(requestBody));
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < contentMD5bytes.Length; i++)
{
sb.Append(contentMD5bytes[i].ToString("X2"));
}
string contentMD5 = sb.ToString();
string stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}", httpAction, contentMD5, contentType, date, requestPath);
HMACSHA1 sha1 = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(secret_key));
byte[] sha1Bytes = Encoding.ASCII.GetBytes(stringToSign);
MemoryStream stream = new MemoryStream(sha1Bytes);
byte[] sha1Hash = sha1.ComputeHash(stream);
string signature = System.Convert.ToBase64String(sha1Hash);
httpWReq.Headers.Add("Authorization", string.Format("VWS {0}:{1}", access_key, signature));
var streamWriter = httpWReq.GetRequestStream();
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(requestBody);
requestBytesArray = buffer;
streamWriter.Write(buffer, 0, buffer.Length);
streamWriter.Flush();
streamWriter.Close();
response = httpWReq.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader sr = new StreamReader(receiveStream, System.Text.Encoding.UTF8);
string responseData = sr.ReadToEnd();
response.Close();
sr.Close();
GetTargetsResponse result = JsonReader.Deserialize<GetTargetsResponse>(responseData);
Debug.Log("Transaction result: " + result.result_code);
Debug.Log("Transaction ID: " + result.transaction_id);
}
catch (Exception ex)
{
Debug.Log(string.Format("ERROR: {0}", ex.Message));
}
}
}
public class PostNewTrackableRequest
{
public string name;
public string width;
public string image;
public string active_flag;
public string application_metadata;
}
It will be apreciated if anyone can help me with this.
Thanks.
Hi thanks for this. I was scratching my head over a minute problem in my code for ages until I read this.
My posts here may help anyone trying to do this in unity:
https://developer.vuforia.com/forum/cloud-recognition/vws-requests-c-unity-authentication#comment-2021210
Cheers
Tom