Confluence Rest API: Can I create a page by space and parent? - c#

Im just facing the fact, that i want to create a page in a certain space as a child of a defined parent.
Is there a possibility to do this by these means?
I didn't find it yet.
Thank you! :)

Please have a look at the documentation:
Create a new page as a child of another page
This is curl, but should be the similar in C#

Create a new page as a child of another page
This is a REST API. Because the REST API is based on open standards, you can use any web development language to access the API.
In C#, you could use one of the following options:
HttpWebRequest / HttpWebResponse
WebClient
HttpClient (available from .NET 4.5 on)
I'd highly recommend using the HttpClient class, as it's engineered to be much better (from a usability standpoint) than the former two.

all the parts you'll need:
the createPage function
the http post function
the dumb class to make the sample json qualified.
the sample json & base url
internal static string createAPage(string space, string title, string body, string objectType, int ancestorId = -1)
{
string json = string.Empty;
try
{
CreateContentWithParentJson createContentWithParentJson = JsonConvert.DeserializeObject<CreateContentWithParentJson>(_jsonCreatePageWithParentSample);
createContentWithParentJson.space.key = space;
createContentWithParentJson.title = title;
body = body.Replace("&", "&");
createContentWithParentJson.body.storage.value = "<p>" + body + "</p>";
Ancestor a = new Ancestor();
a.id = ancestorId;
createContentWithParentJson.ancestors = new List<Ancestor>();
createContentWithParentJson.ancestors.Add(a);
json = JsonConvert.SerializeObject(createContentWithParentJson, Utils.getJsonSettings());
}
catch (Exception) { // handle exception
}
return Utils.contentPost(json, _baseUrl);
}
internal static string contentPost(string postData, string url, string method = "POST")
{
string encodedCred = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(ConfAPI._confUser + ":" + ConfAPI._confPass));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add("Authorization", "Basic " + encodedCred);
request.Headers.Add("X-Atlassian-Token", "no-check");
request.Method = method;
request.Accept = "application/json";
request.ContentType = "application/json";
// request.KeepAlive = false;
if (postData != null)
{
byte[] data = Encoding.UTF8.GetBytes(postData);
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
}
WebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException e)
{
return e.Message + " " + e.StackTrace.ToString();
}
var responsestring = new StreamReader(response.GetResponseStream()).ReadToEnd();
return responsestring;
}
public class CreateContentWithParentJson
{
public string type { get; set; }
public string title { get; set; }
public List<Ancestor> ancestors { get; set; }
public Space space { get; set; }
public Body body { get; set; }
}
internal static string _baseUrl = "http://localhost:8090/rest/api/content";
internal static string _jsonCreatePageWithParentSample = #"{'type':'page','title':'new page', 'ancestors':[{'id':456}], 'space':{'key':'TST'},'body':{'storage':{'value':'<p>This is a new page</p>','representation':'storage'}}}";

Related

Http Web Request Errors in UWP Application

