Showing posts with label Asp.Net MVC. Show all posts
Showing posts with label Asp.Net MVC. Show all posts

Thursday, 6 February 2014

Updated Json.Net and now OWIN errors

I took the step on an Asp.Net MVC 5 application last night to update all of the nuget packages in the entire application to be the latest. The main reason for this was I added SignlR to the solution and it required a newer version of OWIN which is fine. With the update of all packages came the update to Json.Net to the newly released version 6 and on fire up of the application I got the following error:

Could not load file or assembly 'Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Using the information in the error message I added the following snippet into the runtime element in the web.config to resolve the issue:

<dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="6.0.0.0" />
</dependentAssembly>

I think nuget is a great concept but I still think there is a bit of an issue when it comes to multi packages which rely on a specific package which then is updated later if you update all. In the future I will be more selective on which packages to update.

Wednesday, 22 January 2014

RavenDB Import / Export in code

The recommended way of doing backups automatically is using Smuggler on the server in a scheduled job or if you do manual backups and restores it’s through the RavenDB management studio but what happens if you’ve not got the ability to do either of those? It’s time to build in import/export functionality into your application.

This was a requirement that I was looking at a while back and then when I did some further investigation more recently I had found a thread on the RavenDB Google group and the associated pull request to allow for smuggling functionality without the http server running; problem solved! So how can it be used?

The changes that were made extracted out an interface ISmugglerApi to allow for a common mechanism for both the server/http version and the internal embedded implementations.

So how do we backup? This is an implementation from an MVC application perspective. Context is a way to determine the difference in implementation if you require to develop and/or deploy onto the different platforms.

public async Task<ActionResult> Backup()
{
    SmugglerOptions smugglerOptions = new SmugglerOptions { BackupPath = Server.MapPath(ServerMapPath) };
    switch (Context)
    {
        case Context.Embedded:
            DataDumper dumper = new DataDumper(((EmbeddableDocumentStore)MvcApplication.Store).DocumentDatabase, smugglerOptions);
            var embeddedExport = dumper.ExportData(null, smugglerOptions, false);
            await embeddedExport;
            break;

        case Context.Server:
            var connectionStringOptions = new RavenConnectionStringOptions
            {
                ApiKey = “insert ApiKey”,
                DefaultDatabase = “db_name,
                Url = “http://localhost:8080”
            };

            var smugglerApi = new SmugglerApi(smugglerOptions, connectionStringOptions);
            var serverExport = smugglerApi.ExportData(null, smugglerOptions, false);
            await serverExport;
            break;
    }

    return File(Server.MapPath(ServerMapPath), "application/binary", "backup.dump");
}

For the embedded version you specify the mapped server path on the local machine at the location the server will write the file to, initiate a new instance of the DataDumper class and call ExportData. There is no need for a stream or to get the incremental flag for this basic usage.

The hosted server version you have to specify they api key, database name and the url of the server to use. These are all bit of information you should know if you or can get access to if you are developing in this way. Once this is established you can call ExportData in the same way as the DataDumper call.

Restoring the backed up file is very similar but in reverse.

public async Task<ActionResult> Restore()
{
    SmugglerOptions smugglerOptions = new SmugglerOptions { BackupPath = Server.MapPath(ServerMapPath) };
    switch (Context)
    {
        case Context.Embedded:
            DataDumper dumper = new DataDumper(((EmbeddableDocumentStore)MvcApplication.Store).DocumentDatabase, smugglerOptions);
            var embeddedImport = dumper.ImportData(smugglerOptions);
            await embeddedImport;
            break;

        case Context.Server:
            var connectionStringOptions = new RavenConnectionStringOptions
            {
                ApiKey = “insert ApiKey”,
                DefaultDatabase = “db_name”,
                Url = “http://localhost:8080”
            };

            var smugglerApi = new SmugglerApi(smugglerOptions, connectionStringOptions);
            var serverImport = smugglerApi.ImportData(smugglerOptions);
            await serverImport;
            break;
    }

    return View("Index");
}

There are many other options which can be used but the above is one of the simplest implementations.

When I was doing some research on how to use this mechanism there were no examples I could find in the blogosphere however reading the the code and looking at the unit tests of the RavenDB source it was enough of an example to work with. I’d highly recommend reading the unit tests and the source of open source if you are struggling to find examples of how to use it; it is good documentation especially if the mechanism you are trying to use is used in the software itself.

Sunday, 19 May 2013

Asp.net MVC Output Caching During Development

During some Asp.Net MVC development for a public website recently I have been looking at caching. The content of the site has minimal churn so I looked to use OutputCache. This works fine once it’s been finished and released. However it causes frustrations during development when you want to change something, compile, refresh and nothing happens.

