Multiple Facebook Canvas Applications within same web application - CanvasAuthorizeAttribute - asp.net-mvc-3

I am having a problem with running multiple Facebook applications under a single Web application.
Similar to this problem:
Multiple facebook apps under one web application
I do like the solution suggested here, however the CanvasAuthorizeAttribute uses the FacebookApplication.Current internally and this is a static instance of the FB application within the Web application.
I can't call the .SetApplication method within the controller as I will have concurrency issues.
It would be nice if the FacebookApplication.Current called the Func that is passed into the .SetApplication instead of just calling inside of the .SetApplication.
That way I could pass a function that does my logic for retrieving the correct FB application.
Am I missing something that is already in the SDK?

You can always have your own logic at http://facebook.stackoverflow.com/questions/4931240/multiple-facebook-apps-under-one-web-application/4936703#4936703
private IFacebookApplication Current
{
get
{
var url = HttpContext.Current.Request.Url;
var app = GetSettingsForUrl(url);
// put your custom logic here and return the appropriate IFacebookApplication
return app;
}
}
But you should do this during Application_Start where it is still running on a single thread and not in Controller.

Related

How to set FiddlerCore up to monitor all system traffic?

We are evaluating FiddlerCore for a use-case. Basically, for now we just want to catch all of the endpoints/urls being requested on a system. This works fine in Fiddler, no issues. But we only want to catch them while a certain vendor software is open. So we want to write a plugin to that software that will run when it launches, and then exit when it exits. Hence, using FiddlerCore (hopefully).
As proof-of-concept, I just made a simple app, one form with a textbox, that it should just append each url into the textbox. Simple as simple can be. However, it's not doing anything. I run the app, then refresh a page in my browser, and ... nothing.
Here is the entire (non-generated) code of my program...
using Fiddler;
using System;
using System.Windows.Forms;
namespace ScratchCSharp {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
FiddlerApplication.Startup(8888, FiddlerCoreStartupFlags.Default);
}
private void FiddlerApplication_AfterSessionComplete(Session s) {
textBox1.Invoke((Action)delegate () {
AddText(s.fullUrl);
});
}
public void AddText(string text) {
textBox1.Text += $"{text}\n";
}
}
}
After a little more poking around, I see that FiddlerApplication.IsSystemProxy is returning false. Seems to have to do with that the Startup flag to set as system proxy is no longer honored, and it tells you now to use the Telerik.NetworkConnections.NetworkConnectionManager to set it as the system proxy. But I can't find anywhere that actually says how to do that. The closest thing I could find is this thread which seems to be their official answer to this question. However, it only goes into a lot of talk about WHY they deprecated the flag, and what their thinking was in how they designed its replacement, but not actually into HOW TO USE the replacement. The Demo app also does NOT use these libraries (probably why it doesn't catch anything either).
The biggest problem though, is that the NetworkConnectionsManager class has no public constructor, so you can't create an instance. It is not inheritable, so you can't make a subclass instance. All of the methods on it are instance methods, not static/shared. And there seems to be no method in the libraries which will create an instance of NetworkConnectitonsManager for you.
So while the class is clearly designed to be used as an instance (hence the methods not being static/shared, there doesn't actually seem to be any way to create an instance.
Any help on how to set this thing up to catch all the outgoing URLs on the system?
You can use the following code for starting Fiddler Core and registering it as a system proxy:
FiddlerCoreStartupSettings startupSettings =
new FiddlerCoreStartupSettingsBuilder()
.ListenOnPort(fiddlerCoreListenPort)
.RegisterAsSystemProxy()
.ChainToUpstreamGateway()
.DecryptSSL()
.OptimizeThreadPool()
.Build();
FiddlerApplication.Startup(startupSettings);
Some of the methods are obsolete for now, but I would recommend to stick with them until the NetworkConnectionManager API is improved and finalized.
Also, there is a sample application (that FiddlerCore installer installs on the Desktop), which is useful for a starting point with the development.

Calling internal (Endpoint) function in WebAPI

I am using Hangfire to execute recurring jobs in my web API and I use System.Web.HttpContext.Current.Server.MapPath in the "RoutineMethod" function.
But the problem is it throws object null exception.
I searched the problem and found that recurring jobs don't use http threads, they use background threads.
Now to resolve this problem I need to call my internal (endpoint) using httpclient.
But to do that I need to give URL of the Web API (to generate URI). So is there any other way to call internal function using httpclient.
My current code:
public static async Task<IHttpActionResult> RoutineTask()
{
//It was like this before.
//await new DemoController().RoutineMethod();
//await new DemoController().RoutineMethod2();
//I am planning to do this.
using (var client = new HttpClient())
{
//But I need to give URI which I don't think is a good idea.
var uri = new Uri("http://localhost/DemoApp/api/DemoController/RoutineMethod");
await client.GetAsync(uri);
}
return new DemoController().Ok();
}
The short answer is no. The HttpClient, as its name implies, requires an http connection.
There are no smell issues with storing service connection information in a configuration file.
However, to expand on Nkosi's comment, it appears that since your code can create an instance of DemoController, that it must have a reference to that controller's project or even be in the same project. I would extract the interesting code into a library or service that all areas needing the information can reference.

How to access session from a view in ASP .NET Core MVC 1.0

I am trying to access session data from inside a view.
Use Case: I'm storing status messages in the session that will be displayed at the top of the page. Currently I implemented this by using a DisplayMessages() function that sets some ViewData[....] properties and calling it at the beginning of every controller action.
Goal: I want to only set the status message once without needing additional code in the controller to display the messages on the next page load.
So I'm trying to access the messages that are stored in the session directly from the view.
So far I have tried the following:
Dependency Injection of an IHttpContextAccessor (doesn't seem to work anymore with ASP .NET Core MVC 1.0.0
Creating a static class to access the session, including the change from next() to next.invoke() suggested in the comment
This didn't work. I could access the HttpContext and Session.IsAvailable was true, but there was no data in the session.
The following should work in the view: Context.Session.TryGetValue
If you are using the SessionExtensions then Context.Session.GetString will work.
Injecting IHttpContextAccessor does work, but starting with ASP.NET Core 1.0.0 RC2, the IHttpContextAcessor is not registered by default, because it has significant performance overhead per request. See this GitHub announcement for more information.
Tratcher posted:
IHttpContextAccessor can be used to access the HttpContext for the current thread. However, maintaining this state has non-trivial performance costs so it has been removed from the default set of services.
Developers that depend on it can add it back as needed:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
But in your use case, I would suggest using a ViewComponent, which is a reusable piece of View with logic, that do not depend on a controller.
The documentation can be found here.
In your Views you would simply embed it with
#await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
or
#Component.Invoke("PriorityList", new { maxPriority = 2, isDone = false })
for synchronous calls.

MiniProfiler with Web.API 2; is there a global magic request context object?

I'm trying to setup MiniProfiler on my web api site, and having a hard time getting MiniProfiler.Current to work.
I followed the directions at miniprofiler.com, and have the following in global.asax:
protected void Application_Start()
{
MiniProfilerEF6.Initialize();
// other setup
}
protected void Application_BeginRequest() {
// need to start one here in order to render out the UI
MiniProfiler.Start();
}
protected void Application_EndRequest() {
MiniProfiler.Stop();
}
This uses the default WebRequestProfilerProvider, which stores the actual profile object in HttpContext.Current.Items.
When I ask for MiniProfiler.Current, it looks to HttpContext.Current.
When I make a request for one of my web api URLs:
Application_BeginRequest creates the profiler, store it in HttpContext.Current
in a web api MessageHandler, I can see HttpContext.Current
in a web apu IActionFilter, HttpContext.Current is now null, and my attempt to MiniProfiler.Current.Step("controller:action") fails
my EF queries run from various services do not get recorded, as that miniprofiler hook relies MiniProfiler.Current, which relies on HttpContext.Current, which is null right now
Application_EndRequest fires, and HttpContext.Current is magically back, and so it wraps up the profiler and tells me how long it's been since the request began
I dug through the code, and I can create my own IProfileProvider, to store the profiler object somewhere more reliable than HttpContext.Current, but I don't know where that could be.
I spent a few hours trying things out, but couldn't find a workable solution. The problems:
the IProfileProvider is a global variable; all worker threads in either the MVC or Web API pipeline all have to use the same IProfileProvider
I can dig around in web api RequestContext.Properties to pull out the HttpContext for that request, but that doesn't really help because my IProfileProvider is global across the entire app; If I tell it to store the profile in HttpContext A, then any simultaneous requests for other HttpContexts are going to pollute the profile
I can't rely on any kind of threadstorage because of async/await re-using threads dynamically
I can't stick the profiler object in an Ninject binding with InRequestScope because InRequestScope doesn't seem to work with web api 2.1, but even if I could
everyone says HttpRequestMessage.Properties is the new HttpContext.Current.Items, but again, IProfileProvider is a global variable and I don't know of a way to ensure each request is looking at their version HttpRequestMessage. MiniProfiler.Current can be called from anywhere, so I guess a global IProfileProvider would have to somehow inspect the call stack to and find an HttpRequestMessage there? That sounds like madness.
I'm at a loss. What I really want is a special variable.
The process of putting the question together I figured it out. HttpContext.Current can get lost when you async/await things: Why is HttpContext.Current null after await?
I had to make the web.config change listed there, and adjusted my filters to use Miniprofiler.Current before any awaiting.
Also discussed at https://www.trycatchfail.com/2014/04/25/using-httpcontext-safely-after-async-in-asp-net-mvc-applications/

Play 1.2.4 Mobile and PC design on the same app

I am a new developer in Play world! For a project I need to have a mobile and desktop version. But I don't know how to!!
Create 2 applications, share the model..;
Create a mobile controller to separate the desktop views against the mobile views
I have no idea of how to make this properly. I know the responsive design but I can't use it on this project.
Thanks
PS: Sorry for my english
Depending on the use case I would have a look at a framework like Twitter Bootstrap. With the twitter bootstrap you can use ONE set of view templates for both desktop and mobile. There is also a framework called Kickstrap and a few others.
But on the other hand, if you want to develop some sort of 'backend' or 'admin' application (you still CAN use twitter bootstrap, but you might have a look at frameworks like Sencha (EXT JS and Touch) or Kendo UI.
What ever you choose, Play will enable you to develop the serverside as it should be (RESTful), so the choice for the frontend can change in time, but you app architecture will be fine :-)
Either one is okay. As they are essentially the same thing, 2 set of routes/controllers/views plus 1 set of domain models.
If you are using my play clone, then you can simplified it to 1 set of domain model + 1 set of routes/controllers + 2 set of views, as you can do something like follows:
public class Application extends Controller {
...
#OnApplicationStart
public static class ViewRouter extends Job {
Controller.registerTemplateNameResolver(new ITemplateNameResolver(){
#Override
public String resolveTemplateName(String templateName) {
return UserAgent.isMobile() ? "mobile/" + templateName : templateName;
}
});
}
}
Thus you just put your mobile views under app/views/mobile and all others still remain in app/views, the template will be loaded dynamically based on the request's user agent, if it's coming from a mobile device then app/views/mobile/.. version get loaded otherwise, the normal view will be loaded.

Resources