I am using the Microsoft Translator API in .NET UWP application and I'm following the steps for obtaining an access token from the link:
https://msdn.microsoft.com/en-us/library/hh454950.aspx?f=255&MSPPError=-2147217396
I copied the code into my project, but I'm getting errors on the HttpWebRequest GetRequestStream() and GetResponse() methods saying it does not contain a definition for those. I believe the issue is that I'm using a UWP application since I tried it out in a console application and it worked.
Does anyone know how I can get this code to work in my UWP application? TIA.
private AdmAccessToken HttpPost(string DatamarketAccessUri, string requestDetails)
{
//Prepare OAuth request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(DatamarketAccessUri);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
//webRequest.ContentLength = bytes.Length;
using (Stream outputStream = webRequest.GetRequestStream())
{
outputStream.Write(bytes, 0, bytes.Length);
}
using (WebResponse webResponse = webRequest.GetResponse())
{
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
//Get deserialized object from JSON stream
AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
return token;
}
}
UPDATE
The errors that I was getting for the above code were fixed when I followed the checked answer. However, there's still one more error that I'm trying to fix - I followed the response in the comments below, and while the errors went away, the code exits at the line
WebResponse response = await translationWebRequest.GetResponseAsync();
Relevant code posted below:
//Exits on the WebResponse line
private static async System.Threading.Tasks.Task<string> DetectMethod(string authToken, AdmAccessToken token, string txtToTranslate)
{
string headerValue = "Bearer " + token.access_token;
string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + WebUtility.UrlEncode(txtToTranslate) + "&from=en&to=es";
WebRequest translationWebRequest = WebRequest.Create(uri);
translationWebRequest.Headers["Authorization"] = headerValue;
WebResponse response = await translationWebRequest.GetResponseAsync(); //where it's exiting
System.IO.Stream stream = response.GetResponseStream();
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
System.IO.StreamReader translatedStream = new System.IO.StreamReader(stream, encode);
System.Xml.XmlDocument xTranslation = new System.Xml.XmlDocument();
xTranslation.LoadXml(translatedStream.ReadToEnd());
translatedText = xTranslation.InnerText;
return null;
}
//Where DetectMethod is called from
public static async System.Threading.Tasks.Task<string> Translate(string TextToTranslate)
{
AdmAccessToken admToken;
string headerValue;
AdmAuthentication admAuth = new AdmAuthentication("<>", "<>");//codes removed
try
{
admToken = admAuth.GetAccessToken();
// Create a header with the access_token property of the returned token
headerValue = "Bearer " + admToken.access_token;
await DetectMethod(headerValue, admToken, TextToTranslate); //calls previous method
}
catch (WebException e)
{
ProcessWebException(e);
}
return translatedText;
}
The method that calls upon Translate() method also has await for calling the method and async in its signature. Again, with these changes, there are no more errors, but the program exits at the WebResponse line.
I copied the code into my project, but I'm getting errors on the HttpWebRequest GetRequestStream() and GetResponse() methods saying it does not contain a definition for those. I believe the issue is that I'm using a UWP application since I tried it out in a console application and it worked.
Yes,UWP is targeting .Net Core while console application is targeting normal .Net Framework.
Instead of GetRequestStream and GetResponse you can use the async version like below:
//mark the method as async
private async System.Threading.Tasks.Task<AdmAccessToken> HttpPost(string DatamarketAccessUri, string requestDetails)
{
...
//use 'GetRequestStreamAsync'
using (Stream outputStream =await webRequest.GetRequestStreamAsync())
{
...
}
//use 'GetResponseAsync' instead
using (WebResponse webResponse = await webRequest.GetResponseAsync())
{
...
return token;
}
}
Update: I made a demo using translator API. Here are the codes:
MainPage.xaml:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Center">
<Button Name="myBtn" Click="myBtn_Click">Click Me</Button>
<TextBlock Name="myTB"></TextBlock>
</StackPanel>
</Grid>
MainPage.xaml.cs:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void myBtn_Click(object sender, RoutedEventArgs e)
{
var translatedText = await Translate("Text for test");
myTB.Text = translatedText;
}
//Exits on the WebResponse line
private static async System.Threading.Tasks.Task<string> DetectMethod(string authToken, AdmAccessToken token, string txtToTranslate)
{
string headerValue = "Bearer " + token.access_token;
string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + WebUtility.UrlEncode(txtToTranslate) + "&from=en&to=es";
WebRequest translationWebRequest = WebRequest.Create(uri);
translationWebRequest.Headers["Authorization"] = headerValue;
WebResponse response = await translationWebRequest.GetResponseAsync(); //where it's exiting
System.IO.Stream stream = response.GetResponseStream();
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
System.IO.StreamReader translatedStream = new System.IO.StreamReader(stream, encode);
System.Xml.XmlDocument xTranslation = new System.Xml.XmlDocument();
xTranslation.LoadXml(translatedStream.ReadToEnd());
//translatedText = xTranslation.InnerText;
return xTranslation.InnerText;
}
//Where DetectMethod is called from
public static async System.Threading.Tasks.Task<string> Translate(string TextToTranslate)
{
AdmAccessToken admToken;
string headerValue;
string translatedText=null;
AdmAuthentication admAuth = new AdmAuthentication("<>", "<>");//codes removed
try
{
admToken =await admAuth.GetAccessToken();
// Create a header with the access_token property of the returned token
headerValue = "Bearer " + admToken.access_token;
translatedText= await DetectMethod(headerValue, admToken, TextToTranslate); //calls previous method
}
catch (WebException e)
{
}
return translatedText;
}
public class AdmAccessToken
{
public string access_token { get; set; }
public string token_type { get; set; }
public string expires_in { get; set; }
public string scope { get; set; }
}
public class AdmAuthentication
{
string clientID = "winffee_4960";
string clientSecret = "N0aTQ4OUKKP5lpNIBs0h9wfFXGpHlel1BpIkmDd1cVE=";
String strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
String strRequestDetails;
public AdmAuthentication(String str1, String str2)
{
strRequestDetails= string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", WebUtility.UrlEncode(clientID), WebUtility.UrlEncode(clientSecret));
}
public async Task<AdmAccessToken> GetAccessToken()
{
WebRequest webRequest = System.Net.WebRequest.Create(strTranslatorAccessURI);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(strRequestDetails);
//webRequest.ContentType = bytes.Length;
using (Stream outputStream = await webRequest.GetRequestStreamAsync())
{
outputStream.Write(bytes, 0, bytes.Length);
}
WebResponse webResponse = await webRequest.GetResponseAsync();
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
//Get deserialized object from JSON stream
AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
string headerValue = "Bearer " + token.access_token;
return token;
}
}
}

