Specified value has invalid HTTP Header characters - c#

Im trying to access WOWZA Streaming Cloud through their REST API from an ASP.NET site, however have little experience in RESTSharp.
Here is an example curl I'm trying to create:
curl -H 'wsc-api-key: KEY' -H 'wsc-access-key: KEY' -H 'Content-Type:
application/json' -X POST -d '{"live_stream": {"name": "MyNewLiveStream",
"transcoder_type": "transcoded", "billing_mode": "pay_as_you_go",
"broadcast_location": "us_west_california", "encoder": "other_rtmp",
"delivery_method": "push", "aspect_ratio_width": 1920,
"aspect_ratio_height": 1080}}'https://api.cloud.wowza.com/api/v1/live_streams/
see: https://sandbox.cloud.wowza.com/apidocs/v1/
Here is the c# code im using:
var client = new RestClient("https://api.cloud.wowza.com/");
var newRequest = new RestRequest("api/v1/live_streams",Method.POST);
newRequest.AddHeader("wsc-api-key", ConfigurationManager.AppSettings["WowzaAPIKey"]);
newRequest.AddHeader("wsc-access-key", ConfigurationManager.AppSettings["WowzaAccessKey"]);
newRequest.AddHeader("Content-Type", "application/json");
var body = "{\"live_stream\": {" +
"\"aspect_ratio_height\": 720," +
"\"aspect_ratio_width\": 1280," +
"\"billing_mode\": \"pay_as_you_go\"," +
"\"broadcast_location\": \"us_west_california\"," +
"\"closed_caption_type\": \"none\"," +
"\"delivery_method\": \"push\"," +
"\"encoder\": \"wowza_gocoder\"," +
"\"hosted_page\": true," +
"\"hosted_page_sharing_icons\": true," +
"\"name\": \"MyLiveStream\"," +
"\"player_countdown\": false," +
"\"player_responsive\": true," +
"\"player_type\": \"original_html5\"," +
"\"player_width\": 0," +
"\"recording\": false," +
"\"target_delivery_protocol\": \"hls\"," +
"\"transcoder_type\": \"transcoded\"," +
"\"use_stream_source\": false}";
newRequest.AddJsonBody(body);
IRestResponse myResponse = client.Execute(newRequest);
Following modifications based on the responses, the response code is now
"{\"meta\":{\"status\":401,\"code\":\"ERR-401-InvalidApiKey\",\"title\":\"Invalid Api Key Error\",\"message\":\"Invalid API key.\",\"description\":\"\",\"links\":[]}}"

Your headers are wrong- you dont need to repeat content-type in value and remove : from the api-key name:
newRequest.AddParameter("content-type", "application/json");
newRequest.AddParameter("wsc-api-key", ConfigurationManager.AppSettings["WowzaAPIKey"]);
Update as OP updated the question
So now after the modification, the call is through and is working fine. The current error is regarding invalid api key you are passing - may be the access key/api key you are passing is invlaid/expired.

