Posts Tagged ‘C#’

Ampersandjs and ASP.NET MVC

Thursday, November 13th, 2014

Ampersand is a newish client JavaScript framework that helps build native web applications. It is built and maintained by &yet. Ampersand is different than other frameworks because it is not a monolithic library that solves all your problems. It is a collections of small modules that all solve a single problem that when put together make up Ampersand. This allows you to easily switch out modules that don’t work for you. To read more about Ampersand and its benefits check out the following links.

I recently wanted to know what it would take to run the Ampersand-cli demo app using ASP.NET MVC instead of node.js. So I did just that. The can be found on my github. Head over there and check it out. What follows is some the key points that is a bit different than the node.js version.

Getting Started

Node.js is required when setting up my demo code. It is not required but I used it because it is easier if you do. Node allows us to use npm and tools like gulp and browserify which we will cover in a bit.

First we need to install gulp and browserify from npm. Navigate to the WebApp root folder from the command line and run:

npm install -g gulp browserfiy

Next install all the dependencies found in the package.json from npm by running

npm install

Next run gulp.

gulp

Finally build and run the visual studio project.

Browserify and gulp 

Ampersand highly suggests to use a common JS loader like browserify. In my example, I followed this suggestion. Browserify is a commonJS loader that allows you to require(”) modules, like node, in the browser. Gulp is a streaming build system that allows you to run jobs such as pre-compiling CSS, copying files, and many other things.

When browserify is pointed at our main app.js file (Scripts\App\app.js) and run, it will bundle all of the app’s JavaScript files into one file (Scripts\app.bundle.js).

Gulp and the corresponding gulpfile.js is used to watch the JavaScript files and automatically run browserify when things change. This means that as you edit files, gulp will rebuild the app.bundle.js file. All you have to do is reload the browser to get the final results.

Routes

With any native web application frame, the odds are good you are doing routing on the client side. Which means the server must serve the same html, css, and js for any page that is request. To do this, a catch all route is created.

routes.MapRoute(
    name: "Default",
    url: "{*.}",
    defaults: new { controller = "Home", action = "Index"}
);

Base Layout and Action

Notice the _Layout.cs file is basically empty. This is because everything is loaded via Ampersand including anything in <head>. This also means that our default controller and action serve nothing. The only things our default action needs to serve is any CSS and JavaScript.

Templates

Ampersand’s demo site uses Jade templates and complies them at runtime down to a single template.js file. Meaning that all HTML is served to the user the first time the application loads. In my examples, I sort of replicated this by creating an Action that creates a single JS file with all the HTML templates. This can be better and more automated but for the purposes of this demo I stopped here to show a direction that could be taken.

See the Template Controller and the views in the Template view folder.

Templates do not need to be served this way. You could make HTTP get requests for them in Ampersand. I did it this way to keep in the spirit of the original demo.

Sample API

The simple API was created using Web API. Nothing really different going on here expect that because of C# our models are strongly typed.

CSS

The original Ampersand demo used stylizer and a CSS preprocessor. I took the output from that and put it into site.css. You could do whatever suits your needs here.

Final things to Note

In this code, the app.bundle.js and template JavaScript is not far future cached. It could be. That is something you will need to figure out. There are many different ways to do this in MVC, I did not want to suggest one. The same goes for the CSS.

Much like Nuget’s packages folder, the node_modules folder is not checked into source control. Running npm install command will repopulate this folder much like Nuget’s auto restore.

Other than what is about, the rest of the application is vanilla Ampersand, no other changes were made.

Source Code: https://github.com/Oobert/Ampersand-and-ASP.NET-MVC/tree/master

C# HttpClient integrated authentication

Monday, July 14th, 2014

HttpClient has become the standard way to make http requests in C#. This is mainly used for API calls but has other uses as well. Recently, I have had to make http requests to servers that require authentication and the documentation on how to do this is scattered. The funny part is that it is really easy to do.

var uri = new Uri("<url>");

var credentialCache = new CredentialCache();
credentialCache.Add(
    new Uri(uri.GetLeftPart(UriPartial.Authority)),
            "<auth method>",
            new NetworkCredential("<user name>", "<password>", "<domain>")
            );
            

HttpClientHandler handler = new HttpClientHandler();
handler .Credentials = credentialCache;
var httpClient = new HttpClient(handler );

var response = httpClient.GetAsync(uri).Result;

can be basic, digest, ntlm, or negotiate. Then just updated the Network Credentials to that of the user you want to make the call and you are good to go.

It appears that kerberos on its own does not work. This may be because of my server configuration. However if you use negotiate, HttpClient will use kerberos if the server is configured for it otherwise it will fallback to NTLM.

ASP.NET Dropin DLL Plugin – Part Two

Tuesday, July 9th, 2013

ASP.NET Dropin DLL Plugin – Part One

The first post was a quick intro to the project. In this post, we will cover this works in more detail. So let’s just jump right in.