why can't I send WNS toast notification from c# to windows phone 8.1

I have followed these two guides:
https://msdn.microsoft.com/en-us/library/windows/apps/hh202945(v=vs.105).aspx
https://msdn.microsoft.com/library/windows/apps/xaml/hh868252
The resulting code is the following. Despite it all seems right, it returns a 404 error. How can this be? Any help will delay my suicide.
public static void PushToWindows2()
{
try
{
var accessToken = GetAccessToken("Nhz******************XkwX", "ms-app://s-1-15-2-***************-2150981501");
byte[] contentInBytes = Encoding.UTF8.GetBytes("<toast launch=\"\"><visual lang=\"en-US\"><binding template=\"ToastImageAndText01\"><image id=\"1\" src=\"World\" /><text id=\"1\">Hello</text></binding></visual></toast>");
HttpWebRequest request = HttpWebRequest.Create("https://db5.notify.windows.com/?token=awyaaaborhlhub%2bfxeytzjnz****************pftroh5l18sgorvgrkq%3d") as HttpWebRequest;
request.Method = "POST";
request.ContentLength = contentInBytes.Length;
request.ContentType= "text/xml";
request.Headers.Add("X-WindowsPhone-Target", "token");
request.Headers.Add("X-NotificationClass", "1"); ;
request.Headers.Add("X-WNS-Type", "wns/toast");
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken.ToString()));
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
}
catch (Exception ex)
{
Console.Write("EXCEPTION: " + ex.Message);
}
}
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
public static OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
public static OAuthToken GetAccessToken(string secret, string sid)
{
var urlEncodedSecret = HttpUtility.UrlEncode(secret);
var urlEncodedSid = HttpUtility.UrlEncode(sid);
var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",
urlEncodedSid,
urlEncodedSecret);
string response;
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
response = client.UploadString("https://login.live.com/accesstoken.srf", body);
}
return GetOAuthTokenFromJson(response);
}
I have also tried to go the PushSharp route, in which case, I get the "Device subscription has expired" error. Here goes:
var config = new WnsConfiguration("424****.*******nts", "ms-app://s-1-15-2-***************1501", "Nhz************XkwX");
// Create a new broker
var wnsBroker = new WnsServiceBroker (config);
wnsBroker.QueueNotification(new WnsToastNotification {
ChannelUri = deviceId,
Payload = XElement.Parse (#"
<toast>
<visual>
<binding template=""ToastText01"">
<text id=""1"">WNS_Send_Single</text>
</binding>
</visual>
</toast>")
});
}
Update:
It is not encoding related either. I've used both the unencoded token with = and + signs and the encoding one. Still 404
HTTP 404 error for WNS means that the channel URI itself has been munged with so WNS can't understand it. It looks like from your code the channel URI is getting tolower()ed somewhere - usually the tokens start with something like "AwYAAAD". Try removing whatever's lowercasing the channel URI.
Also, it looks like you're mixing WNS and MSDN documentation when you want WNS (although this is not causing your 404 errors). This is WNS, but this is MPNS documentation. Specifically, these headers are for MPNS and will be ignored or failed by WNS:
X-WindowsPhone-Target
X-NotificationClass
X-NotificationStatus
X-SubscriptionStatus
X-DeviceConnectionStatus
You want to use these WNS headers instead.

REST seems to reject JSON POST

