SignalR service: Get message depending on user role - javascript

I created
MVC app (installed -Install-Package Microsoft.AspNet.SignalR.JS) (ref here)
Web Service
(//Install from Nuget Package window
//Install-Package Microsoft ASP.NET SignalR .NET Client
//Install-Package Microsoft ASP.NET SignalR Core Components)
Signalr Service (Installed -Install-Package Microsoft.AspNet.SignalR.SelfHost and Install-Package Microsoft.Owin.Cors)
What I am doing: I am calling MVC page and after processing one task using web service. In that web service when task is processing I want to notify user what is going on behind the seen like task is in processing or it is done using Signalr service.
I created All project separately.
using web Service I am calling the signalr hubs (see here)
challenges facing:
I want to broadcast the message to that user and if no. of user are there then depending on there role i want to send messages.
Edited:Extra Enhancement added in my project:I have no. of MVC app and its corresponding Web services and My single signalR service so how can I identify which MVC app calling it corresponding service and service pushing to all or it application users or particular user. Like pusher will create application Id to application and number of tokens for user. It is possible to do it.

Summary:
I'm not sure that it's possible to have the hubs living on the WCF SignalR service. It would be best to let the MVC project act as a proxy between the client and web service. You can connect to SignalR later with other clients (such as desktop clients) if that's one of your requirements, and also connect to this hub from your web service to send updates to the clients and/or users in a specified group.
Workflow:
To start, the flow would look more like this:
Managing Client Connections:
If you are using an in-memory approach to managing your connected users, then you could start by adding the connection id and the user id to whatever collection you are using to handle this. For example:
public static ConcurrentDictionary<String, String> UsersOnline = new ConcurrentDictionary<String, String>();
public override System.Threading.Tasks.Task OnConnected()
{
UsersOnline.TryAdd(Context.ConnectionId, Context.User.Identity.GetUserId());
return base.OnConnected();
}
A word of caution: The Context.User will be null unless you map SignalR after the authentication.
It may be beneficial to store the connection id in variable on the client side as well so you can pass it to your methods later.
var connectionId;
var testHub = $.connection.testHub;
$.connection.hub.start().done(function () {
connectionId = $.connection.hub.id;
}
The Hub:
The hub can be used to communicate with the web service. In this example I'll be using it as a soap service, but rest should work just the same.
public void LongRunningTask(String ConnectionId)
{
using (var svc = new Services.MyWebService.SignalRTestServiceClient())
{
svc.LongRunningTask(ConnectionId);
} // end using
} // end LongRunningTask
Note that we pass the connection id to the service as well. This comes into play when the service starts sending messages back to the MVC project to deliver to the client(s).
Listener or Web API:
Set up a listener controller or a Web API on the MVC site to receive messages from the web service.
public ActionResult SignalR(String Message, String Type, String ConnectionId)
{
if (!String.IsNullOrWhiteSpace(Message) && !String.IsNullOrWhiteSpace(Type) && !String.IsNullOrWhiteSpace(ConnectionId))
{
if (Type == "ShowAlert")
{
// Determine if the user that started the process is still online
bool UserIsOnline = Hubs.TestHub.UsersOnline.ContainsKey(ConnectionId);
// We need this to execute our client methods
IHubContext TestHub = GlobalHost.ConnectionManager.GetHubContext<Hubs.TestHub>();
if (UserIsOnline)
{
// Show the alert to only the client that started the process.
TestHub.Clients.Client(ConnectionId).showAlert(Message);
} // end if
else
{
List<String> UserIdsInRole = new List<String>();
using (var connection = new System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString()))
{
// Assuming you're using Identity framework since it is an MVC project, get all the ids for users in a given role.
// This is using Dapper
UserIdsInRole = connection.Query<String>(#"
SELECT ur.UserId
FROM AspNetUserRoles ur
JOIN AspNetRoles r ON ur.RoleId = r.Id
WHERE r.Name = #rolename
", new { rolename = "SpecialRole" }).ToList();
} // end using
// Find what users from that role are currently connected
List<String> ActiveUsersInRoleConnectionIds = Hubs.TestHub.UsersOnline.Where(x => UserIdsInRole.Contains(x.Value)).Select(y => y.Key).ToList();
// Send the message to the users in that role who are currently connected
TestHub.Clients.Clients(ActiveUsersInRoleConnectionIds).showAlert(Message);
} // end else (user is not online)
} // end if type show alert
} // end if nothing is null or whitespace
return new HttpStatusCodeResult(200);
} // end SignalR
Web Service:
The web service method that does the long running work should accept a client id as well, so it can send it back to the listener controller or web API. It can use a method similar to this (using RestSharp) to connect back to the MVC project:
public void ShowAlert(String Message, String ConnectionId)
{
RestClient Client = new RestClient("http://localhost:8888");
RestRequest Request = new RestRequest("/Listener/SignalR", Method.POST);
Request.Parameters.Add(new Parameter() { Name = "Message", Type = ParameterType.QueryString, Value = Message });
Request.Parameters.Add(new Parameter() { Name = "Type", Type = ParameterType.QueryString, Value = "ShowAlert" });
Request.Parameters.Add(new Parameter() { Name = "ConnectionId", Type = ParameterType.QueryString, Value = ConnectionId });
IRestResponse Response = Client.Execute(Request);
} // end Show Alert
Demo:
I did a proof of concept and uploaded it to Github.

Related

Best way to send notification through FCM if I have array of token [duplicate]

I execute this code to push notifications to mobile device using FCM library
public string PushFCMNotification(string deviceId, string message)
{
string SERVER_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxx";
var SENDER_ID = "xxxxxxxxx";
var value = message;
WebRequest tRequest;
tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));
tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
var data = new
{
to = deviceId,
notification = new
{
body = "This is the message",
title = "This is the title",
icon = "myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
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;
}
now, how to send message to multi device,
assume that string deviceId parameter replaced with List devicesIDs.
can you help
Update: For v1, it seems that registration_ids is no longer supported. It is strongly suggested that topics be used instead. Only the parameters shown in the documentation are supported for v1.
Simply use the registration_ids parameter instead of to in your payload. Depending also on your use case, you may use either Topic Messaging or Device Group Messaging.
Topic Messaging
Firebase Cloud Messaging (FCM) topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. Based on the publish/subscribe model, topic messaging supports unlimited subscriptions for each app. You compose topic messages as needed, and Firebase handles message routing and delivering the message reliably to the right devices.
For example, users of a local weather forecasting app could opt in to a "severe weather alerts" topic and receive notifications of storms threatening specified areas. Users of a sports app could subscribe to automatic updates in live game scores for their favorite teams. Developers can choose any topic name that matches the regular expression: "/topics/[a-zA-Z0-9-_.~%]+".
Device Group Messaging
With device group messaging, app servers can send a single message to multiple instances of an app running on devices belonging to a group. Typically, "group" refers a set of different devices that belong to a single user. All devices in a group share a common notification key, which is the token that FCM uses to fan out messages to all devices in the group.
Device group messaging makes it possible for every app instance in a group to reflect the latest messaging state. In addition to sending messages downstream to a notification key, you can enable devices to send upstream messages to a device group. You can use device group messaging with either the XMPP or HTTP connection server. The limit on data payload is 2KB when sending to iOS devices, and 4KB for other platforms.
The maximum number of members allowed for a notification_key is 20.
For more details, you can check out the Sending to Multiple Devices in FCM docs.
You should create a Topic and let users subscribe to that topic.
That way, when you send an FCM message, every user subscribed gets it, except you actually want to keep record of their Id's for special purposes.
FirebaseMessaging.getInstance().subscribeToTopic("news");
See this link: https://firebase.google.com/docs/cloud-messaging/android/topic-messaging
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
"to": "/topics/news",
"data": {
"message": "This is a Firebase Cloud Messaging Topic Message!",
}
}
Please follow these steps.
public String addNotificationKey(
String senderId, String userEmail, String registrationId, String idToken)
throws IOException, JSONException {
URL url = new URL("https://android.googleapis.com/gcm/googlenotification");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
// HTTP request header
con.setRequestProperty("project_id", senderId);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");
con.connect();
// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "add");
data.put("notification_key_name", userEmail);
data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
data.put("id_token", idToken);
OutputStream os = con.getOutputStream();
os.write(data.toString().getBytes("UTF-8"));
os.close();
// Read the response into a string
InputStream is = con.getInputStream();
String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next();
is.close();
// Parse the JSON string and return the notification key
JSONObject response = new JSONObject(responseString);
return response.getString("notification_key");
}
I hope the above code will help you to send push on multiple devices.
For more detail please refer this link https://firebase.google.com/docs/cloud-messaging/android/device-group
***Note : Please must read the about creating/removing group by the above link.
A word of caution mentioned in FCM DOcument which is as follows,
Caution: Any apps that use device group messaging must continue to use the legacy API for the management of device groups (creating, updating, etc.). The HTTP v1 can send messages to device groups, but does not support management.
https://firebase.google.com/docs/cloud-messaging/migrate-v1
Also the Admin SDK's uses a Batch HttpPostrequest to make it easy for consumers, so if you want Device Group messaging you could still uses the New V1 FCM API, but using FCM Admin SDK.
Here is the code from Admin SDK which does this job for you.
Class Name: FirebaseMessagingClientImpl
for (Message message : messages) {
// Using a separate request factory without authorization is faster for large batches.
// A simple performance test showed a 400-500ms speed up for batches of 1000 messages.
HttpRequest request = childRequestFactory.buildPostRequest(
sendUrl,
new JsonHttpContent(jsonFactory, message.wrapForTransport(dryRun)));
request.setParser(jsonParser);
setCommonFcmHeaders(request.getHeaders());
batch.queue(
request, MessagingServiceResponse.class, MessagingServiceErrorResponse.class, callback);
}

Display a document without authentification

I am currently developping a java/jee application using alfresco as ged and spring as a framework.I want to display a file in the navigator without authentification requirment.So how can i do that.By the way i have 2 modules in my project:Frontend and backend which are communicating via rest calls.From the backend i tried to pass the byte array of the object but unfortunately i recieved it as string so i can't work with it.So any suggestion to solve this issue?
public Map<String, Object> getCourrierDetails(String idCourrier) throws Exception {
Map<String, Object> courriersDetails = runtimeService.getVariables(idCourrier);
courriersDetails.put("idCourrier", idCourrier);
DocumentDaoImpl dao=new DocumentDaoImpl();
Document docCmis = (Document) dao.getDocument("workspace://SpacesStore/73871a36-9a6c-42c6-b3e3-7d68362fe9c0");
byte[] myByteArray = readContent(docCmis.getContentStream().getStream());
ByteArrayResource resource = new ByteArrayResource(myByteArray) {
#Override
public String getFilename() {
return docCmis.getContentStreamFileName();
}
};
System.out.println(resource.getFilename());
//courriersDetails.put("resources", myByteArray);
System.out.println(courriersDetails.get("resources")+" rrrr");
//courriersDetails.put("contentStream",docCmis.getContentStream().getStream());
return courriersDetails;
}
Assuming your front-end and back-end are custom and your back-end communicates with Alfresco, all you need to do is write a proxy that resides in your back-end.
The proxy can establish a session with Alfresco using a pre-configured "service account" that has access to the content. In this way, the person using your custom webapp does not use their own credentials to get the object from Alfresco. Instead, the service account is used and the web app streams that to the requester.
For example, in one of my projects I have an AssetService that uses CMIS to get the InputStream from content given its ID:
public InputStream download(String assetId) {
CmisObject obj = session.getObject(assetId);
Document doc = null;
if (obj.getBaseTypeId().equals(BaseTypeId.CMIS_DOCUMENT)) {
doc = (Document) obj;
}
return doc.getContentStream().getStream();
}
Then, my Controller just asks the service for the asset to get some info about it to make it easy to set some helpful headers, then it gets the input stream from the asset service and returns that:
#RequestMapping(value = "/api/asset/{assetId:.+}/download/{name}", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> downloadAsset(
#PathVariable("assetId") String assetId,
#PathVariable("name") String name) {
// get the asset so we can get some info about it
Asset asset = assetService.getAsset(assetId);
// set the http headers (mimetype and length at a minimum)
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.parseMediaType(asset.getMimetype()));
httpHeaders.setContentLength(asset.getLength());
// get the content stream
InputStream inputStream = assetService.download(assetId);
InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
return new ResponseEntity<InputStreamResource>(inputStreamResource, httpHeaders, HttpStatus.OK);
}
This example uses Spring MVC within a Spring Boot app but of course you could do something similar with a plain old servlet if you want.
One option is to write your own web script and set it up in a way that it allows guest access.
http://docs.alfresco.com/4.1/concepts/ws-authenticating.html
There's also an option to completely disable permission checking, which I have never tried, though.
https://community.alfresco.com/thread/175381-disabling-permission-checking

