dotnetopenauth - change call back url for twitter? - c#

I am using the dotnetopenauth library and I am trying to figure out how to change the call back url.
I am looking at the sample file
public partial class SignInWithTwitter : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (TwitterConsumer.IsTwitterConsumerConfigured) {
this.MultiView1.ActiveViewIndex = 1;
if (!IsPostBack) {
string screenName;
int userId;
if (TwitterConsumer.TryFinishSignInWithTwitter(out screenName, out userId)) {
this.loggedInPanel.Visible = true;
this.loggedInName.Text = screenName;
// In a real app, the Twitter username would likely be used
// to log the user into the application.
////FormsAuthentication.RedirectFromLoginPage(screenName, false);
}
}
}
}
protected void signInButton_Click(object sender, ImageClickEventArgs e) {
TwitterConsumer.StartSignInWithTwitter(this.forceLoginCheckbox.Checked).Send();
}
So this is all what is needed to send a request off to twitter( for webforms slightly different for mvc).
I would like to change the url that the response comes back too(I rather have a separate action result.
Now it seems like StartSignInWithTwitter() is where it sets the url.
/// <summary>
/// Prepares a redirect that will send the user to Twitter to sign in.
/// </summary>
/// <param name="forceNewLogin">if set to <c>true</c> the user will be required to re-enter their Twitter credentials even if already logged in to Twitter.</param>
/// <returns>The redirect message.</returns>
/// <remarks>
/// Call <see cref="OutgoingWebResponse.Send"/> or
/// <c>return StartSignInWithTwitter().<see cref="MessagingUtilities.AsActionResult">AsActionResult()</see></c>
/// to actually perform the redirect.
/// </remarks>
public static OutgoingWebResponse StartSignInWithTwitter(bool forceNewLogin) {
var redirectParameters = new Dictionary<string, string>();
if (forceNewLogin) {
redirectParameters["force_login"] = "true";
}
Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix("oauth_");
var request = TwitterSignIn.PrepareRequestUserAuthorization(callback, null, redirectParameters);
return TwitterSignIn.Channel.PrepareResponse(request);
}
It seems to be hard coded to get the current request from context. is it possible to override this somehow without me actually changing this line of code and recompiling the .dll?
Edit
For now I made changes to the .dll - I really don't like this way as now i got to support a custom version.
public static OutgoingWebResponse StartSignInWithTwitter(bool forceNewLogin) {
Uri callback = MessagingUtilities.GetRequestUrlFromContext().StripQueryArgumentsWithPrefix("oauth_");
return StartProcess(forceNewLogin, callback);
}
private static OutgoingWebResponse StartProcess(bool forceNewLogin, Uri callback)
{
var redirectParameters = new Dictionary<string, string>();
if (forceNewLogin)
{
redirectParameters["force_login"] = "true";
}
var request = TwitterSignIn.PrepareRequestUserAuthorization(callback, null, redirectParameters);
return TwitterSignIn.Channel.PrepareResponse(request);
}
public static OutgoingWebResponse StartSignInWithTwitter(bool forceNewLogin, Uri callback)
{
return StartProcess(forceNewLogin, callback);
}
Hopefully there is another way.

I appreciate your desire to not recompile libraries. But the DotNetOpenAuth.ApplicationBlock library is just an auxiliary library to DotNetOpenAuth and it ships with source because it isn't really intended to be used as-is. It's expected that you'll copy and paste the source code out of it into your web application that you need and dump the rest. For example, there is no backward compatibility promise in the applicationblock library from version to version like there is in the core dotnetopenauth.dll file.
So by all means, if you find a deficiency in the appblock, you're in the right to fix it for yourself.

Related

What is the proper return type for an C# SDK CRUD operations?

I'm currently struggling to write a really good SDK for our API. I'm looking at doing it one of a few ways right now.
I can either pass the HttpResponseMessage back from my API call (as you can see below).
I can do some data processing and pass back just the object.
I can create a custom object to wrap the SDK return so that it can contain what it needs to.
I can throw exceptions when a server error is encountered, but that can be expensive especially if the application can recover from the exception.
I could also return a tuple in the getter here so that I get both an object and the HttpResponseMessage.
I want the SDK to do just the right amount of processing on the data and I'm not sure if there is an example of how to write a good SDK in .NET or not. I am actually going to consume this SDK myself so I want it to be good. I have written some code and I'll include that here but I think it's current iteration is flawed.
public interface IBaseApi<T>
{
Task<IEnumerable<T>> GetAllAsync();
Task<T> GetByIdAsync(int id);
Task<HttpResponseMessage> InsertAsync(T obj);
Task<HttpResponseMessage> UpdateAsync(T obj);
Task<HttpResponseMessage> DeleteAsync(int id);
}
Right now we return a null object to indicate that either Get request failed. But I think that's a flawed concept.
I've also looked at the Facebook, Square, and a few other Sdks. Nothing quite hit the mark for me.
So what return type should my API be sending? Just a pointer, I don't know how the client is going to consume this. It could be part of a larger query or a direct pass through to their Controller. My overall goal is that the consumer will have as little processing to do themselves, but also a meaningful if something goes wrong message.
What I have done in the past and has worked really well is to create an "Api Response" object that contains metadata about the response as well as the actual data resulting from the call, something along the lines of:
public class ApiResponse<TData>
{
/// <summary>
/// Constructor for success.
/// </summary>
/// <param name="data"></param>
public ApiResponse(TData data)
{
Data = data;
Success = true;
Errors = new List<string>();
}
/// <summary>
/// Constructor for failure.
/// </summary>
/// <param name="ex"></param>
public ApiResponse(IEnumerable<string> errors)
{
Errors = errors;
Success = false;
}
/// <summary>
/// Gets whether the API call was successful.
/// </summary>
public bool Success { get; private set; }
/// <summary>
/// Gets any errors encountered if the call was not successful.
/// </summary>
public IEnumerable<string> Errors { get; private set; }
/// <summary>
/// Gets the data resulting from the API call.
/// </summary>
public TData Data { get; private set; }
}
You could have a base class that does not return any data too and then derive this one from that.

Reference to an ASMX webservice wants to implement IDisposable

I have a somewhat simple web app, that uses an ASMX web service as its sole data access. All the information is gotten from it, and saved to it. It works fine so thats out of the way.
I just updated to VS2012, and it complained about the class implementing the service reference, does not inherit from IDisposeable.
After some reading, i am more confused as some solutions are really elaborate, some are simple. Short version is, after understanding so little, it seems like i cant adapt it to how my app is made.
I have several data access classes, all focusing on methods for an area. For example, one dataaccess for customer related calls, one for product related calls etc.
But since they are all using the same service, they all derive from a base data access class that holds the reference.
This is the base data access class:
public class BaseDataAccess
{
private dk.odknet.webudv.WebService1 _service;
private string _systemBrugerID, _systemPassword;
public BaseDataAccess()
{
//Gets the system user and password that is stored in the webconfig file. This means you only have to change
//the username and password in one place without having to change the code = its not hardcoded.
_systemBrugerID = System.Configuration.ConfigurationManager.AppSettings["SystemBrugerID"].ToString();
_systemPassword = System.Configuration.ConfigurationManager.AppSettings["SystemPassword"].ToString();
_service = new dk.odknet.webudv.WebService1();
}
/// <summary>
/// Gets an instance of the webservice.
/// </summary>
protected dk.odknet.webudv.WebService1 Service
{
get { return _service; }
}
/// <summary>
/// Gets the system user id, used for certain methods in the webservice.
/// </summary>
protected string SystemBrugerID
{
get { return _systemBrugerID; }
}
/// <summary>
/// Gets the system user password, used for certain methods in the webservice.
/// </summary>
protected string SystemPassword
{
get { return _systemPassword; }
}
}
And here is how a derived class utilizes the service reference from the base class:
public class CustomerDataAccess : BaseDataAccess
{
public CustomerDataAccess() {}
/// <summary>
/// Get's a single customer by their ID, as the type "Kunde".
/// </summary>
/// <param name="userId">The user's username.</param>
/// <param name="customerId">Customer's "fkKundeNr".</param>
/// <returns>Returns a single customer based on their ID, as the type "Kunde".</returns>
public dk.odknet.webudv.Kunde GetCustomerById(string userId, string customerId)
{
try
{
return Service.GetKunde(SystemBrugerID, SystemPassword, userId, customerId);
}
catch (Exception e)
{
Debug.WriteLine(e);
throw;
}
}}
So how on earth do i implement IDisposable in this situation? I just cant wrap my head around it.
EDIT
I have fiddled with the service reference, and come up with this:
/// <summary>
/// Gets an instance of the webservice.
/// </summary>
protected dk.odknet.webudv.WebService1 Service
{
get
{
try
{
using (_service = new dk.odknet.webudv.WebService1())
{
return _service;
}
}
catch (Exception e)
{
Debug.WriteLine(e);
throw;
}
}
}
Yes the exception handling isnt great, i will get to that (advice is appreciated), but VS2012 does not complain about the lack of IDisposable anymore.
Instantiation of the service has been removed from the constructor. The app works fine without any further modifications.
Will this suffice?

Hide a QueryString parameters, how?

I have a url: like this one: http://www.example/about/49.
I want it to be seen as http://www.example/about/, but I must have this parameters passed as QueryString parameters.
Is it possible ?
Be careful with session variables; it's easy to have multiple pages opened which are all using the same session and end up mixing the values.
It would be better to use TempData, which only allows the value to be used once (removed on first access). However, this implies the value will be used almost immediately.
You can also write a cookie with the desired value, intercept the request (ASP.Net provides a variety of ways of doing this, such as the BeginRequest event), and internally process the URL as though it contained the value.
Of course, you then must cleanup the cookie (which will have the same problem as a Session-based solution). Remember that a cookie is more vulnerable to tampering on the client.
Personally, I think any of these approaches are far more trouble than they are worth. "Hackable URLs" (such as those which contain a potentially meaningful ID) are usually a good thing.
My workaround for this (Which works REALLY well, thanks to the help of the SO Community)
Create a class called SiteSession.cs
Input the following code:
using System;
using System.Collections.Generic;
using System.Web;
/// <summary>
/// Summary description for SiteSession
/// </summary>
public class SiteSession
{
/// <summary>
/// The _site session
/// </summary>
private const string _siteSession = "__SiteSession__";
/// <summary>
/// Prevents a default instance of the <see cref="SiteSession" /> class from being created.
/// </summary>
private SiteSession()
{
}
/// <summary>
/// Gets the current Session
/// </summary>
/// <value>The current.</value>
public static SiteSession Current
{
get
{
SiteSession session = new SiteSession();
try
{
session = HttpContext.Current.Session[_siteSession] as SiteSession;
}
catch(NullReferenceException asp)
{
}
if (session == null)
{
session = new SiteSession();
HttpContext.Current.Session[_siteSession] = session;
}
return session;
}
}
//Session properties
public int PageNumber {get;set;}
}
You can put anything in the Session Properties, just make sure its public.
Then, set it by:
SiteSession.Current.PageNumber = 42
And call it with
int whatever = SiteSession.Current.PageNumber

Extension methods and class library's for importing HttpResponseException

I've got this extension method that check for some info in the request cookie and if this info I'm looking for is not in the cookie I go to the database.
All this is OK but when I built this extension I designed it in my MVC4 application, and now I am refactoring items to relative library's and I cannot seem to find a way to import or add a reference to my class library that would allow me to throw an HttpResponseException.
Any ideas on how to overcome this?
namespace LinkedIn.Extensions
{
public static class httprequest_linkedincontext
{
/// <summary>
/// Extension that creates a OAuthLinkedIn object by checking the cookie first, and if the cookie has no LinkedIn info or has expried then builds the LinkedIn OAuthLinkedIn from the database.
/// </summary>
/// <param name="request"></param>
/// <param name="userName"></param>
/// <returns>oAuthLinkedIn information</returns>
public static oAuthLinkedIn GetLinkedInContext(this HttpRequestMessage request, string userName)
{
OAuthHelper helper = new OAuthHelper(request, userName, false);
oAuthLinkedIn oauth = new oAuthLinkedIn(helper.Verify, helper.Token, helper.TokenSecret);
if (string.IsNullOrEmpty(oauth.Token) || string.IsNullOrEmpty(oauth.TokenSecret))
{
throw new System.Web.Http.HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.NotFound));
}
return oauth;
}
}
}
Right now there is a little red squiggle line under Http in the System.Web.Http.HttpResponseException.