I'm trying to POST data in JSON format but the server is rejecting it. It works if I POST in XML and it will reply in either XML or JSON.
The contract is
[ServiceContract]
public interface IService
{
// One string data
[OperationContract]
[WebInvoke(
BodyStyle = WebMessageBodyStyle.Bare,
Method = "POST",
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "data")]
string DataPost(Hidden param);
}
// If you get a compilation error, add
// System.Runtime.Serialization to the references
[DataContract(Name = "Hidden", Namespace = "")]
public class Hidden
{
[DataMember]
public string id { get; set; }
}
The implementation is
public class Service : IService
{
public string DataPost(Hidden param)
{
Console.WriteLine("DataPost " + param.id);
return "DataPost said " + param.id;
}
}
On the client side, it is the run of the mill standard stuff.
namespace client
{
enum HttpVerb
{
GET,
POST,
PUT,
DELETE
};
class RestClient
{
// Properties
public string EndPoint { get; set; }
public HttpVerb Method { get; set; }
public string ContentType { get; set; }
public string ParamData { get; set; }
public string PostData { get; set; }
// Methods
public string MakeRequest()
{
var responseValue = string.Empty;
string ep = EndPoint;
if (!string.IsNullOrEmpty(ParamData))
ep += "/" + ParamData;
var request = (HttpWebRequest)WebRequest.Create(ep);
request.Method = Method.ToString();
request.ContentLength = 0;
request.ContentType = ContentType;
// Postdata parameters
if (!string.IsNullOrEmpty(PostData) && Method == HttpVerb.POST)
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(PostData);
request.ContentLength = bytes.Length;
using (var postStream = request.GetRequestStream())
{
postStream.Write(bytes, 0, bytes.Length);
}
if (PostData.Substring(0, 1) != "<")
request.ContentType = "application/json";
Console.WriteLine("Content type is " + request.ContentType.ToString());
}
// Send request and get response
using (var response = (HttpWebResponse)request.GetResponse())
{
// Did it work?
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// get response
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
}
}
return responseValue;
}
void TalkTo(
HttpVerb in_method,
string in_endPoint,
string in_paramdata,
string in_postdata)
{
Method = in_method;
EndPoint = in_endPoint;
ContentType = "text/xml";
ParamData = in_paramdata;
PostData = in_postdata;
try
{
string response = MakeRequest();
Console.WriteLine("Endpoint: " + EndPoint);
Console.WriteLine("Resp : " + response);
Console.WriteLine();
}
catch (System.Net.WebException e)
{
Console.WriteLine("Endpoint: " + EndPoint);
Console.WriteLine("Failed : " + e.Message);
}
}
static void Main(string[] args)
{
RestClient me = new RestClient();
string endPointPrefix = #"http://localhost:8000/";
me.TalkTo(
HttpVerb.POST,
endPointPrefix + "data",
"",
"<Hidden><id>xml works</id></Hidden>");
string post = "{\"id\":\"json works\"}";
Console.WriteLine("Json string is [" + post + "]");
me.TalkTo(
HttpVerb.POST,
endPointPrefix + "data",
"",
post);
Console.WriteLine("Press <Enter> to terminate");
Console.ReadLine();
}
}
}
On the client side, I'm getting
Content type is text/xml
Endpoint: http://localhost:8000/data
Resp : <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">DataPost said xml works</string>
Json string is [{"id":"json works"}]
Content type is application/json
Endpoint: http://localhost:8000/data
Failed : The remote server returned an error: (400) Bad Request.
Press <Enter> to terminate
When I look at the help, it says that JSON format is allowable but when I try it, it falls over. The trace from the sever debug seems to imply that it is ignoring the application/json and just assuming that everything is xml.
Exception: System.Runtime.Serialization.SerializationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message: There was an error checking start element of object of type System.String. The data at the root level is invalid. Line 1, position 1.
Last few lines of stack trace
System.Runtime.Serialization.XmlObjectSerializer.IsStartObjectHandleExceptions(XmlReaderDelegator reader)
System.Runtime.Serialization.DataContractSerializer.IsStartObject(XmlDictionaryReader reader)
System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.ReadObject(Message message)
All the examples I've looked at on SO and other sites don't add anything special so is it not working because I'm using the VS2013 express?
EDIT It also happens on VS2013 Web Express
EDIT2 Doesn't look like it is isolated to express versions - I've just tried it on VS2010 Professional. It is still using the XMLObjectSerializer to parse JSON and failing miserably.
The fix is to no convert the PostData to bytes
if (!string.IsNullOrEmpty(PostData) && Method == HttpVerb.POST)
{
if (PostData.Substring(0, 1) != "<")
request.ContentType = "application/json";
Console.WriteLine("Content type is " + request.ContentType.ToString());
request.ContentLength = PostData.Length;
using (var postStream = new StreamWriter(request.GetRequestStream()))
{
postStream.Write(PostData);
}
}

How to send Android push notifications via GCM on C# .Net