Thanks everyone for the help - i can now interact seamlessly with Wowza Cloud Streaming through the REST api wrapped by C# and using restsharp.
The solution in the end was to use the visual studio function to generate template JSON classes through Paste Special (see In C#, how do I model a JSON object with multiple nested arrays?) - generating the WowzaLivestream class.
Then using this code in the end:
_restClient = new RestClient("https://api-sandbox.cloud.wowza.com");
var newRequest = new RestRequest("api/v1/live_streams", Method.POST);
newRequest.RequestFormat = DataFormat.Json;
newRequest.AddHeader("wsc-api-key", ConfigurationManager.AppSettings["WowzaAPIKey"]);
newRequest.AddHeader("wsc-access-key", ConfigurationManager.AppSettings["WowzaAccessKey"]);
newRequest.AddHeader("Content-Type", "application/json");
newRequest.AddHeader("Accept", "application/json");
var requestBody = new WowzaLivestream
{
live_stream = new Live_Stream
{
aspect_ratio_height = 1024,
aspect_ratio_width = 1900,
billing_mode = "pay_as_you_go",
broadcast_location = "eu_ireland",
closed_caption_type = "none",
delivery_method = "push",
encoder = "other_rtmp",
name = "WowzaLStest2: " + DateTime.Now.ToShortTimeString(),
player_countdown = true,
player_responsive = true,
player_type = "original_html5",
player_width = 0,
recording = false,
target_delivery_protocol = "hls",
transcoder_type = "transcoded",
use_stream_source = false
}
};
var json = newRequest.JsonSerializer.Serialize(requestBody);
newRequest.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
IRestResponse myResponse = _restClient.Execute(newRequest);
It turns out that the URL used was wrong - it isnt specifically stated in the documentation but for sandbox use, the URL is https://api-sandbox.cloud.wowza.com.

Are you sure you want to add "content-type", "wsc-api-key" and "wsc-access-key" as request parameters?
They should be added in the request header as following.
newRequest.AddHeader("content-type", "Content-Type: application/json");
newRequest.AddHeader("wsc-api-key:", ConfigurationManager.AppSettings["WowzaAPIKey"]);
newRequest.AddHeader("wsc-access-key", ConfigurationManager.AppSettings["WowzaAccessKey"]);

Related

Get Pdf Rest Sharp (GET)

I am testing a service to which you send a json and it returns a PDF with the data you sent it. I did tests with Insomnia as shown here:
It works correctly, but trying to recover the file through code always generates an error. My code is the following:
var client = new RestClient("Api");
var request = new RestRequest(Method.GET);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\n\t\"QuotationId\": 0,\n\t\"QuotationName\": \"CasaLomas\",\n\t\"UserGUID\": \"75DB06AC-E349-4C47-A5AF-87EC63A9B8A9\",\n\t\"QuotedQuantity\": 5,\n\t\"TotalPrice\": 500,\n\t\"CopyEmail\": \"angelmg50#hotmail.com\",\n\t\"MaterialDetails\": [\n\t\t{\n\t\t\t\"SKU\": \"C05423082015140001\",\n\t\t\t\"Name\": \"PORC KONE WHITE MATE 60x30x1\",\n\t\t\t\"Quantity\": 1,\n\t\t\t\"Price\": 638.09,\n\t\t\t\"Amount\": 6380\n\t\t},\n\t\t{\n\t\t\t\"SKU\": \"C05423082015140001\",\n\t\t\t\"Name\": \"PORC KONE WHITE MATE 60x30x1\",\n\t\t\t\"Quantity\": 1,\n\t\t\t\"Price\": 638.09,\n\t\t\t\"Amount\": 6380\n\t\t},\n\t\t{\n\t\t\t\"SKU\": \"C05423082015140001\",\n\t\t\t\"Name\": \"PORC KONE WHITE MATE 60x30x1\",\n\t\t\t\"Quantity\": 1,\n\t\t\t\"Price\": 638.09,\n\t\t\t\"Amount\": 6380\n\t\t}\n\t]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
This connects correctly with the API but apparently the json has not been sent correctly. Any idea why this happens?
I created the json with dynamic and tried to send it.
dynamic cotizacion = new JObject();
cotizacion.QuotationId = 0;
cotizacion.QuotationName = "Casa lomas 3";
cotizacion.UserGUID = "75DB06AC-E349-4C47-A5AF-87EC63A9B8A9";
cotizacion.QuotedQuantity = 6;
cotizacion.TotalPrice = 456.12;
cotizacion.CopyEmail = "angelmg50#hotmail.com";
cotizacion.MaterialDetails = new JArray(new JObject(
new JProperty("SKU", "C05423082015140001"),
new JProperty("Name", "PORC KONE WHITE MATE 60x30x1"),
new JProperty("Quantity", 1),
new JProperty("Price", 638.09),
new JProperty("Amount", 6380.30)));
var client = new RestClient("Api");
var request = new RestRequest(Method.GET);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", cotizacion, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
But this does not work either.
When I print response.Content in console it shows me the following: "Message": "Internal error when trying to generate the PDF" Value can not be null. \ R \ nParameter name: source "," StatusCode ": 3," Result ": null, "ResultList": null}
https://github.com/restsharp/RestSharp/wiki/Recommended-Usage
It seems like you are trying to add a parameter with the name "application/json". You may need to specify the name of the parameter in the endpoint and use AddObject instead of AddParameter. We can help more if you can give us some more info on your endpoint.

Making POST API request via c# with hashed API Key

I'm trying to make a POST call (from a C# WPF app) to a web service on an internal intranet (so I can't give the exact URL sorry), which is basically a url shortening service.
The page gives the following instructions:
In order to use the API service, simply make HTTP POST requests to this URL:
https://...internalAddress.../api/<method>
For example, to create a snip, make an HTTP POST request to:
https://...internalAddress.../api/shorten
with these parameters:
api_key hash of a registered API key
url URL to be shortened
Now I have tried to implement this in a couple of different ways with what I've found via google / here, these are:
1:
string apiKey = "xxxx11112222333";
string urlForShortening = #"http://www.codeproject.com/Tips/497123/How-to-make-REST-requests-with-Csharp";
string destination = #"https://internalurl/api/shorten";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(destination);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write("{'api_key': '" + apiKey + "', 'url': '" + urlForShortening + "'}");
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
MessageBox.Show(responseText);
}
2: (Using the rest library created in the article found in the shortening link)
string apiKey = "xxxx11112222333";
string urlForShortening = #"http://www.codeproject.com/Tips/497123/How-to-make-REST-requests-with-Csharp";
string destination = #"https://internalurl/api/shorten";
RestClient client = new RestClient(destination, HttpVerb.POST,
"{'api_key': '" + apiKey + "', 'url': '" + urlForShortening + "'}");
var json = client.MakeRequest();
MessageBox.Show(json);
have also tried feeding in the jsonData in double quotes:
var jsonData = "{\"api_key\": \"" + apiKey + "\", \"url\": \"" + urlForShortening + "\"}";
The result from both methods I always get is:
{"status": 400, "message": "Missing API key"}
Can someone please shed some light on what I'm doing wrong?
From the brief, I think the key may need to be hashed in some form and not sure how to do this.
Turns out my whole implementation was wrong, I was trying to send the data as JSON / using the wrong classes instead of a vanilla HTTP POST.
I used Method 2 found in this article and it worked fine: HTTP request with post
ie.
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["api_key"] = "xxxx11112222333";
values["url"] = #"http://www.codeproject.com";
string destination = #"https://internalurl/api/shorten";
var response = client.UploadValues(destination, values);
var responseString = Encoding.Default.GetString(response);
MessageBox.Show(responseString);
}
Thanks for your help though!
I assume that you are attempting to send json data in the request body for the POST call to the API.
You dont seem to be providing a valid json here though. This is what you are sending now:
{'api_key':'someApiKey'}
{'url':'someUrlForShortening'}
Use a json validator to ensure you have a valid json document before you attempt to send it to the API.
A valid json would be
{
"api_key":"someApiKey",
"url":"someUrlForShortening"
}