One option is to comment out the OutputCache attribute, either on each action or on the specific controller, during development but that seems a bit crazy and isn’t sustainable. So what can we do about this?

A Preprocessor Directive is one potential answer; especially the #if and using DEBUG value for example:

#if !DEBUG
    [OutputCache(Location = OutputCacheLocation.Any, Duration = 36000)]
#endif
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

Now when you build in debug mode it will disable the caching and then once you’re happy and ready to release, change the build to “release” and it will be included ready to deploy to the production environment.

Tuesday, 7 May 2013

Tournament – Results and Calculating Scores with RavenDB Indexes

This is the 4th part of a series that is following my progress writing a sporting tournament results website. The previous posts in this series can be found at:

In the previous post I explained the basic CRUD operations and interesting routing issues which I found to get the setup I was looking for.

What do I want to achieve?

By the end of this post I will have shown you how I have started the process off of saving match data, how I have chosen a jQuery plugin to aid with the user interface when entering results and my first run at a calculated index to calculate the scores of the matches so far.

Match up details

The arguably most important part of a result stats website is recording the match ups between players and the outcomes. Once this is done the accumulation of the result scores can be implemented. How they are linked to Events is a small issue compared to recording the actual results.

Let’s start with the first part and see how it goes.

So let’s take a look at some of the potential scenarios which could happen and how we will deal with them.

  1. Single and Doubles match ups with home and away players
  2. Players could play for the other team due to number match ups
  3. Players could move club between events
  4. Ringers could play for any club at any time

To address these issues for each match up there needs to a be a collection of home players and away players. These will be the player records at the point in time at which the match up takes place; the assumption here is the match details won’t be changed after any player changes are made for future events. As we’re using a document database for this and the root is the match then each match will have an instance of the player record at that time point when it occurred.

public class Match : RootAggregate
{
    // todo: link to leg
    public Classification Classification { get; set; }
    public Result Result { get; set; }
    public Team WinningTeam { get; set; }
    public Team HomeTeam { get; set; }
    public Team AwayTeam { get; set; }
    public ICollection<Player> HomePlayers { get; set; }
    public ICollection<Player> AwayPlayers { get; set; }
    public ICollection<Comment> Comments { get; set; }
}

As we can see above we also want a reference to both the home and away teams as well as the winning team. With these details by themselves it would work fine and store the data as required. I have decided to include a Classification enum to make it easier to distinguish between Singles or Doubles match ups (the doubles classification will also be used for 3 on 2 match ups). Due to the issue of 3 on 2 scenarios I’ve kept the players as collections and not explicitly player 1 and player 2. In addition to this I’ve added in an associated “Result” enum value. 

public enum Result
{
    Incomplete = 0,
    Draw,
    HomeWin,
    AwayWin
}

Having this result value will aid with determining the scores without having to do comparisons between different properties (and potential sub properties) with the aim to make the score index calculations cleaner to read.

Chosen

Chosen is a jQuery plugin to aid with making dropdowns and multi selects more user friendly. I first came across this about 12 months back when it was introduced at work to aid with large dropdown selectors. I decided to use this because I would be selecting individual teams from dropdowns but mainly I would be selecting multiple players from a multi select form input and wanted to make it keyboard friendly to speed up result entry.

image

As you can see from the small screen shot above it aids with single selection and makes the multi select look cleaner by hiding the “noise” around a default vanilla multi select input form control.

I’m not completely sold this will be the final solution for this issue however it performs as required for now. When I get to working on the UI then I will decide if Chosen is the best way to go or to find an alternative solution.

Score calculations

I had read multiple blog entries on how to do a Map / Reduce index in Raven DB. The general concept of this is to map from a document collection into a simple form with a counter set to 1 which can then be collated and grouped on a property and the counter value can be aggregated to get the full result. This would be fine however I want to count Wins, Losses, Draws and eventually Extras per player in one index. I knew there had to be a way but what was it?

This is when I discovered AbstractMultiMapIndexCreationTask. It works in a similar way to the more basic AbstractIndexCreationTask<T> however instead of having a specific type it “maps” - as defined by T – it allows for a generic method called AddMap<T>. AddMap allows the document type to be defined and then to map into a separate result type (as per the AbstractIndexCreationTask) however you can call this as many times as you like (although I’d imagine there was a limit somewhere either implementation wise or coding standards wise) on any number of document collection types.

Using the AddMap method I added in a “map” for Home wins / losses, Away wins / losses and Draws irrespective of if the player was playing at home or away. I will look to build on this in the future to do more stats for points such as “performs better on home soil” type scenarios.