I'm new to all Android GCM push notifications and I have read stack posts but couldn't get a straight answer.I have also read Create push notification in android to get a better understanding of how GCM works. I have also used the gcm-demo-server and gcm-demo-client provided by the SDK. However, here are my doubts and what I have tried so far:
Regarding the link I have put, the phone which has the app registers to get the registration key. Is this a unique key for all phones which uses the same app?
Does this registration key expires in any case? (E.g. App running on background)
Assuming that I have the registration key, I have tried the following code snippet to push notification via GCM to my app. This is written on c# .net. Please let me know whether what I have mentioned above can be achieved using the following code snippet:
private string SendGCMNotification(string apiKey, string postData, string postDataContentType = "application/json")
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
// MESSAGE CONTENT
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// CREATE REQUEST
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
Request.Method = "POST";
Request.KeepAlive = false;
Request.ContentType = postDataContentType;
Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
Request.ContentLength = byteArray.Length;
Stream dataStream = Request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
// SEND MESSAGE
try
{
WebResponse Response = Request.GetResponse();
HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
{
var text = "Unauthorized - need new token";
}
else if (!ResponseCode.Equals(HttpStatusCode.OK))
{
var text = "Response from web service isn't OK";
}
StreamReader Reader = new StreamReader(Response.GetResponseStream());
string responseLine = Reader.ReadToEnd();
Reader.Close();
return responseLine;
}
catch (Exception e)
{
}
return "error";
}
Is there a direct way of sending push notifications without the phone first being registered in our custom server?
Refer Code:
public class AndroidGCMPushNotification
{
public AndroidGCMPushNotification()
{
//
// TODO: Add constructor logic here
//
}
public string SendNotification(string deviceId, string message)
{
string SERVER_API_KEY = "server api key";
var SENDER_ID = "application number";
var value = message;
WebRequest tRequest;
tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
tRequest.Method = "post";
tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));
tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse tResponse = tRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();
tReader.Close();
dataStream.Close();
tResponse.Close();
return sResponseFromServer;
}
}
Referance Link:
http://www.codeproject.com/Tips/434338/Android-GCM-Push-Notification
Code looks bit long but it works. I just sent a push notification to my phone after struggling 2 days by implementing the following code in C# project. I referred a link regarding this implementation, But couldn't find it to post here. So will share my code with you. If you want to test the Notification online you may visit to this link.
note : I have hardcorded apiKey, deviceId and postData, please pass
the apiKey,deviceId and postData in your request and remove them from
the method body. If you want pass message string also
public string SendGCMNotification(string apiKey, string deviceId, string postData)
{
string postDataContentType = "application/json";
apiKey = "AIzaSyC13...PhtPvBj1Blihv_J4"; // hardcorded
deviceId = "da5azdfZ0hc:APA91bGM...t8uH"; // hardcorded
string message = "Your text";
string tickerText = "example test GCM";
string contentTitle = "content title GCM";
postData =
"{ \"registration_ids\": [ \"" + deviceId + "\" ], " +
"\"data\": {\"tickerText\":\"" + tickerText + "\", " +
"\"contentTitle\":\"" + contentTitle + "\", " +
"\"message\": \"" + message + "\"}}";
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
//
// MESSAGE CONTENT
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
//
// CREATE REQUEST
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
Request.Method = "POST";
Request.KeepAlive = false;
Request.ContentType = postDataContentType;
Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
Request.ContentLength = byteArray.Length;
Stream dataStream = Request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
//
// SEND MESSAGE
try
{
WebResponse Response = Request.GetResponse();
HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
{
var text = "Unauthorized - need new token";
}
else if (!ResponseCode.Equals(HttpStatusCode.OK))
{
var text = "Response from web service isn't OK";
}
StreamReader Reader = new StreamReader(Response.GetResponseStream());
string responseLine = Reader.ReadToEnd();
Reader.Close();
return responseLine;
}
catch (Exception e)
{
}
return "error";
}
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
return true;
}
You may not familiar with words like apiKey, deviceId. Dont worry i will explain what are they and how to create those.
apiKey What & why :This a key that will be used when sending requests to GCM server. How to create : Refer this post
deviceId What & why : This id also known as RegistrationId. This is a unique id to identify the device. When you want to send a
notification to a specific device you need this id. How to
create: This depends on how you implement the application. For cordova
i used a simple pushNotification Plugin You can simply create a
deviceId/RegistrationId using this plugin. To do that you need to have
a senderId. Google how to create a senderId it is really simple =)
If anyone needs some help leave a comment.
Happy Coding.
-Charitha-
Just for the information for new visitors on this post, if you want to send same message to multiple devices then simply send comma separated device ids in registration_id parameter of request.
Here is a nice article on this
http://www.codewithasp.net/2015/11/send-message-gcm-c-sharp-single-multiple.html
This never worked for me and it is hard to debug plus passing a list of registration token is not clear -would expect passing a string array instead of comma separated string - , the fact that this is very simple post request i created my own class with a method that return the server response, and it works very well:
Usage
//Registration Token
string[] registrationIds ={"diks4vp5......","erPjEb9....."};
AndroidGcmPushNotification gcmPushNotification = new
AndroidGcmPushNotification(
"API KEY", registrationIds, "Hello World"
);
gcmPushNotification.SendGcmNotification();
Class
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
public class AndroidGcmPushNotification
{
private readonly string _apiAccessKey;
private readonly string[] _registrationIds;
private readonly string _message;
private readonly string _title;
private readonly string _subtitle;
private readonly string _tickerText;
private readonly bool _vibrate;
private readonly bool _sound;
public AndroidGcmPushNotification(string apiAccessKey, string[] registrationIds, string message, string title = "",
string subtitle = "", string tickerText = "", bool vibrate = true, bool sound = true )
{
_apiAccessKey = apiAccessKey;
_registrationIds = registrationIds;
_message = message;
_title = title;
_subtitle = subtitle;
_tickerText = tickerText;
_vibrate = vibrate;
_sound = sound;
}
public string SendGcmNotification()
{
//MESSAGE DATA
GcmPostData data = new GcmPostData()
{
message = _message,
title = _title,
subtitle = _subtitle,
tickerText = _tickerText,
vibrate = _vibrate,
sound = _sound
};
//MESSAGE FIELDS
GcmPostFields fields = new GcmPostFields();
fields.registration_ids = _registrationIds;
fields.data = data;
//SERIALIZE TO JSON
JavaScriptSerializer jsonEncode = new JavaScriptSerializer();
//CONTENTS
byte[] byteArray = Encoding.UTF8.GetBytes(jsonEncode.Serialize(fields));
//REQUEST
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
request.Method = "POST";
request.KeepAlive = false;
request.ContentType = "application/json";
request.Headers.Add($"Authorization: key={_apiAccessKey}");
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
//SEND REQUEST
try
{
WebResponse response = request.GetResponse();
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseLine = reader.ReadToEnd();
reader.Close();
return responseLine;
}
}
catch (Exception e)
{
return e.Message;
}
}
private class GcmPostFields
{
public string[] registration_ids { get; set; }
public GcmPostData data { get; set; }
}
private class GcmPostData
{
public string message { get; set; }
public string title { get; set; }
public string subtitle { get; set; }
public string tickerText { get; set; }
public bool vibrate { get; set; }
public bool sound { get; set; }
}
}
There is package PushSharp.
Allows to communicate with almost every popular notification api.
Example code:
// Configuration
var config = new GcmConfiguration ("GCM-SENDER-ID", "AUTH-TOKEN", null);
// Create a new broker
var gcmBroker = new GcmServiceBroker (config);
// Wire up events
gcmBroker.OnNotificationFailed += (notification, aggregateEx) => {
aggregateEx.Handle (ex => {
// See what kind of exception it was to further diagnose
if (ex is GcmNotificationException) {
var notificationException = (GcmNotificationException)ex;
// Deal with the failed notification
var gcmNotification = notificationException.Notification;
var description = notificationException.Description;
Console.WriteLine ($"GCM Notification Failed: ID={gcmNotification.MessageId}, Desc={description}");
} else if (ex is GcmMulticastResultException) {
var multicastException = (GcmMulticastResultException)ex;
foreach (var succeededNotification in multicastException.Succeeded) {
Console.WriteLine ($"GCM Notification Failed: ID={succeededNotification.MessageId}");
}
foreach (var failedKvp in multicastException.Failed) {
var n = failedKvp.Key;
var e = failedKvp.Value;
Console.WriteLine ($"GCM Notification Failed: ID={n.MessageId}, Desc={e.Description}");
}
} else if (ex is DeviceSubscriptionExpiredException) {
var expiredException = (DeviceSubscriptionExpiredException)ex;
var oldId = expiredException.OldSubscriptionId;
var newId = expiredException.NewSubscriptionId;
Console.WriteLine ($"Device RegistrationId Expired: {oldId}");
if (!string.IsNullOrWhitespace (newId)) {
// If this value isn't null, our subscription changed and we should update our database
Console.WriteLine ($"Device RegistrationId Changed To: {newId}");
}
} else if (ex is RetryAfterException) {
var retryException = (RetryAfterException)ex;
// If you get rate limited, you should stop sending messages until after the RetryAfterUtc date
Console.WriteLine ($"GCM Rate Limited, don't send more until after {retryException.RetryAfterUtc}");
} else {
Console.WriteLine ("GCM Notification Failed for some unknown reason");
}
// Mark it as handled
return true;
});
};
gcmBroker.OnNotificationSucceeded += (notification) => {
Console.WriteLine ("GCM Notification Sent!");
};
// Start the broker
gcmBroker.Start ();
foreach (var regId in MY_REGISTRATION_IDS) {
// Queue a notification to send
gcmBroker.QueueNotification (new GcmNotification {
RegistrationIds = new List<string> {
regId
},
Data = JObject.Parse ("{ \"somekey\" : \"somevalue\" }")
});
}
// Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
gcmBroker.Stop ();
I have worked with Android Applications and IOS application using Firebase's FCM.
This code is working .Middle layer is ASP.NET API.You start a project in visual studio and select API.To be create a controller.Your server_api_key and sender id adding Web.config file.
Adding user fcm server_api_key and sender id.
<appSettings>
<add key="SERVER_API_KEY" value=""/>
<add key="SENDER_ID" value=""/>
</appSettings>
The below code to add your controller
using System;
using System.Net;
using System.Web.Http;
using System.Web.Script.Serialization;
using System.Configuration;
using System.IO;
namespace pushios.Controllers
{
public class HomeController : ApiController
{
[HttpGet]
[Route("sendmessage")]
public IHttpActionResult SendMessage()
{
var data = new {
to = "Device Token",
data = new
{
//To be adding your json data
body="Test",
confId= "",
pageTitle= "test",
pageFormat= "",
dataValue= "",
title= "C#",
webviewURL= "",
priority = "high",
notificationBlastID = "0",
status = true
}
};
SendNotification(data);
return Ok();
}
public void SendNotification(object data)
{
var Serializer = new JavaScriptSerializer();
var json = Serializer.Serialize(data);
Byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);
SendNotification(byteArray);
}
public void SendNotification(Byte[] byteArray)
{
try
{
String server_api_key = ConfigurationManager.AppSettings["SERVER_API_KEY"];
String senderid = ConfigurationManager.AppSettings["SENDER_ID"];
WebRequest type = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
type.Method = "post";
type.ContentType = "application/json";
type.Headers.Add($"Authorization: key={server_api_key}");
type.Headers.Add($"Sender: id={senderid}");
type.ContentLength = byteArray.Length;
Stream datastream = type.GetRequestStream();
datastream.Write(byteArray, 0, byteArray.Length);
datastream.Close();
WebResponse respones = type.GetResponse();
datastream = respones.GetResponseStream();
StreamReader reader = new StreamReader(datastream);
String sresponessrever = reader.ReadToEnd();
reader.Close();
datastream.Close();
respones.Close();
}
catch (Exception)
{
throw;
}
}
}
}