Typically in ASP.NET MVC, the framework knows where to look for files based on the conventions of the framework. Views are in view folder. With a plugin, the framework needs to be told if a files exists in a plugin DLL and be given a stream to the file. This where the System.Web.Hosting.VirtualPathProvider and System.Web.Hosting.VirtualFile come into play.

In the example there are two class that inherit from the above two classes: AssembleVirtualPathProvider and AssembleVirtualFile. These are Terrible implementations because they are only looking for the one plugin dll. This is a major area for improvement as these classes should look within any DLL that is a plugin. There are many options for this but that is another topic.

The AssembleVirtualPathProvider main job is to see if a view exists within a dll. To do this a number of methods need to be overridden. These methods by default look for views following MVC default naming and file location conventions. In order to check inside of the assembles, these methods need to be overridden and code added to look for the views within the DLLs. Make sure to call the base methods! If you don’t MVC will not be able to find the files local to main MVC project.

The AssembleVirtualFile is a representation of the a file being loaded from a plugin. It has one job, to open a file stream to the file that is in a dll and return it. That is it. This class is used by the AssembleVirtualPathProvider to return a file when GetFile method is called.

Once these are created, the main MVC project must be told to use these providers. In the main MVC project’s global.asax, the new path provider needs to be registered.

System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new Lib.AssembleVirtualPathProvider());

Now there is a catch to this. Plugins must be in the main MVCs project’s bin directory. I have tried multiple ways to get around this but have not had any luck. The reason is when DLLs are in the bin directory, the website’s process does a deep inspection of all the files in the bin directory. It keeps tabs on what files exist, exception model and controllers. If the DLLs are not in the bin directory, MVC will not be able to resolve the models and controller classes.

Moving on, serving static files from the DLLs. One of the goals of this was that the code in the plugins was written as close as possible to a normal MVC application. I did not want to have some special syntax for plugins vs non plugins. In order for this works, images and files need to be handled by a HTTP handler. In this case a static handler. Bring in the System.Web.StaticFileHandler. This will serve files from DLLs or the file system. It is pretty handy. In the web.config of the main MVC project an entry needs to be added for each static file type you would like to serve from the plugins.

<add name="AspNetStaticFileHandler-GIF" path="*.gif" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
<add name="AspNetStaticFileHandler-JPG" path="*.jpg" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
<add name="AspNetStaticFileHandler-PNG" path="*.png" verb="GET,HEAD" type="System.Web.StaticFileHandler" />
<add name="AspNetStaticFileHandler-JS" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />

On top of this, routes need to be ignored for static file extensions that are going to be handled by the StaticFileHandler.

routes.IgnoreRoute("{*staticfile}", new { staticfile = @".*\.(css|js|gif|jpg)(/.*)?" });

But wait, another catch! System.Web.StaticFileHandler does not correctly set the HTTP response headers correctly for caching when serving files from plugins. It works perfectly when serving files from the file system. In order to fix this, a http module needs to be created that looks to see if the file was served from the StaticFileHandler and set the cache headers or use a different StaticFileHandler. Super secret 3rd option (which is sort not good), is to serve all static files from the main MVC project.

Generally speaking that is it. No hidden projects, mirrors or DLL references. A bonus is the plugins will run independently from the main MVC project when doing development if needed.

Some areas that can be improved.
-Better assembly handling in the file and path providers.
-Loaded routes, filters, ect from plugins using MEF (or similar)
-Use/write a better static file handler

Github repo with example: https://github.com/Oobert/ASP.NET-MVC-Plugins

ASP.NET Dropin DLL Plugin – Part One

Wednesday, June 12th, 2013

My intro to web programming was with PHP and scripts such as phpBB and other internet forum software. I always like that installing a plugin normally just worked. You would drop a folder into some directory and the script would see it and you could install it. I have yet to really see this recreated in ASP.NET MVC.

For the past year or so I have been trying to find a way to recreate this. There are many blog posts and half tutorials on this. There is even a few libraries out there on how to do this.

And old blog post from 2008 was my starting off point. It talked about Virtual Paths. It worked but the syntax was terrible.

I knew if I was going to do this, I wanted everything to just work as easily as possible. I also wanted the plugins to be runnable on there own if the developer wanted (for dev and debug reasons).

Griffin.MvcContrib has a way to do this. It seems overly complicated to me. So I kept at it.

After some more searching I found an example of some code that implemented a virtual path provider. I don’t know from where or who but I feel bad because I would like to give them credit. I finally had enough to start tinkering on my own.

I finally have something to show for all of this. I have posted on github a working example of how to create a ASP.NET MVC plugin system. This system allows for DLLs that contain all necessary files, compiled or embedded, to be dropped into the bin directory of a main site and then those files served from the DLL.

Over the course of a few more post, I will cover how the important bits work and what the gotchas are. If you need this now, check out the github project. Currently, it has one plugin that has JavaScript and image examples.

Questions are always welcome.

ASP.NET Dropin DLL Plugin – Part Two