AddMap<Match>(matches => from match in matches
                    from player in match.HomePlayers.Select(x => x)
                    where match.Result == Enumerations.Result.HomeWin
                         select new Result
                         {
                              PlayerId = player.Id,
                              Wins = 1,
                              Losses = 0,
                              Draws = 0
                         }
                );

Above is one of the AddMap calls. Looking at this you can see how we can determine, using a combination of HomePlayers and Result value, that the home players have a win. After another internal code review I have noticed that I didn’t need to do the Select(x => x) however this was left over from earlier development when I was looking at extracting out just the player id and will be updated.

I now had the “mapped” part of the implementation. At this point I have a collection of Result objects with each entry being the result of an individual match per player in that match.

The Reduce part is a simple aggregation using the PlayerId as the group key. This can be easily established using the code below.

Reduce = results => from result in results
                    group result by result.PlayerId
                    into r
                    select new Result
                        {
                            PlayerId = r.Key,
                            Wins = r.Sum(x => x.Wins),
                            Losses = r.Sum(x => x.Losses),
                            Draws = r.Sum(x => x.Draws)
                        };

This will give you a result record per player, who has played at least one match, and their “record” for all events.

At this point it got me the data I wanted but I also wanted to display the player information as well as the results. I first started off looking to do a “join” between the index results and a Player query although I realised I was still thinking too “relational” and needed to find another cleaner option; enter TransformResults.

TransformResults is another function on an index which you can access much like AddMap and Reduce. The tooltip description is a bit cryptic “The result translator definition” but if you allow Visual Studio to work its magic to set out the signature it makes a bit more sense …

TransformResults = (database, results) =>

What this gives you is a delegate in the form of a function expression which takes in IClientSideDatabase and the IEnumerable<T> of your results set which is the outcome of the Reduce we did earlier. The IClientSideDatabase interface, and it’s associated implementation which gets passed in by RavenDB at run time, is purely a lightweight data accessor. As per the documentation the methods are used purely for loading documents during result transformations; perfect! Using this mechanism I was able to Load the player record for each of the result values to be able to access the additional information.

TransformResults = (database, results) => from result in results
                            let player = database.Load<Player>(result.PlayerId)
                            select new Result
                                          {
                                              PlayerId = result.PlayerId,
                                              Player = player,
                                              Wins = result.Wins,
                                              Losses = result.Losses,
                                              Draws = result.Draws
                                          };

Conclusion

In this post I have gone over how I’ve decided to model match information, used a jQuery plugin called Chosen to aid with the user experience when adding / editing a match data and how I used a AbstractMultiMapIndexCreationTask derived index in Raven DB to calculate the scores for each player, returning their scores along with their player data.

As always you can follow the progress of the project on GitHub. Any pointers, comments, suggestions please let me know via Twitter or leave a comment on this blog.

Wednesday, 24 April 2013

Tournament – Learning to CRUD

This is the 3rd part of a series that is following my progress writing a sporting tournament results website. The previous posts in this series can be found at:

In the previous post I explained the setup that I will be using for my project. In this post I will go through the basic CRUD operations and interesting routing issues which I found to get the setup I was looking for.

What do I want to achieve?

By the end of this post I will show you how I have managed to sort out the CRUD operations for a simple Entity object including working with RavenDB to get auto incrementing identifiers. I will also describe the tweaks to the default routing definitions to allow for the url pattern I want to continue to work with for the public urls.

Should your Entity be your ViewModel?

After my post the other day about your view driving data structure I decided to put in ViewModel / Entity mappings after originally writing the CRUD setup straight onto both my Team and Player entities. I didn’t like the fact that there were DataAnnotations in my data model so I refactored it to use ViewModels instead to avoid this “clutter” and keep the separation between View and Data. To aid in the mapping between the two types I Nuget’ed down AutoMapper.

To keep with the default pattern of everything which is required by the application being setup in Global.ascx.cs in Application_Start but done through calling static methods into specific function classes in App_Start I created an AutoMapperConfig class with a static register method (see below).

public class AutoMapperConfig
{
    public static void RegisterMappings()
    {
        // Team
        Mapper.CreateMap<Team, TeamViewModel>();
        Mapper.CreateMap<TeamViewModel, Team>();

        // Location
        Mapper.CreateMap<Location, LocationViewModel>();
        Mapper.CreateMap<LocationViewModel, Location>();

        // Player
        Mapper.CreateMap<Player, PlayerViewModel>();
        Mapper.CreateMap<PlayerViewModel, Player>();
    }
}

With doing this I can keep all my mappings in a single place and it won’t clutter the Global.ascx.cs with unnecessary mess.

Auto incrementing Ids

The default setup for storing documents in RavenDB is using a HiLow algorithm. However this does not give the auto incrementing id functionality I’d like. Why will this not do? Well the id makes up part of the url route linking to the individual entity and I want to keep that as sequential and not dot about. The default ID creation would be fine for Ids which aren’t exposed to the public but they will be in this application.