how to call Hub or Client Method in One Signal R app1 from another One Signal R app2

hi i have two signalR applications and i need to call Hub method or Client side method present in SignalR app1 from SignalR2 app, i am using GlobalHost.ConnectionManager.GetHubContext for accessing ChatHubIn which present SignalR2 app:
public class ChatHub : Hub
{
public void SendToOtherApp(string name, string message, string Id)
{
var context = GlobalHost.ConnectionManager.GetHubContext("ChatHubIn");
context.Clients.All.addNewMessageToPage(name,message);
}
}
but i am getting error ChatHubIn Hub could not be resolved what is this ?? why it is coming ?? any way solve this problem or any other way to call Hub method or Client from other application.
Edited:
public class ChatHubIn : Hub
{
public void SendToSameApp(string name, string message, string Id) //, string c_id
{
Clients.All.addNewMessageToPage(name, message);
}
}
see i have two separate applications SignalR1 app, SignalR2 app as i told and every body knows two apps willl have two separate client , hub parts here i need to call ChatHubIn Hub present in SignalR2 app from Hub part of SignalR1 app and from there i need to send messages to all clients in SignalR2 app
I cannot give you the exact answer to your problem because the short snippet of code and explanation is less than informative but what I have done is reproduced the whole solution in which I had no problems.
Just to clarify the issue:
see i have two separate applications SignalR1 app, SignalR2 app as i
told and every body knows two apps willl have two separate client ,
hub parts here i need to call ChatHubIn Hub present in SignalR2 app
from Hub part of SignalR1 app and from there i need to send messages
to all clients in SignalR2 app
It's hard to digest the above, So what I have done is create two projects; one webform (SignalR1 which essentially the server/host) and one MVC (SignalR2 the client)
None of this was terribly difficult, The webform project I installed the full stack of signalR, I wanted it to be the server as such.
Within the MVC project I installed the SignalR JS client and the SignalR .Net client thus giving me the ability to connect to the host.
Most Importantly install/enable Cors which needs to be installed on the host:
Install-Package Microsoft.AspNet.Cors -Version 5.2.3
Allowing cors in the startup class:
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});
}
Not only can the MVC project receive messages, I now have the ability to fire a method on the Hub
Connecting to a host:
<script src="~/Scripts/jquery-1.6.4.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
<script src="http://localhost:45569/signalr/hubs"></script>
<script>
$(document).ready(function () {
var chatHub = $.connection.chatHub;
$.connection.hub.url = "http://localhost:45569/signalr";
// Declare a function on the chat hub so the server can invoke it
// Create a function that the hub can call to broadcast messages.
chatHub.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
$.connection.hub.start(function () {
//We can also fire back :-) Happy days
});
});
</script>
We can do this in C# too!:
var hubConnection = new HubConnection("http://localhost:45569/");
IHubProxy chatHubProxy = hubConnection.CreateHubProxy("chatHub");
hubConnection.Start().Wait();
chatHubProxy .Invoke("Send", "name", "message");
Now if I install the full package of SignalR on the MVC, I could call my Hub to call another:
public class OtherChatHub : Hub
{
public void Send(string name, string message)
{
var hubConnection = new HubConnection("http://localhost:45569/");
IHubProxy chatHubProxy = hubConnection.CreateHubProxy("chatHub");
hubConnection.Start().Wait();
chatHubProxy .Invoke("Send", "name", "message");
}
}
//EDIT
Due to the level of code required, to get a minimal sln working is too much for this Q. So I decided to add to GitHub for you to download and learn not just use the exact code.
SignalRTwoWay-GitHub
You need to provide more info what code is involved in order to help resolve this issue.
Please note that the two hubs have to be hosted on the same machine. If you want to address another hub in a different machine or hosting environment then have one hub act as a client to the other hub.
Edit upon question edit:
Just one more thing that got my attention: Based on the infos provided, that the Hub name cannot be resolved: Try to resolve the hub by calling
var context = GlobalHost.ConnectionManager.GetHubContext<ChatHubIn>();
to debug possible naming issues that could occur when resolving the hub by name.
I'm still in doubt, that you can get hold of the hub context over process boundaries. If that's not possible then the cleanest approach would be to have on hub act additionally as a hub client to the other hub, which provides a specialized method to receive the notification and then broadcast it to its clients.

