Mocking out and ref parameters with Rhino Mocks

There doesn’t seem to be that much information about how to mock ref and out parametered methods using Rhino Mocks, and what I did find was not overly useful and/or mutually contradictory (maybe I was using the wrong search terms – who knows?). So here is how you do it – and yes it does work with ref parameters too, something that other sites seem to deny.

For testing a method MyMethod in MyClass with the definition:

public void MyMethod(string test, string test2, ref MyObject obj);

Do the following in your test class:


private IMyClass _MyClassMocked = MockRepository.GenerateMock<IMyClass>(); 
 
[Test]
public void Test_Method()
{
        MyObject obj = new MyObject();
        _MyClassMocked.Stub(x => x.MyMethod("test", "", ref obj)).OutRef(
                 new MyObject()
                 {
                    ...
                 }
            );
}

Just change the ref to out for out parameters.

Advertisements

Increasing the security of AJAX requests from the browser

Just a quickie.

I’ve a situation where I need to use AJAX to get a list of items for a particular user.

The for the request is in a hidden field (i.e. fully publicly viewable) in the DOM

e.g. http://www.example.com/users/alexhardman/items

The problem with using the username here is that it is human readable which makes it very easy to hack by changing on or more of the characters.

To increase the securing I’ve added a guid row to my user table which will be used to retrieve users.

e.g. http://www.example.com/items/for/7275670d-f06d-4be2-b260-4c8e094ead6c

This makes it infinitely more difficult to hack the url and return information for a user other than the one given in the url.

e.g.

Using different web.config/NHibernate.config settings for each Visual Studio release configuration

When you have a development, test and production environment it is likely that each one has different connection strings and other application settings. To avoid the tedium (and any errors) of having to manually change the config files each time you change configuration then I suggest Scott Hanselmann’s method of using a pre-build command that chooses one out of multiple config files (one for each configuration) is a less error-prone way of doing it.

His article is here.

There are several other things to note here:

  1. The pre-build command is not quite correct (for my system anyway). Instead of:
    "$(ProjectDir)copyifnewer.bat" "$(ProjectDir)Web.config.$(ConfigurationName)" "$(ProjectDir)Web.config"
    

    You will need:

    call "$(ProjectDir)copyifnewer.bat" "$(ProjectDir)Web.config.$(ConfigurationName)" "$(ProjectDir)Web.config"
    
  2. If you are using NHibernate then you will probably also want to change the NHibernate.config file between releases. In which case simply add another line to the pre-build event:
    call "$(ProjectDir)copyifnewer.bat" "$(ProjectDir)Web.config.$(ConfigurationName)" "$(ProjectDir)Web.config"
    call "$(ProjectDir)copyifnewer.bat" "$(ProjectDir)NHibernate.config.$(ConfigurationName)" "$(ProjectDir)NHibernate.config"
    
  3. If you are using SourceSafe then you will need to make sure that your Web.config and NHibernate.config files are checked out prior to building, otherwise they are read-only and the copy process won’t be able to overwrite them (and you probably wouldn’t want it to anyway).
  4. Of course any new application settings etc probably have to be added into all versions of the config files, rather than just the one.

This method saves a lot of mistakes being made in more complex web.config files.

CAS with MVC and Sharp Architecture

To integrate the central authentication system into an MVC/Sharp Architecture website do the following:

Download the dotnet-client-1.0-Bin.zip file from the following link, unzip and put the dll and related files in your bin directory. Follow the instructions on how to configure your web.config:

https://wiki.jasig.org/display/CASC/.Net+Cas+Client

3 points to note here:
(a) the instructions say that the position of the casClientConfig section in the web.config is unimportant. It isn’t, it needs to go after the configSections section.
(b) I found that I needed to set the ticketValidatorName attribute in the casClientConfig to Cas10, as we are still using CAS 1.0.
(c) The path attribute in the authentication section should not have a trailing slash, or CAS seems to get discombobulated if you try to go to your home page. This might be more to do with the configuration of my particular site though, as I am using a virtual directory.

If you are using a Sharp Architecture project then you can now just decorate the controller methods you want to protect with the Authorize attribute, i.e.:

[HttpGet]
[Authorize]
public ActionResult MyMethod()
{
      ...
}

You can also decorate the class with Authorize to protect all the methods in that controller.

You will probably need a log out controller method if you want to provide the user with a link to log out. This is probably best in a separate controller but it’s up to you! This is the method:

public class SecurityController: Controller
{
       public ActionResult LogOff()
       {
            CasAuthentication.SingleSignOut();
            return RedirectToAction("Index", "Home");
        }
}

For those who aren’t using Sharp Architecture projects you can follow this link for how to set up a standard MVC project for CAS: https://wiki.jasig.org/pages/viewpage.action?pageId=32210981

Handling a browser back-button press with MVC

If you need MVC to reload a view via a controller method, even when the browser’s back button has been pressed, then you need to tell the browser to disable caching of that page. This can be done using the OutputCache attribute on the controller method that displays the view.

[HttpGet]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")] 
public ActionResult MyView()
{
  ...
}

This method will then be called every time the browser displays that view. If you want to pass information to this page (that wasn’t in the original URL), then the ‘next’ view needs to put that data in a Session variable so that it is available when the user presses the back button.

Note that there are also jQuery plugins that can read your browser history but they all seem to have Internet Explorer compatibility issues.