Thanks to the pointers from Itamar and Kim on Twitter I was able to achieve the desired effect without much trouble at all. In the create method on the TeamController when storing the data I had to call a different override to the Store method and specify the collection part of the identifier to use.

RavenSession.Store(team, "teams/");

And that was it.

Routing setup

There was two issues when it came to routing; accessing the record for admin functions and accessing the details of a specific entity to keep with the routing in the current site. Default RavenDB ids are made up of the collection name of the document and the id eg “teams/2”. To get Asp.net MVC to understand these the controller actions which accept an id need to be changed from int to string

public ActionResult Edit(string id) { .. }

And the default route gets updated as follows:

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

On a brief look it might not look like anything has changed however the {id} part of the url has been updated to {*id} to allow for anything before the id part – this will allow the Raven DB default collection based indicators to match eg. teams/2

The next part was the public routes to see the details of the different entities. Let me explain this a bit further. The default url to access teams is /team and for a specific team I want to have a url which follows the url pattern of /team/{id}/{slug} eg /team/1/team-name-slug-here. This is to partially aid with SEO but also make the urls more human readable when posted on forums, twitter etc.

This can be established using the following route:

routes.MapRoute(
    name: "EntityDetail",
    url: "{controller}/{id}/{slug}",
    defaults: new { action = "detail", slug = UrlParameter.Optional },
    constraints: new { id = @"^[0-9]+$" }
    );

The constraint is to limit the matching to integer values only – remember routes match from specific to general. We want to limit the restriction to just this url pattern only.

The next hurdle to over come was the issue with the raven DB identifier which includes the collection name (eg teams/2 or players/5), all I want is the integer part to make up the url and hence match the url route pattern which we defined above. To do this I wrote a small extension method which works on a string. It’s very basic, see below. 

public static string Id(this string ravenId)
        {
            var split = ravenId.Split('/');
            return (split.Count() == 2) ? split[1] : split[0];
        }

This will allow me to reference the identifier properties on my view models however be able to access the integer part of it to setup the route for the entity specific none admin views. So how do we use this?

<viewModel>.Id.Id()

Conclusion

In this post I have shown how to setup the basic mappings between entities and view models. In addition to this I have shown how I made Raven DB play nice with sequential incrementing identifiers. I have also discussed the current routing requirements and how to extract out the integer identifier part of a Raven DB collection identifier to be able to set these as required.

In the next post I will briefly discuss how I am planning on saving match results and take a look at the first attempt at using indexes in Raven DB to calculate each players results.

As always you can follow the progress of the project on GitHub. Any pointers, comments, suggestions please let me know via Twitter or leave a comment on this blog.

Monday, 22 April 2013

Tournament – Project Setup

For the first few iterations of this project it will be based in a single Asp.Net MVC 4 Internet Web Application. This can be found through the regular File > New process in Visual Studio. I may at some point decide to break it up into different projects but at the moment I don’t see an immediate need and don’t want to over complicate it at the beginning.

Once Visual Studio has setup the project and is happy then it’s time to add in the required packages to use RavenDB. Most of the development will be done using just the client RavenDB functionality as I have a RavenDB server running locally however when I get close to deployment I will create it so that it can either run with a dedicated server instance or in an embedded way.

The NuGet packages which I have installed are the following:

<package id="RavenDB.Client" version="2.0.2261" targetFramework="net40" />
<package id="RavenDB.Client.MvcIntegration" version="2.0.2261" targetFramework="net40" />

These give us the basics required to get the data access rolling as well as a way to start profiling what is going on.

I’ve decided to go for the setup of having the DocumentStore instance setup in the Global.ascx.cs on Application_Start and then create a session on each action call via a BaseController and finalise at the end of the call of each action. After some Googling this seems to be a simple and common way to setup a RavenDB session, avoiding DRY situations and I read somewhere (can’t remember where) that creating a session is relatively inexpensive processing wise. If this changes or I find an issue with performance then I may need to come back to it.

The base controller is very simple …

public class BaseController : Controller
{
    public IDocumentSession RavenSession { get; protected set; }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        RavenSession = MvcApplication.Store.OpenSession();
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.IsChildAction)
            return;

        using (RavenSession)
        {
            if (filterContext.Exception != null)
                return;

            if (RavenSession != null)
                RavenSession.SaveChanges();
        }
    }
}

Now we’re ready to roll!

As always you can follow the progress of the project on GitHub. Any pointers, comments, suggestions please let me know via Twitter or leave a comment on this blog.

Thursday, 18 April 2013

My Journey with Asp.Net MVC and RavenDB – Introduction to Tournament