Woocommerce REST API POST in v2 not working

I have upgraded to V2 and having trouble with posting updates to Woocommerce on my Windows server from C# (using RestSharp).
GET works in both V1 and V2.
Changing order status (for order 81) works in V1, using this code:
var client = new RestClient("https://mysite.com");
client.Authenticator = new HttpBasicAuthenticator("ck_6c5bbb4e467d1994d2428a476bxxxxxx",
"cs_008adefb1692a708e9795de9fxxxxxx");
var requestv1 = new RestRequest("wc-api/v1/orders/{id}", Method.POST);
requestv1.RequestFormat = DataFormat.Json;
requestv1.AddBody(new { status = "completed" });
requestv1.AddParameter("id", 81, ParameterType.UrlSegment);
var queryResultv1 = client.Execute<WC_Manager.OrderSingle>(requestv1);
Changing the resource to "wc-api/v2/orders/{id}" generates no error and the Execute still returns the order now with the extra fields from v2, however the status is NOT changed in the queryresult or in the database.
Same problem when trying to post an update for a product in V2.
Trying to PUT or DELETE gives me a "MethodNotAllowed".
You can add body content with this:
string bodyContent;
bodyContent = "{ \"status\": \"completed\" , ";
bodyContent += "\"customer_note\": \"" + customerNote + "\" }";
request.AddParameter("application/json", bodyContent, ParameterType.RequestBody);