Invoke signalr hub method from one app and receive in javascript in another app

I'm very curious and very much in need of some pointers.
Basically I have a web application that invokes a hub method in .NET (c#)
var hubConnection = new HubConnection("http://domain/signalr");
IHubProxy applicationHubProxy = hubConnection.CreateHubProxy("ApplicationHub");
hubConnection.Start().Wait();
applicationHubProxy.Invoke("JoinGroup", appKey).Wait();
And ideally if a client (another application hosted else where) has a connection to the hub then receive the message in js.
var connection = $.hubConnection();
connection.url = "http://domain/signalr";
// Declare a proxy to reference the hub.
var applicationHub = connection.createHubProxy('ApplicationHub');
//mock is just a dynamic type that recieves the message in the join group hub method
applicationHub.on('mock', function (msg)
{
alert(msg);
});
Please note that I'm already using Cors, and singalr is working fine with Tests. As I begin with the production code, I'm hoping I could get a better understanding of how the above is going to work.
So just to reiterate, how do I receive a response in JavaScript that is sent from another app in c#?
Any help greatly appreciated,

Creating a YouTube Service via ASP.NET using a pre-existing Access Token

I've been working on a Website for users to upload videos to a shared YouTube account for later access. After much work I've been able to get an Active Token, and viable Refresh Token.
However, the code to initialize the YouTubeService object looks like this:
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows an application to upload files to the
// authenticated user's YouTube channel, but doesn't allow other types of access.
new[] { YouTubeService.Scope.YoutubeUpload },
"user",
CancellationToken.None
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = Assembly.GetExecutingAssembly().GetName().Name,
});
I've already got a token, and I want to use mine. I'm using ASP.NET version 3.5, and so I can't do an async call anyways.
Is there any way I can create a YouTubeService object without the async call, and using my own token? Is there a way I can build a credential object without the Authorization Broker?
Alternatively, the application used YouTube API V2 for quite some time, and had a form that took a token, and did a post action against a YouTube URI that was generated alongside the token in API V2. Is there a way I can implement that with V3? Is there a way to use Javascript to upload videos, and possibly an example that I could use in my code?
NOTE: I ended up upgrading my Framework to 4.5 to access the google libraries.
To programatically initialize a UserCredential Object you've got to build a Flow, and TokenResponse. A Flow Requires a Scope (aka the permissions we are seeking for the credentials.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Auth.OAuth2.Flows;
string[] scopes = new string[] {
YouTubeService.Scope.Youtube,
YouTubeService.Scope.YoutubeUpload
};
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = XXXXXXXXXX, <- Put your own values here
ClientSecret = XXXXXXXXXX <- Put your own values here
},
Scopes = scopes,
DataStore = new FileDataStore("Store")
});
TokenResponse token = new TokenResponse {
AccessToken = lblActiveToken.Text,
RefreshToken = lblRefreshToken.Text
};
UserCredential credential = new UserCredential(flow, Environment.UserName, token);
Hope that helps.
Currently the official Google .NET client library does not work with .NET Framework 3.5. (Note: this is an old question the library hasn't supported .NET 3.5 since 2014. So the statement would have been valid then as well.) That being said you are not going to be able to create a service for the Google .NET client library using an existing access token. Also not possible to create it with an access token using any .NET Framework you would need to create your own implementation of Idatastore and load a refresh token.
Supported Platforms
.NET Framework 4.5 and 4.6
.NET Core (via netstandard1.3 support)
Windows 8 Apps
Windows Phone 8 and 8.1
Portable Class Libraries
That being said you are going to have to code this yourself from the ground up. I have done it and it is doable.
Authentication :
You have stated you have your refresh token already so I won't go into how to create that.
The following is a HTTP POST call
Refresh access token request:
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
Refresh Access token response:
{ "access_token" : "ya29.1.AADtN_XK16As2ZHlScqOxGtntIlevNcasMSPwGiE3pe5ANZfrmJTcsI3ZtAjv4sDrPDRnQ", "token_type" : "Bearer", "expires_in" : 3600 }
An call you make to the YouTube API you can either add the access token as the authorization bearer token or you can just take it on to the end of any request
https://www.googleapis.com/youtube/v3/search?access_token={token here}
I have a full post on all of the calls to the auth server Google 3 legged Oauth2 flow. I just use normal webRequets for all my calls.
// Create a request for the URL.
WebRequest request = WebRequest.Create("http://www.contoso.com/default.html");
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine (((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
reader.Close();
response.Close();
Upgrade .NET 4+
If you can upgrade to the newest version of .NET using the library will be much easier. This is from Googles official documentation Web Applications ASP.NET. I have some additional sample code on my github account which shoes how to use the Google Drive API. Google dotnet samples YouTube data v3.
using System;
using System.Web.Mvc;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Mvc;
using Google.Apis.Drive.v2;
using Google.Apis.Util.Store;
namespace Google.Apis.Sample.MVC4
{
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "PUT_CLIENT_ID_HERE",
ClientSecret = "PUT_CLIENT_SECRET_HERE"
},
Scopes = new[] { DriveService.Scope.Drive },
DataStore = new FileDataStore("Drive.Api.Auth.Store")
});
public override string GetUserId(Controller controller)
{
// In this sample we use the session to store the user identifiers.
// That's not the best practice, because you should have a logic to identify
// a user. You might want to use "OpenID Connect".
// You can read more about the protocol in the following link:
// https://developers.google.com/accounts/docs/OAuth2Login.
var user = controller.Session["user"];
if (user == null)
{
user = Guid.NewGuid();
controller.Session["user"] = user;
}
return user.ToString();
}
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
}
}
Top tip YouTube doesn't support service accounts your going to have to stick with Oauth2. As long as you have authenticated your code once it should continue to work.

Categories