The idea of this journey is based on a number of reasons. The main two are to learn how to use and work with RavenDB, focusing the usage in an Asp.Net MVC context and the other is to re-work a site which has been live for the past 4 years which has had minimal change over that time and needs a refresh and admin functionality.

I have chosen to use RavenDB as the backend of this system due to the nature of how the data is stored. The site is a sporting results site so once an event has taken place the results will not change. They may need some tweaking while entering them but once in and confirmed they won’t change. Due to this a relational database I feel isn’t the best fit for the data. Reading and speed of reading the data is the main function. The current site calculates scores on the fly all the time where as this isn’t required due to the previous reason of once the results are in they’re in.

I have decided to post the code onto GitHub during the development so the world can see how I’m progressing. I will also be posting about what I have learnt, what issues I’ve come across and how I’ve over come them. Also I believe it’s a good way to show case of what I am capable of. This series won’t be a step by step walk through but I hope with looking at the code and the description of the main parts in the blog it should aid others in how to get up and running.

Any pointers, comments, suggestions please let me know via Twitter or leave a comment on this blog.

Let’s start the journey ….

Wednesday, 20 June 2012

Testable client side view model with knockout without any server side dependencies

After reading the blog post series looking at creating a testable application with a JavaScript by Peter Vogel which looked at setting up the server side and the client side view model using Knockout I couldn’t help but think JavaScript needs a way of doing a kind of dependency injection so it can be unit testable without the reliance on the server side.

I understand that it will have a reliance on the server side to output the tests, however this is down to the implementation of the project not a requirement of unit testing.

View model creation

The view model is setup in a very similar way to how Peter had it in his example with a couple of tweaks to allow for the “DI” to function.

var Customer = function () {
    this.CustId = ko.observable();
    this.CompanyName = ko.observable();
    this.City = ko.observable();

    var self = this;

    this.getCustomer = function (custId) {

        MyApp.Customer.getCustomer(custId, this.updateData);

    };

    this.updateData = function (data) {
        self.CustId(data.CustomerID);
        self.CompanyName(data.CompanyName);
        self.City(data.City);
    };
}

We start by setting up the properties of the view model with the Knockout observables, set a reference to it’s self to be able to reference them later (good practice with Knockout from what I can gather), a callback binding function and the first “action” function on the model; getCustomer.

The getCustomer method calls into the data service passing in the parameters it requires for the action to execute and a callback function to call on the result. This could easily be expanded so that error handling can be caught and handled by another callback function but for this we’ll keep it simple.

With the view model set, the data service contract defined and being called in the function the view model is clean and not cluttered. At this point we can take a look at the data service “interface”.

Client side data service

var MyApp = MyApp || {};
MyApp.Customer = {};
MyApp.Customer.getCustomer = function (custId, callback) { };

The data service is built up with JavaScript object notation. The first two lines is to make sure that firstly there is a “MyApp” defined and it has a “Customer” property. Then the getCustomer function is defined with the set parameters required for execution and the delegate for the callback. Doing it this way you also add it into your own applications namespace and avoid cluttering up the global name space.

Lets look at the implementations for unit testing and for the actual application implementation.

The Unit Test

The test we are trying to pass is relatively simple and still based on Peter’s from the original series.

test("Get Customer",
    function () {
        stop();
        cust = new Customer();
        cust.getCustomer("ALFKI");
        setTimeout(function () {
            equals(cust.CustId(), "ALFKI", "ID not correct");
            equals(cust.CompanyName(), "My Company", "Company not correct");
            equals(cust.City(), "Reading", "City not correct");
            start();
        },
    3000);
    })

All it is trying to do is call getCustomer and make sure the data returned is bound to the correct properties.

Data service in testing

For testing purposes the view model test requires a populated JSON object to be returned from the data service. To enable the test to pass and remove the reliance on the server side test controller I create a mock client side data service before the qunit tests are added to the page.

var MyApp = MyApp || {};
MyApp.Customer = {};
MyApp.Customer.getCustomer = function (custId, callback) {
callback({ CustomerID: custId, CompanyName: "My Company", City: "Reading" });
};

All this is doing is following the contract/interface as defined for the data service, but instead of calling into a server side action it is returning a “mock” object. At this point we have removed the need for any server side calls.

After this has been defined we can now write our unit test (as above) and test that JSON object values which are being returned are bound to the correct properties.

Application implementation

So now we’ve created a mock data service and got our unit tests passing for the view model it’s time to create the actual implementation to allow for server communication and getting actual data.

var MyApp = MyApp || {};
MyApp.Customer = {};
MyApp.Customer.getCustomer = function (custId, callback) {
    var url = "@Url.Action("CustomerById", "Home")/" + custId;
    $.getJSON(url, null, callback);
};