How to post data to specific URL using WebClient in C#

I need to use "HTTP Post" with WebClient to post some data to a specific URL I have.
Now, I know this can be accomplished with WebRequest but for some reasons I want to use WebClient instead. Is that possible? If so, can someone show me some example or point me to the right direction?
I just found the solution and yea it was easier than I thought :)
so here is the solution:
string URI = "http://www.myurl.com/post.php";
string myParameters = "param1=value1&param2=value2&param3=value3";
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
}
it works like charm :)
There is a built in method called UploadValues that can send HTTP POST (or any kind of HTTP methods) AND handles the construction of request body (concatenating parameters with "&" and escaping characters by url encoding) in proper form data format:
using(WebClient client = new WebClient())
{
var reqparm = new System.Collections.Specialized.NameValueCollection();
reqparm.Add("param1", "<any> kinds & of = ? strings");
reqparm.Add("param2", "escaping is already handled");
byte[] responsebytes = client.UploadValues("http://localhost", "POST", reqparm);
string responsebody = Encoding.UTF8.GetString(responsebytes);
}
Using WebClient.UploadString or WebClient.UploadData you can POST data to the server easily. I’ll show an example using UploadData, since UploadString is used in the same manner as DownloadString.
byte[] bret = client.UploadData("http://www.website.com/post.php", "POST",
System.Text.Encoding.ASCII.GetBytes("field1=value1&field2=value2") );
string sret = System.Text.Encoding.ASCII.GetString(bret);
More: http://www.daveamenta.com/2008-05/c-webclient-usage/
string URI = "site.com/mail.php";
using (WebClient client = new WebClient())
{
System.Collections.Specialized.NameValueCollection postData =
new System.Collections.Specialized.NameValueCollection()
{
{ "to", emailTo },
{ "subject", currentSubject },
{ "body", currentBody }
};
string pagesource = Encoding.UTF8.GetString(client.UploadValues(URI, postData));
}
//Making a POST request using WebClient.
Function()
{
WebClient wc = new WebClient();
var URI = new Uri("http://your_uri_goes_here");
//If any encoding is needed.
wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
//Or any other encoding type.
//If any key needed
wc.Headers["KEY"] = "Your_Key_Goes_Here";
wc.UploadStringCompleted +=
new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
wc.UploadStringAsync(URI,"POST","Data_To_Be_sent");
}
void wc__UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
MessageBox.Show(e.Result);
//e.result fetches you the response against your POST request.
}
catch(Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
Using simple client.UploadString(adress, content); normally works fine but I think it should be remembered that a WebException will be thrown if not a HTTP successful status code is returned. I usually handle it like this to print any exception message the remote server is returning:
try
{
postResult = client.UploadString(address, content);
}
catch (WebException ex)
{
String responseFromServer = ex.Message.ToString() + " ";
if (ex.Response != null)
{
using (WebResponse response = ex.Response)
{
Stream dataRs = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataRs))
{
responseFromServer += reader.ReadToEnd();
_log.Error("Server Response: " + responseFromServer);
}
}
}
throw;
}
Using webapiclient with model send serialize json parameter request.
PostModel.cs
public string Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
WebApiClient.cs
internal class WebApiClient : IDisposable
{
private bool _isDispose;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (!_isDispose)
{
if (disposing)
{
}
}
_isDispose = true;
}
private void SetHeaderParameters(WebClient client)
{
client.Headers.Clear();
client.Headers.Add("Content-Type", "application/json");
client.Encoding = Encoding.UTF8;
}
public async Task<T> PostJsonWithModelAsync<T>(string address, string data,)
{
using (var client = new WebClient())
{
SetHeaderParameters(client);
string result = await client.UploadStringTaskAsync(address, data); // method:
//The HTTP method used to send the file to the resource. If null, the default is POST
return JsonConvert.DeserializeObject<T>(result);
}
}
}
Business caller method
public async Task<ResultDTO> GetResultAsync(PostModel model)
{
try
{
using (var client = new WebApiClient())
{
var serializeModel= JsonConvert.SerializeObject(model);// using Newtonsoft.Json;
var response = await client.PostJsonWithModelAsync<ResultDTO>("http://www.website.com/api/create", serializeModel);
return response;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
Most of the answers are old. Just wanted to share what worked for me. In the interest of doing things asynchronously i.e. to post data to specific URL using WebClient asynchronously in .NET 6.0 Preview 7, .NET Core and other versions can be done using WebClient.UploadStringTaskAsync Method.
Use namespace System.Net; and for a class ResponseType to capture the response from the server, we can use this method to POST data to a specific URL. Make sure to use the await keyword while calling this method
public async Task<ResponseType> MyAsyncServiceCall()
{
try
{
var uri = new Uri("http://your_uri");
var body= "param1=value1&param2=value2&param3=value3";
using (var wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Authorization] = "yourKey"; // Can be Bearer token, API Key etc.....
wc.Headers[HttpRequestHeader.ContentType] = "application/json"; // Is about the payload/content of the current request or response. Do not use it if the request doesn't have a payload/ body.
wc.Headers[HttpRequestHeader.Accept] = "application/json"; // Tells the server the kind of response the client will accept.
wc.Headers[HttpRequestHeader.UserAgent] = "PostmanRuntime/7.28.3";
string result = await wc.UploadStringTaskAsync(uri, body);
return JsonConvert.DeserializeObject<ResponseType>(result);
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
Here is the crisp answer:
public String sendSMS(String phone, String token) {
WebClient webClient = WebClient.create(smsServiceUrl);
SMSRequest smsRequest = new SMSRequest();
smsRequest.setMessage(token);
smsRequest.setPhoneNo(phone);
smsRequest.setTokenId(smsServiceTokenId);
Mono<String> response = webClient.post()
.uri(smsServiceEndpoint)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(Mono.just(smsRequest), SMSRequest.class)
.retrieve().bodyToMono(String.class);
String deliveryResponse = response.block();
if (deliveryResponse.equalsIgnoreCase("success")) {
return deliveryResponse;
}
return null;
}

Categories

Resources