Creating a basecamp TODO returns a 403 forbidden (restsharp, asp.net mvc, basecamp api)

I can get a todo without any problem, but when I POST a todo in basecamp I get 403 forbidden
Here is my code
CODE
var client = new RestClient()
{
BaseUrl = "https://basecamp.com/" + accountId + "/api/v1/projects/" + projectId + "/todolists/" + todolistId + "/todos.json"
};
string baseCampClientId = WebConfigurationManager.AppSettings["bcClientId"];
string baseCampClientSecret = WebConfigurationManager.AppSettings["bcClientSecret"];
var request = new RestRequest(Method.POST);
request.RequestFormat = DataFormat.Json;
string json = JsonConvert.SerializeObject(todo);
request.AddHeader("User-Agent", "MyApp (my#email.com)");
request.AddHeader("Content-type", "application/json");
request.AddHeader("charset", "utf - 8");
request.AddHeader("Authorization", userInfo.BaseCampToken);
request.AddParameter("client_id", baseCampClientId);
request.AddParameter("client_secret", baseCampClientSecret);
request.AddParameter("access_token", userInfo.BaseCampToken);
request.AddBody(json);
var result = client.Execute(request);
string jsonResult = result.Content;
The response is always 403 Forbidden
The json which I send in the request body is
JSON
"{\"content\":\"solve this thing\",\"due_at\":\"2014-07-10T00:00:00.0000000\",\"assignee\":{\"id\":\"1111111\",\"type\":\"Person\"}}"
and here is the image of the request
Please help me to fix this 403 forbidden issue
well i tried your code with only changing one thing and it worked for me. my changes were:
client.Authenticator = new Auth2AuthorizationRequestHeaderAuthenticator(userInfo.BaseCampToken) for
request.AddParameter("access_token", userInfo.BaseCampToken);
also try removing "assignee" from your json data if you have any.

ASP.NET Equivalent to this cURL command

I'm working with the Twilio API and it provides examples in PHP and Ruby. I'm working on a site to send text messages through the API that's coded in ASP.NET MVC 3, and using my limited knowledge of the WebRequest object, I was able to translate this:
curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/AC4840da0d7************f98b20b084/SMS/Messages.xml' \
-d 'From=%2B14155992671' \
-u AC4840da0d7************f98b20b084:f7fc2**************75342
Into this:
var request =
WebRequest.Create(MessageApiString + "?From=+14*********1&To=" + Phone + "&Body=" + smsCampaign.Message);
var user = "AC4840da0d7************f98b20b084";
var pass = "f7fc2**************75342";
string credentials = String.Format("{0}:{1}", user, pass);
request.Headers.Add("Authorization", credentials);
var result = request.GetResponse();
But it's not authenticating, I'm getting a 401 from their API. What is the equivalent C# to the cURL -u command?
Update
var request =
WebRequest.Create(MessageApiString + "?From=+14155992671&To=" + Phone + "&Body=" + smsCampaign.Message);
var cc = new CredentialCache();
cc.Add(new Uri(MessageApiString), "NTLM", new NetworkCredential("AC4840da0d7************f98b20b084", "f7fc2**************75342"));
request.Credentials = cc;
request.Method = "POST";
var result = request.GetResponse();
Still getting 401. Any ideas?
Update 2
Alright, thanks to the answers below I was able to get through to the api, but now I'm getting a 400 Bad Request. Is there a cleaner way to build a query string to pass this data along? The three fields are From, To, and Body.
Try including
request.Method = "POST";
and
request.Credentials = new NetworkCredential("username", "password");
The -u option in Curl is to specify a username and password for Server Authentication.
For C# this is set using the WebRequest.Credentials property.

Categories