Access Moodle API from .Net Console Application - c#

For one of my projects I need to manage some of the attributes of our Moodle, including (but probably not limited to) Creating/Updating users and managing enrolments.
I need to create this interface in a .Net (4.0+) Console application, so information can be processed from other systems.
I have checked NuGet for packages for Moodle but I cant find anything.
Can you advise on how I could achieve this interface?
Thanks in advance.

I don't think there is a wrapper available for this. You will need to enable moodle webservices:
https://docs.moodle.org/dev/Web_services
And create your own. I am using RestSharp for this:
https://www.nuget.org/packages/RestSharp

This code will work for accessing course information
string result = "";
string methodName = "GetCourse";
string apiName = "core_course_get_courses";
string apiCall = moodleUrl + "?wstoken=" + token + "&wsfunction=" + apiName + "&moodlewsrestformat=json";
try
{
using (WebClient client = new WebClient())
{
client.BaseAddress = apiCall;
client.Headers[HttpRequestHeader.Accept] = "application/json";
result = client.DownloadString(apiCall);

Related

Looking for client side Json/WebAPI package to send HttpGet/HttpPost messages

BACKGROUND
currently I am in a side project where I am building a Xamarin based mobile App for easy movie and tv show searching and navigation based on user preferences (e.g. based on movie genre etc).
To do this the mobile app acts as a client to the https://www.themoviedb.org/documentation/api online movie database's Web API service.
PROBLEM
I am looking for an easy and well supported package to wrap API Uri paths and query parameters into a web api query. I have looked a bit on RestSharp .
I like the syntax very much with the pattern based query path:
var request = new RestRequest("resource/{id}");
request.AddParameter("name", "value");
request.AddUrlSegment("id", "123");
but I am not sure about the packages future. Also if there is an alternative from MS, I would take that.
So have also looked Web-API tailored at MS alternatives but I am unsure what is recommended there. I only can find docs and examples for the server side (ASP.NET CORE MVC).
I need to be pointed to a well functioning .NET Standard 2.0 package from Microsoft or from a 3rd party to send Web API request from my Xamarin client.
Where am I
I have already written a lot of code based on pure HttPClient and AspNetcore.WebUtilituies for assembling a query string. But the gazillions of API path segments are getting out of my hand. I really need something to manage API path templates like RestSharp does
Code sample:
here I declare all of the path segments which I assemble manually ==> ugly AF
public static class WebApiPathConstants
{
public const string BASE_Address = "https://api.themoviedb.org";
public const string BASE_Path = "/3";
public const string CONFIG_Path = "/configuration";
public const string GENRE_LIST_Path = "/genre/movie/list";
...
lot of lines here
....
public const string PAGE_Key = "page";
public const string INCLUDE_Adult_Key = "include_adult";
public const string API_KEY_Key = "api_key";
public const string RECOMMENDATIONS_Path = "/recommendations";
public const string SIMILARS_Path = "/similar";
}
Here I assemble a query and kick of a task to get movie details based on the query from the server: The assembly of the Url path is my main problem. It looks too error prone.
public async Task<FetchMovieDetailsResult> FetchMovieDetails(int id, string language = null, int retryCount = 0, int delayMilliseconds = 1000)
{
string baseUrl = BASE_Address + BASE_Path + MOVIE_DETAILS_Path + "/" + id;
var query = new Dictionary<string, string>();
query.Add(API_KEY_Key, apiKeyValue);
if (!string.IsNullOrEmpty(language))
query.Add(LANGUAGE_Key, language);
string requestUri = QueryHelpers.AddQueryString(baseUrl, query);
FetchMovieDetailsResult result = await GetResponse<FetchMovieDetailsResult>(retryCount, delayMilliseconds, requestUri);
return result;
}
The result is a POCO class with the HttpStatusCode and (if successful ) a Json object. The client accesses the Json object only if the StatusCode == 2xx.
Prepared to be shot down in flames here, if this doesn't match your use-case, but it looks like the TheMovieDb site itself has a list of client libraries. It's available here: https://www.themoviedb.org/documentation/api/wrappers-libraries. They're obviously a layer higher than you're asking for here, in that they completely wrap the API, such that you need not even know what you're calling or how you're calling it, but in the interests of getting the job done, they seem like they'd do the trick.

How do I stop single sign on (SSO) option using Web Authentication Broker

I am developing a Windows Store App which requires user to authenticate using Yammer credentials. I have written the following code to achieve the functionality.
var client_id = <<My Client ID >>;
var client_secret = <<My Client Secret>>;
string redirectURI = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().ToString();
string loginURI = "https://www.yammer.com/dialog/oauth?client_id=" + client_id + "&redirect_uri=" + redirectURI;
var result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, new Uri(loginURI), new Uri(redirectURI));
if (result.ResponseStatus == WebAuthenticationStatus.Success)
{
var response = result.ResponseData;
string[] keyValPairs = response.Split('=');
HttpClient client = new HttpClient();
string url = "https://www.yammer.com/oauth2/access_token.json?client_id=" + client_id + "&client_secret=" + client_secret + "&code=" + keyValPairs[1];
HttpResponseMessage JSONresponse = await client.GetAsync(url);
string content = await JSONresponse.Content.ReadAsStringAsync();
}
When I ran the app for the first time it asked me for my credentials and I was able to login.
Now when I run my app , it takes my previous entered credentials and logs in automatically. I am sure that I did not check "Keep Me signed In" option.
I want the app to ask for credentials every time I run it.
Please help and thanks in advance.
I had a similar problem with an app using the Pocket OAUTH 2.0 API. I am using the WebAuthenticationBroker http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.authentication.web.webauthenticationbroker.aspx and its AuthenticateAsync method but I think the problem is the same.
I had used the AuthenticateAsync(options, url) method which ended up -once credentials are saved - I was never able to use a different login so basically could not change accounts.
Tried AuthenticateAsync(options, url, redirectURI) method and same problem.
But then I realized that redirectURI is set to GetCurrentApplicationCallbackUri as in your example this seems to trigger SSO.
Changing the redirectURI to a custom one (e.g. your own domain) seems to disable SSO and credentials have to be added every time as wanted.
This is easy with the AuthenticateAsync method as it uses a WebAuthenticationBroker, not sure how to adapt this with the HttpClient you use above but I maybe you could use
WebAuthenticationBroker?
But my code example (Javascript but same API):
var authweb = Windows.Security.Authentication.Web
var OAUTH_URI = 'https://$WHATEVERSERVICE'
var OAUTH_CODE = '$GOT BEFORE'
var endURI = 'http://$YOURDOMAIN.com' // this is the important part
var authorizeUri = new Windows.Foundation.Uri(OAUTH_URI
+ '?request_token=' + encodeURIComponent(OAUTH_CODE) // POCKET SPECIFIC PARAM
+ '&redirect_uri=' + encodeURIComponent(endURI)
);
authweb.WebAuthenticationBroker.authenticateAsync(
authweb.WebAuthenticationOptions.none,
authorizeUri,
Windows.Foundation.Uri(endURI)
).done(...
This way I get a clean (no prefilled or even submitted) login form every time.
Hope this helps?

How would you detect the current browser in an Api Controller?

I'm trying to detect the current web browser within one of my Api Controllers in my program using MVC4. Everywhere I look people say to use Request.Browser, however I can't get that to work. Any suggestions or is there something I'm overlooking?
You can use the HttpBrowserCapabilities in System.Web like this
var userAgent = HttpContext.Current.Request.UserAgent;
var userBrowser = new HttpBrowserCapabilities { Capabilities = new Hashtable { { string.Empty, userAgent } } };
var factory = new BrowserCapabilitiesFactory();
factory.ConfigureBrowserCapabilities(new NameValueCollection(), userBrowser);
//Set User browser Properties
BrowserBrand = userBrowser.Browser;
BrowserVersion = userBrowser.Version;
This relies on browscap.ini in Windows/System32/inetsrv/ or Windows/SysWOW64/inetsrv for definitions.
This article may also help - http://stephenwalther.com/archive/2010/03/05/use-asp-net-4-browser-definitions-with-asp-net-3-5
You could do something like following too from within the Web API's action:
System.Net.Http.HttpRequestMessage currentRequest = this.Request;
System.Net.Http.Headers.HttpHeaderValueCollection<System.Net.Http.Headers.ProductInfoHeaderValue> userAgentHeader = currentRequest.Headers.UserAgent;

Make Google Plus post through .NET (C#)

Good day all.
Does anyone has a working example how to make Google Plus post through .NET (C#).
I have already tried google and stackoverflow search, but did not manage to find the solution.
I successfully get posts:
public void Post(string text)
{
PlusService plus = new PlusService {Key = "MYVERYSECRETKEY"};
ActivitiesResource ar = new ActivitiesResource(plus, null);
ActivitiesResource.ListRequest list = ar.List("108055870103885325249", new ActivitiesResource.Collection());
ActivityFeed feed = list.Fetch();
string activityKey = "";
foreach (var a in feed.Items)
if (a.Url == "https://plus.google.com/108055870103885325249/posts/EtvvUgn8eKz")
{
activityKey = a.Id;
break;
}
ActivitiesResource.GetRequest get = ar.Get(activityKey);
Activity act = get.Fetch();
var sb = new System.Text.StringBuilder();
sb.AppendLine("Title: " + act.Title);
sb.AppendLine("URL:" + act.Url);
sb.AppendLine("Published:" + act.Published);
sb.AppendLine("By:" + act.Actor.DisplayName);
sb.AppendLine("Annotation:" + act.Annotation);
sb.AppendLine("Content:" + act.Object.Content);
sb.AppendLine("Type:" + act.Object.ObjectType);
sb.AppendLine("# of +1s:" + act.Object.Plusoners.TotalItems);
sb.AppendLine("# of reshares:" + act.Object.Resharers.TotalItems);
}
But I cannot find any method for making posts.
Thanks in advance.
Currently, the Google+ API does not allow writing of posts to a user's activity stream. You can use the moments.insert method in the Google+ REST API to write App Activities to the user's profile, which the user can choose whether to share publicly or to their circles.
You would work with the REST API in a similar manner to other REST APIs in .NET by POSTing to the moments.insert end-point.
This feature is now available to apps that request the https://www.googleapis.com/auth/plus.login scope and specify the type of moments that the app wants to write in the request_visible_actions parameter either in the Google+ Sign-In button or directly in the OAuth query parameters.

How to reliably build a URL in C# using the parts?

I keep feeling like I'm reinventing the wheel, so I thought I'd ask the crowd here. Imagine I have a code snippet like this:
string protocol = "http"; // Pretend this value is retrieved from a config file
string host = "www.google.com"; // Pretend this value is retrieved from a config file
string path = "plans/worlddomination.html"; // Pretend this value is retrieved from a config file
I want to build the url "http://www.google.com/plans/worlddomination.html". I keep doing this by writing cheesy code like this:
protocol = protocol.EndsWith("://") ? protocol : protocol + "://";
path = path.StartsWith("/") ? path : "/" + path;
string fullUrl = string.Format("{0}{1}{2}", protocol, host, path);
What I really want is some sort of API like:
UrlBuilder builder = new UrlBuilder();
builder.Protocol = protocol;
builder.Host = host;
builder.Path = path;
builder.QueryString = null;
string fullUrl = builder.ToString();
I gotta believe this exists in the .NET framework somewhere, but nowhere I've come across.
What's the best way to build foolproof (i.e. never malformed) urls?
Check out the UriBuilder class
UriBuilder is great for dealing with the bits at the front of the URL (like protocol), but offers nothing on the querystring side. Flurl [disclosure: I'm the author] attempts to fill that gap with some fluent goodness:
using Flurl;
var url = "http://www.some-api.com"
.AppendPathSegment("endpoint")
.SetQueryParams(new {
api_key = ConfigurationManager.AppSettings["SomeApiKey"],
max_results = 20,
q = "Don't worry, I'll get encoded!"
});
There's a new companion library that extends the fluent chain with HTTP client calls and includes some nifty testing features. The full package is available on NuGet:
PM> Install-Package Flurl.Http
or just the stand-alone URL builder:
PM> Install-Package Flurl

Categories

Resources