As you can see we follow the same pattern as before but the difference is the getCustomer body implementation. We can now call into the server action and using jQuery’s $.getJSON method retrieve some json data from a server. The callback function is passed into the $.getJSON method which will delegate what needs to be done when the data is returned.

Conclusion

So to conclude client side unit tests do not need to have reliance on server side actions to execute even if they require data to be returned from an action. Some people may argue that the unit test isn’t testing the responses back from the server and handling them correctly. To do this you could go down the test controller route and get the server side to through actual errors or you could get the mock call to throw the errors.

If you have any comments about the above please post them below or contact me on Twitter - @WestDiscGolf.

Tuesday, 19 June 2012

Asp.net MVC 4 WebAPI RC - What on earth is “Antlr3.Runtime”?!

I upgraded to the latest version of Asp.net MVC 4 at the weekend which is the newly released “RC” so thought I’d have a play and see what’s changed.

On doing File > New on a new MVC 4 / Web API project a newly clean crisp solution loads up in Visual Studio. Just out of interest I make sure it builds – can’t be too careful with these “pre-release” builds. The solution builds fine so it’s time to explorer …

I expand the project references to see what dependencies the project now has and the list is quite large. The usual suspects are there; EntityFramework, System.Web.Mvc, System.Web.Razor etc. but I’m greeted by some un-usuals.

Disclaimer: I’ll point out now I didn’t do this check on the Beta so I’m not sure if some of the following where there before.

The first one is new and expected; Newtonsoft.Json. We’ve been hearing for a while that json.net will be rolled into the final release and here it is. Nice! I’ve been using json.net for other projects for a while and it’s good.

The second two which seem out of place are “Antlr3.Runtime” and “WebGrease”. What on earth are these?

Lets look at WebGrease first …

  • It has an entry in the nuget package file with a version number etc.
  • In object browser it has some of the “Microsoft.Ajax.Utilities” namespace in.
  • The rest seems to do with css, ui etc.
  • Delete it and the app still builds and runs.

Guessing can live with that, but could remove it. What does it do?!

The other remains a mystery; “Antlr3.Runtime”.

  • No entry in the nuget packages
  • Remove it and the default app still builds
  • In object browser from the class names it looks like it does something with Tree structures?!

From doing some searching it relates to parsing grammers etc. to interpret them in your application. Why would that be shipped with asp.net mvc 4? Couldn’t find any documentation to support this so maybe it was an oversight and will be removed from the final RTM version. Will have to wait and see …

Saturday, 16 July 2011

Asp.net MVC 3 / Razor – Using the same view through regular action and Ajax loading

Ever had a view which you wanted to reuse and load through a regular action call or through using the action using a JavaScript call but then it loads in the associated layout multiple times? I had this exact issue recently.

And the solution; in the _ViewStart.cshtml file which specifies the default layout replace:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

with

@{
    Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}

Then in the controllers actions they still continue to return the same view but don’t have any layout associated to it. This could be used to add a specific “ajax” layout instead of none.

Sample project can be found on github.

Saturday, 28 May 2011

Asp.net Mvc 3, Razor and RenderAction

When playing with the Razor syntax for view creation in Asp.net MVC you need to remember its not quite a direct translation between it and the web forms view engine and it is a different syntax. I was frustrated by it earlier in the week and without internet connection continued couldn’t resolve it instantly. It comes down to the syntactic sugar which Razor gives you.

When it comes to methods on the Html helper you can’t use the syntactic sugar by itself you do need to give Razor some parentheses.

Web forms view engine:

<% Html.RenderAction("About"); %>

Razor view engine:

@{ Html.RenderAction("About"); }

not @Html.RenderAction("About")

Thursday, 26 May 2011

GotConnection v0.2

There are a few changes and tweaks from v0.1 in this release. It was after a mini code review by my mate Will who had some suggestions on the connectivity testing which I have incorporated. I’ve also updated the way the options can be passed in to closer match the original way I wanted it to work.

Update to connectivity testing

Instead of specifying if you are connected or not this release has been updated to try and connect automatically and if no connection is available then use the in development settings. When you go live this can be turned off so if there is an issue with Twitter in a production environment it will return an empty string. This will need to tested for in the consuming code but a small price to pay for testing connectivity. This is driven by a configuration switch:

<add key="GotConnection.Twitter.InDevelopment" value="true" />

While testing the code the request for data from Twitter is relatively speedy so putting this functionality into a try/catch didn’t feel like a bad thing.

Update usage

The original plan was to allow the options to be specified with an anonymous object in much the same way in which you can override defaults in jQuery functions by passing in a json object. This release has now been updated to allow for this for the same options as in v0.1. I will look to expand to the rest of the Twitter API Timeline options in later releases.