Reporting on code execution and design patterns?

First of all I wanted to thank all of you for your continuous contributions to the Stack Overflow community! I've been a member of Stack Overflow for years and have come to rely on your input more so than any other source online. Though I try to participate and answer members' questions whenever I can, every once in a while I find myself stuck and in need of help.
Speaking of which I have an unusual code problem. I am writing an API library in C# that needs to be able to be called from WPF/Windows Forms application, but also from within Unit Test code.
The issue is that I need to be able to report (in Excel) on whether each method of the library executed properly when the API is called from within a WPF/windows forms application, along some other metadata and optionally a return type.
When the code is consumed within Unit Tests I don't really care about the reporting, but I do need to be able to produce an Assert on whether the API call executed properly or not.
For instance, if in a Unit Test we have an Test Initialize portion, one of the API calls may be to create a Domain User for the test method to use. Another one may also create a Domain Group, so that the user has proper group membership.
To accomodate the consumption of the API from WPF/WinForms, I've been rewriting every function in the API to return a OperationStep type, with the hopes that when all API calls have executed I would have an IEnumerable<OperationStep> which I can write to a CSV file.
So the question is is there an easier way of achieving what I have done so far? The reporting is extremely tedious and time consuming to code, considering that the API library consists of hundreds of similar methods. Samples are described bellow:
OperationStep<PrincipalContext> createDomainConnectionStep = DomainContext.Current.GetPrincipalContext(settings.DomainInfo);
OperationStep<UserPrincipal> createDomainUserStep = DomainContext.Current.CreateUser(createDomainConnectionStep.Context, settings.TestAccountInfo.Username, settings.TestAccountInfo.Password);
OperationStep<GroupPrincipal> createDomainGroupStep = DomainContext.Current.CreateGroup(createDomainConnectionStep.Context, settings.TestAccountInfo.UserGrupName);
Where the DomainContext is a singleton object whose functionality is to connect to the domain controller and create a user, group, and associate the user to a group.
Note that both the second and the third method call require the output of the first, and therefore warranting the need for having the public T Context within the OperationResult object as described bellow.
The OperationStep object consists of the following properties which are inherited by the IOperation interface with the exception of the public T Context.
public class OperationStep<T> : IOperation
{
/// <summary>
/// Denotes the Logical Name of the current operation
/// </summary>
public string Name { get; set; }
/// <summary>
/// Denotes the stage of execution of the current operation: Setup, Execution, Validation, Cleanup
/// </summary>
public OperationStage Stage { get; set; }
/// <summary>
/// Denotes whether the test step completed properly or failed.
/// </summary>
public OperationResult Result { get; set; }
/// <summary>
/// Denotes the return type of the test method.
/// </summary>
public T Context { get; set; }
/// <summary>
/// Denotes any other relevant information about the test step
/// </summary>
public string Description { get; set; }
/// <summary>
/// If the test step result is failed, this should have the stack trace and the error message.
/// </summary>
public string Error { get; set; }
}
The method calls themselves are a bit bloated and tedious but here is a sample.
public class DomainContext
{
private static volatile DomainContext currentContext;
private static object synchronizationToken = new object();
/// <summary>
/// default ctor.
/// </summary>
private DomainContext() { }
/// <summary>
/// Retrieves the Current DomainContext instance.
/// </summary>
public static DomainContext Current
{
get
{
if (currentContext == null)
{
lock (synchronizationToken)
{
if (currentContext == null)
{
currentContext = new DomainContext();
}
}
}
return currentContext;
}
}
/// <summary>
/// Establishes a connection to the domain.
/// </summary>
/// <param name="domainInfo"></param>
/// <returns></returns>
public OperationStep<PrincipalContext> GetPrincipalContext(DomainInfo domainInfo)
{
OperationStep<PrincipalContext> result = new OperationStep<PrincipalContext>();
result.Name = "Establish Connection to Active Directory";
result.Result = OperationResult.Success;
result.Stage = OperationStage.Setup;
result.Description = string.Format("Domain Name: {0}, Default Containter: {1}", domainInfo.FQDN, domainInfo.Container);
try
{
ContextType contextType = this.GetContextType(domainInfo.DomainType);
PrincipalContext principalContext;
try
{
principalContext = new PrincipalContext(contextType, domainInfo.FQDN, domainInfo.Container);
}
catch
{
throw new Exception("Unable to establish connection to Active Directory with the specified connection options.");
}
if (principalContext != null)
{
bool authenticationResult = principalContext.ValidateCredentials(domainInfo.Username, domainInfo.Password);
if (!authenticationResult)
{
throw new Exception("Unable to authenticate domain admin user to Active Directory.");
}
result.Context = principalContext;
result.Result = OperationResult.Success;
}
}
catch(Exception ex)
{
result.Error = ex.Message;
result.Result = OperationResult.Failure;
}
return result;
}
}
When all method calls have executed theoreticaly I should have an IEnumerable<IOperation> which in the case of a win form I can write in a csv file (to be viewed in MS Excel) or in the case of a unit test I can simply omit the extra info and ignore (other than the method executed successively and the T Context property).
If I understood you correctly - all that OperationSteps are here only for logging. Then why not enable simple .NET logging? Log needed info where it is convenient for you. You can use TraceSource with DelimetedTraceListener to write to .csv file. More than that. You can move logging logic to Strategy class and override its logging methods in your unit test so that instead of logging you call Assert methods.

Categories

Resources