Using default options:

GotConnection.ITwitter twitter = GotConnection.ConnectTo.Twitter();
var result = twitter.TimeLine("WestDiscGolf");

Specify options:

GotConnection.ITwitter twitter = GotConnection.ConnectTo.Twitter();
var result = twitter.TimeLine("WestDiscGolf", new { count = 5 });

Valid options:

format = Defines the format in which you want the result to return. The limitation is still currently only json for offline development; default = json.

count = Defines the number of status records to return in the call; default = 5

include_rts = Specifies if native retweets should be returned in the number of status updates returned; default = true.

Released

The updated code can be found on github. As always any questions or suggestions then please let me know. Also if anyone does find this useful then please let me know if you’re using it and what for.

Monday, 23 May 2011

GotConnection v0.1

As crazy as it sounds with the amount of connectivity out in the wild these days there are still times when you need to do web based development when you’re not connected to the internet. This in itself isn’t usually an issue except for when you’re developing some web service integrations eg. a Twitter feed integration in a website and have no way of accessing the Twitter API. This has been the main inspiration behind this little project as I’m disconnected from the outside world for a couple of hours a day on my commute to and from work and sometimes I want to integrate with Twitter.

So I present GotConnection v0.1.

“How do I use it?”

The concept is pretty simple. You include the library into your asp.net web forms or asp.net MVC or any .net project and where you would write the code to create the web request to extract out the json from Twitter service server side you do this instead …

ITwitter twitter = GotConnection.ConnectTo.Twitter(new { option = “blah” });
var result = twitter.TimeLine(“WestDiscGolf”, 3);

The result returned is the json representation of the timeline data for WestDiscGolf and the last 3 tweets. Simples.

The interesting part comes when you are working offline and have no access to the internet. To continue to develop against the returned json data you don’t need to do any testing in code, or change any of your consuming code at all. All you need to do is update an application setting in the projects web.config file to say that the component isn’t online anymore. And that’s it.

Limitations

The only feature at the moment is the ability to get a users timeline in json format from the Twitter API. This is mainly because this is the only functionality that I require at the moment. The offline data understands the number of tweets to return, but in this version that’s it.

Future versions

I’d like to expand this project to allow for more options in the Twitter time line functionality, including support for the different formats it can return. I’d like to expand it out to other services which have read only data feeds such as blogger, facebook, generic rss/atom feeds etc. Future versions will use the Options class further. The idea behind the Options class is to allow for passing in options/defaults through as an anonymous object much like jquery defaults are set.

I’m not interested in making this a component which becomes a library to log in/out, post etc. to services such as Twitter as there are many out there already. This is purely there for developing against a read only service when you’re not online.

Where can I get it?

Well it is up on github. This is the first time I’ve uploaded any of my code to github so feel free to look around, fork the code and change it all, add in extras etc. If you do find this useful and add any extras in then please let me know and I’ll see about adding them into the main fork. Probably in the next version or 2 I’ll look at putting it on NuGet but will have to wait and see.

Any questions or issues or ideas or comments then please tweet me @WestDiscGolf

Enjoy!

Wednesday, 12 January 2011

Asp.net MVC2 + HTML5 data-* attributes

So you want to add some custom data to a html element to aid your JavaScript development and adding data values to custom attributes is a big no no so what do you do? This is where the new HTML5 data-* comes to your rescue.

The next issue is you can’t use the usual ActionLink method overloads on the html helper as you can’t pass in ‘-‘ into anonymous types because it is a c# reserved character for subtracting!

So on the train home this evening I came up with the following:

public static MvcHtmlString ActionLinkHtml5Data(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, object htmlDataAttributes)
{
    if (string.IsNullOrEmpty(linkText))
    {
        throw new ArgumentException(string.Empty, "linkText");
    }

    var html = new RouteValueDictionary(htmlAttributes);
    var data = new RouteValueDictionary(htmlDataAttributes);

    foreach (var attributes in data)
    {
        html.Add(string.Format("data-{0}", attributes.Key), attributes.Value);
    }

    return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null, actionName, controllerName, new RouteValueDictionary(routeValues), html));
}

And to use it, you already know how to as its the same way as all the other ActionLink overrides which are already available out of the box with an additional parameter which works the same as the htmlattributes parameter.

<%: Html.ActionLinkHtml5Data(“link display”, "Action", "Controller", new { id = Model.Id }, new { @class="link" }, new { extra = “some extra info” })  %>

It worked like a dream.

The issue with the “-“ being reserved has had a work around in MVC 3 by using “_” and then programmatically changing that to being “-“ in the output. I’ve not looked at the implementation but I can’t see how this is much different to what I’ve already achieved simply above.

Please let me know your thoughts.

Tuesday, 23 March 2010

ASP.net MVC – Exe download and file versioning

We use an application at work which is supplied as a single exe file which is downloaded from their website. The issue is the file has always been called application.exe irrespective of the version. With each new version it just gets overridden and keeps the same file name.

We added a request to the manufacturer a request that the file name include the version so we a) know which version we are getting and b) can keep a couple of historical versions locally just in case. However; due to the length of time they have gone for the single filename it is now linked from many different places and they don’t want to break the links.

It got me thinking, this would be ideal for a route in Asp.Net MVC but can you set the route to accept a string “application.exe” and it do as required. The short answer is yes! :-)

The thinking was setup the route for the single filename. This would execute an action on a controller which would go off to a repository, find the latest version file and then return the file as a DownloadResult to throw up the save file dialog. I had a hunt round the internet and found an oldish post by Phil Haack for this kind of thing. I updated it to map to a specific file, for instance on a file share.

public class DownloadResult : ActionResult
{
public string FileLocation { get; set; }
public string FileName { get; set; }
public string ContentType { get; set; }

public override void ExecuteResult(ControllerContext context)
{
if (!String.IsNullOrEmpty(FileLocation))
{
context.HttpContext.Response.AddHeader(
"content-disposition", "attachment; filename=" + FileName);
context.HttpContext.Response.ContentType
= ContentType;
}

context.HttpContext.Response.TransmitFile(FileLocation);
}
}



Once you’ve got that sorted all that’s left is to add in the route in your Global.asax …



routes.MapRoute("download", "application.exe",   
new {controller = "Home", action = "Download"});




And tad ta :-)



The other options would be routing / redirecting at the IIS/Apache level, but as a developer this seemed to be the easiest and simplest way to enable data access to help with new version releases.

Wednesday, 3 March 2010

Asp.net MVC – When to use strongly typed ViewData?

In short; all of the time unless you have a *really* good reason not to.

With the use of generics being able to specify a strongly typed model per view / partial view is so easy with the baked in functionality in the framework, so why aren’t you using it?

Why?

The whole point of MVC is to have control over markup, enable specific routes and reuse existing views / partial views in different locations among others. It’s not to make your life harder than it already is. The underlying issue is if you don’t have the a strongly typed view model for each view then you don’t have confidence in having complete control over it. Throw in a dev team, potentially, changing the same weakly type code and you’re looking for pain.

When you first start looking at examples of MVC applications, you find examples where people start putting in values in to the ViewData dictionary which is available on the views/controllers.

ViewData["MyKey"] = "Some string value";



This uses the weakly typed ViewDataDictionary which can lead to issues with keys not being present, casting it to the wrong type (potentially) and can lead to unnecessary complexity beyond what is required. This can create hard to maintain spaghetti code in the view markup (can anyone say “classic asp 3” ?) … all of which is bad.




So are you suggesting a ViewData model class per view?




Yes; this is exactly what I’m suggesting. This leads to well structured solutions and keeps the code and views together. This isn’t such a big problem when working on your own, but if you know the system you are writing will be a lot bigger when completed or you work in a bigger team (or both) then it’s better to keep things as simple and clear as possible as early as possible. Set a good foundation to work from.





So my current Visual Studio project layout looks something similar to this :



image 



The view data class definitions and the associated full / partial views are filed away in similar namespaces / folder structures * underneath their associated areas of the solution so that you know which are linked together more easily.





* The views in this case are filed under Document instead of Documents because of the name of the controller, although are potentially incorrectly named  :-)




Summary

So to summarise, why do this? Well it helps to know what you’ve got to play with in each view. It breaks down the specifics which you need to pass into a view/partial view to get it to operate nicely. It also means when re-using partial views you know what to pass into them. Also, with strongly typed goodness it helps with refactoring especially when using tools such as Resharper.





Let me know your thoughts.


Further reading:

MikesDotNetting - ASP.NET MVC Partial Views and Strongly Typed Custom ViewModels

Wednesday, 18 November 2009

Asp.Net MVC 2 Beta released

After checking my morning blog feeds the first one in the list which was of interest was Phil Haack’s post about the release of Asp.Net MVC 2 Beta for VS 2008. I was going to put off downloading it and updating until later but after the teaser about nuclear facilities in the Eula I had to investigate …

This was the full Use rights which he was referring to:

a. Because the software is a pre-release version, and may not work correctly, you may not use it, alone and/or in conjunction with other programs in hazardous environments requiring fail-safe controls, including without limitation, the design, construction, maintenance or operation of nuclear facilities, aircraft navigation or communication systems, air traffic control, and life support or weapons systems.

I should read EULAs more often; Genius!