Output Caching and Authenticated Users

In a recent post, I looked at using a custom parameter with OutputCache to provide different versions of an ASP.NET MVC view to different clients (mobile/traditional devices, AJAX / no-AJAX clients). The one question left unaddressed, however, was: what if there are some circumstances where you don’t want to cache at all?

Output caching means that your code runs once to provide the output, then doesn’t run again until the caching period has expired. In my example, that meant it would run four times for my different circumstances, but not again for each individual circumstance until the timeout had expired. But it turns out that isn’t sufficient to my needs. If the user is logged in, the code needs to run every time.

CocktailsRUs is a community site. Anyone can join, and when they join, they can mark cocktails as favorites for ease of access. Every time they view a cocktail, they can choose to add it to (or remove it from) their favorites, and thus be presented with the appropriate button to add or remove a favorite.

screengrab of remove favorite button

So how do we stop the site from using output caching with authenticated users?

One quick and (very) dirty approach would be to use the GetVaryByCustomString() method to assign a unique value (a timestamp or a GUID) as the cache key for authenticated users. That would ensure the code runs every time, but would also lead to a plethora of unwanted pages in the cache.

Fortunately, there is a much better solution. The Output Cache exposes a callback that allows you to decide whether to return the cached item, or run the code. We can use this callback to determine if the user is authenticated–and if they are, invalidate the cache for this response.

The first thing we need to do is create our own derived version of the Output Cache. That’s straightforward–just inherit from OutputCacheAttribute like so:

inheritance code sample

Then we need to override the OnActionExecuting() method to set up the callback where we will invalidate the cache:

OnActionExecuting code sample

Now all we need to do is implement our OnlyIfAnonymous() method and tell it not to cache if this is an authenticated user. The signature of AddValidationCallback gives us access to the HttpContext, an optional data object (which we don’t need) and the HttpValidationStatus–which is passed in by reference and allows us to ignore the cache for this request. Here is the completed method:

Callback code sample

The one remaining step is to replace the OutputCache directive on our controller method with a reference to our new OnlyUnAuthenticated attribute.

Attribute code sample

Now we have a solution that caches appropriately for anonymous users, but ensures that the code runs every time for authenticated users.

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET MVC

Building Web Applications with ASP.NET and AJAX

Improving Performance with Output Caching

I’ve been spending most of my spare time over the past few weeks refactoring the code for my site, cocktailsrus.com, in the Visual Studio 11 beta–partly to play with the new stuff, but mostly just to replace my original quick-and dirty back end with something more elegant. With the process pretty much complete, the new version of the site will be much more maintainable, as well as more performant and scalable. And I don’t know about you, but whenever I see those two words together, the first thing that leaps to my mind is “caching.”

Caching is a fantastic way of reducing the amount of data access on a website. Unfortunately, it can also be a fantastic way of tying yourself in knots and serving the wrong data to the wrong user. It is just too easy to serve stale data–especially when you transition from a single server to a web farm. So which type of caching to use, and how to avoid serving stale data?

ASP.NET offers two types of caching:  data caching and output caching. Data caching is managed programmatically. Output caching is managed via attributes (MVC) or page directives (Web forms).

Historically, I’ve preferred data caching. I’ve specialized in content management systems over the years, and it’s a very rare situation where a CMS delivers the same content to everyone. Data caching allows very fine-grained control. Unfortunately, it doesn’t play very well with Web farms–at least, not since Microsoft removed some of the core SQL Server technologies that allowed it to do so.

So, given that I want to be able to scale up to a Web farm, the question I asked myself was, Could output caching help my application?

The obvious candidate for output caching is the page that displays individual cocktails. These don’t change very often, and are amongst the most heavily trafficked on the site. Also, and most significantly, retrieving a cocktail from the database involves a complex SQL query with many table joins. (A cocktail has multiple ingredients, related cocktails, an author, etc.) The fewer such calls I make, the better.

On the face of it, caching the individual cocktails should be easy. Each one has a unique ID, so you should need to do is add an OutputCache directive, like this:

output cache directive

Looks easy, doesn’t it? Each time the method is called, the individual cocktail will be cached by its ID for 60 seconds.

Unfortunately, it really isn’t as simple as that. This caching will work–but it will deliver the same version of the output to everyone: mobile device users, AJAX users, non-AJAX users…. You get the picture. A user with JavaScript enabled will suddenly find that they are getting the full page rather than an AJAX payload, leading to pages within pages, like this:

page within page screengrab

So simple caching won’t do. We’re going to need to cache four different versions for each cocktail, specifically:

  1. Mobile with no AJAX
  2. Mobile with AJAX
  3. Standard with no AJAX
  4. Standard with AJAX

Unfortunately, there isn’t a querystring parameter that’s going to allow us to make that distinction, so it’s time for a custom parameter.

The first thing we have to do is override the GetVaryByCustomString() method in the global.asax. Here, we can use the request to filter our caching into the four different groups. The site uses jQuery, and jQuery AJAX requests use the “X-Requested-With” header, so we can use that to determine if this was an AJAX request. That’s half of the problem solved. We can then use the underlying infrastructure (or, perhaps, our own version of it) to find out if this request came from a mobile device.

GetVaryByCustomString code

We then assign this to the controller method and we should have something that caches multiple versions and returns the appropriate version from the cache:

VaryByCustom argument

Which is great… except that when we look at it in Firefox, we have the same old problem:

second page within page screengrab

The issue here is where the caching is happening. Output cache is a clever beast, and it’s automatically offloading the work to the client–which is a great idea, but means that if our client switches from AJAX to non-AJAX versions, we end up delivering the wrong item from cache.

Fortunately, there is a simple solution. The OutputCache attribute accepts a Location argument, which you can use to tell it to cache on the server rather than the client:

Corrected OutputCache attribute

So now I have a caching system that will work happily on a Web farm, significantly reduce data access and provide the appropriate custom view to the client.

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET MVC

Building Web Applications with ASP.NET and AJAX

jQuery: A Comprehensive Hands-On Introduction

Exposing IQueryable/oData Endpoints With Web API

This is a follow on from my post on Web API and the Entity Framework. In that post, I showed a couple of approaches to dealing with JSON serialization problems in the Visual Studio 11 beta. Now I want to look at returning IQueryable from Web API methods.

IQueryable allows you to do what it says on the box: return an object that can be queried from the client. In other words, you can pass through arguments that tell the server what data to retrieve. This is a hot topic on the Web, with some people strongly against the idea and some strongly for it. The argument is between convenience (look how easy it is to get any data I want!) and security/architecture (look how easy it is for someone else to get any data they want).

I don’t have strong views either way. I share the concerns of those who worry about leaving client layers free to bombard the data layer with inappropriate (and potentially dangerous) queries, but I also like the convenience of being able to shape my queries from the client—especially given the Web API’s (partial) support of the oData specification. (For those unfamiliar with oData, it allows you to use querystring arguments to modify the query at the server, e.g., $top=10 will become .Take(10) in the EF query).

If I don’t use IQuerable, I will need to write lots of different methods to allow for different queries (e.g., in cocktails-r-us, I need to search for cocktails by beverage, non-liquid ingredient, name, id, etc.). Here is a simple example from my demo project, with two methods:  one returning an IEnumerable of BeverageTypes, the other a single BeverageType by id:

original version of code

If I want to get an individual BeverageType, I make a get request along these lines: http://[mysite]/api/beveragetype/2. Here is the Firebug output from such a request:

output from non-oData request

If I switch to IQueryable as the return type, however, I can supply both queries from a single method (note the addition of ‘AsQuerable()’ at the end of the method return):

IQueryable version of the code

Now I can write my oData query as “http://[MySite]/api/beveragetype?$filter=id eq 2“, so I no longer need my separate specialized method.

screenshot of oData request and result

Let’s try and simplify the method. The oData specification allows us to expand associations using $expand, so let’s remove the .Include(“Beverages”) call from our method and pass that through on the querystring as follows: http://[MySite]/api/beveragetype?$filter=id eq 2&$expand=Beverages.

Here is the new code:

code without include

And here is the result… not quite what we were hoping for:

result of $expand - no include

It turns out that the Web API does not support $expand…. And I rather hope it never does. If Web API supported $expand, then my users would be able to create huge queries with far too many joins. In cocktails-r-us, I only want to return all the details of a cocktail (ingredients, comments, ratings, related cocktails, etc.) for one cocktail at a time. I don’t want users to be able to join all those tables in one massive query. So, that’s the upside. The downside is that I have to go back to using multiple methods, but even then I should only need two:  one to get a specific cocktail (or, in this case, BeverageType) by ID, the other to return lists of them by whatever criteria the client prefers.

final version of two methods

Since I can deal with security concerns by forcing my clients to authenticate (and only giving access to trusted developers in the first place), and that leaves me with only one concern: will my client developers write ill-advised queries? They might, for example return too many rows at once instead of paginating through the data as I would prefer. Fortunately, there is a solution: the [ResultLimit(n)] attribute. This restricts the number of items returned. So now our remote users will have to page through the data rather than return it all at once.

ResultLimit attribute

If we examine the output in Firefox/Firebug, you can see that only 5 rows are returned even though the query requested all the rows:

output with limit in place

ResultLimit is not a perfect solution. It only restricts the number of items returned from the method, not the number retrieved from the database. Here is what’s happening on the server:

Results on server

However, since the remote user won’t be able to get the data they want the easy way, they will be forced to write oData pagination queries like “http://[site]/api/beveragetype?$skip=5&$top=5&$orderby=Type desc” which would give them the following output on the client:

oData paginated query

I understand why people are nervous about exposing IQueryable, and I wouldn’t do it in a completely open way where anyone’s code can access my data without authentication, but I love its openness and flexibility and the way it works so easily with Web API.

Kevin Rattan

For related information, check out this course from Learning Tree: Building Web Applications with ASP.NET MVC.

Working With the Entity Framework and the Web API

In my last post, I talked about the new Web API controllers in MVC and showed how they work with simple data. In the real world, of course, I want them to work with my existing data, which uses Entity Framework. It turns out that this is far from straightforward (at least, in the beta).

Let’s start by trying to expose some standard EF data. When I began coding my personal website www.cocktailsrus.com I used model-first rather than code-first development. (At that point, my focus was on getting to know jQuery mobile, and I was not concerned with best practices in MVC; I have refactored it since). So let’s go back to basics and begin with an .edmx version of the simple data I used in my last post.

beverageType in designer

The code to return this object using Entity Framework and Web API is as follows (with the result first placed into a  variable  so I can more easily examine the return in the debugger):

code to return IEnumerable of BeverageType

When we try and access this in Internet Explorer, we get the following error message:

“The type ‘BeverageType’ cannot be serialized to JSON because its IsReference setting is ‘True’. The JSON format does not support references because there is no standardized format for representing references. To enable serialization, disable the IsReference setting on the type or an appropriate parent class of the type.”

Interestingly, if we use Firefox, it actually works–but here the response is formatted as XML. Still, that suggests we’re almost there. Let’s make it more interesting. Let’s add an Association to our .edmx file to make it more realistic.

design view of association

And let’s add an Include to our Entity Framework code so that we return the Association along with our object:

code with include

Strangely, we get exactly the same results as before. Internet Explorer gives the same JSON error message. Firefox returns the same XML, without the association. Perhaps turning off LazyLoading will improve the Firefox return?

code removing lazy loading

Sadly, it makes no difference. We get exactly the same error, and since there is no convenient way to change the IsReference setting in an .edmx, perhaps it’s time to switch to Code First Generation and see if we can’t return JSON properly to Internet Explorer.

Here are my types:

code first types

And here is my DbContext:

code first dbcontext

Let’s run it again and see what happens now… And yes–this time, we’ve managed to break both Internet Explorer and Firefox! Both get the following error message:

“You must write an attribute ‘type’='object’ after writing the attribute with local name ‘__type’. “

Now, this error is actually useful. It tells us we need to turn off proxy generation, so let’s tweak our DbContext. And we may as well turn of lazy loading here while we’re at it:

turning off proxy creation

Now the Web API makes a valiant effort, sends through the beginning of a JSON version of the data to both IE and Firefox, and then gives up with an error message:

screen capture error

Here is the error message:

“System.Runtime.Serialization.SerializationException: Object graph for type ‘Beverage’ contains cycles and cannot be serialized if reference tracking is disabled.”

At this point, I imagine we’re all starting to get a little frustrated. I know I am. So, to cut a long story (and a lot of Web searching) short… it looks like the fundamental problem lies in the interaction between the Entity Framework and the DataContractSerializer used in the beta. This is supposed to be fixed by a change to the JSON.Net serializer when Web API goes live – but in the meantime, what to do?

There are two possible approaches (and I’ve placed the code for both online here):

  1. Substitute the JSON.Net serializer in place of the default. For this, you need first to follow the helpful instructions in this blog post: http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx and then
    1. Add an instruction to the serializer to ignore self-referencing loops
    2. Add the new serializer in the Global.asax
  2. Use projection. The suggestions online seem to fall into two camps:
    1. Use projection with anonymous objects.
    2. Use projection with Data Transfer Objects.

But if I did want to use projection, why would I want to:

  1. return anonymous objects when I have perfectly good POCO objects, or
  2. create new DTOs when I already have perfectly good POCO objects?

So I wondered what would happen if I used projection with the same POCO Code First objects that the serializer had choked on when I returned them directly…

projection using code first poco objects

And here is the result in Firefox/Firebug:

output from projection

And in Internet Explorer/F12 Developer Tools

output in IE:

The Web API is going to be great, but it takes a little work if you’re using the beta. If you want to look at the code for either solution I outlined above, it’s available here. (The full project is 13MB, even as a zip, so I just put up the code: if you want it to run, you’ll need to copy the files into a VS11 project and download the various Nugets, as well as getting EF to generate the database for you).

In my next article, I’m going to take a look at the thorny issue of whether to return an IQueryable and—if you do choose to do so—how you can protect yourself against over-large queries.

Kevin Rattan

For related information, check out this course from Learning Tree:  Building Web Applications with ASP.NET MVC.

Building RESTful Services with Web API

One of the features I’ve most been looking forward to in the Visual Studio 11 beta is the Web API. It’s been my long-term goal to build an iPhone app to supplement my jQuery mobile view for my personal website, www.cocktailsrus.com (once I learn Objective-C), and a RESTful API is just what I need. In this post, I’m going to explain what the Web API is and how you can use it. In subsequent posts, I’ll look at the issues with combining Web API controllers with Entity Framework data, and the thorny issue of whether to expose oData/IQueryable endpoints. There’s a lot of ground to cover, so let’s get started.

What is the Web API?

The Web API is a new feature of the latest release of ASP.NET MVC. It adds a new controller base type, ApiController, which allows you to return JSON data directly from RESTful urls. (It was always possible to return JSON from Controllers by using the Json() method, but ApiControllers don’t return views, just serialized data. We can also easily expose oData endpoints: more on that in a later post.)

The Add Controller wizard now has new options:

The controller wizard

When you select an empty API controller with read/write actions, you get a basic stubbed template as a starting point:

The empty controller

There are a couple of changes I need to make at the outset:

  1. I want to return a list of BeverageTypes (spirits, non-alcoholic, wine, etc.) rather than a string array,
  2. I already have a BeverageTypeController as part of my MVC application, so I need to change the namespace from the default (in this case, Cocktails.Controllers) to Cocktails.Controllers.API to avoid a name collision.

Here is part of the changed class with a little sample data for testing purposes:

Method returning IEnumerable

Now I can make the following RESTful query “http://[site]/api/BeverageType” and get back JSON data:

Output from the RESTful call

The controller also stubbed out another method for me that accepted an id argument. With a little refactoring to move my data into a separate method – BeverageTypes() – I can now write code like this:

Get with an argument

Now I can make a RESTful query with an argument, thus – “http://[site]/api/BeverageType/1“:

output from the call

So, it looks like I have a nice, simple way of exposing my data as a RESTful API from within an ASP.NET MVC application. I should be able to consume my data from new clients and/or allow third parties to integrate with my site. Unfortunately, it turns out that once you add the Entity Framework into the mix, things get a whole lot more complicated – and that’s going to be the topic of my next post.

Kevin Rattan

For related courses, check out Building Web Applications with ASP.NET MVC from Learning Tree.

Best Practices for Configuring WCF 4.5

In my last few posts I looked at the new options that WCF 4.5 provides for managing the most awkward part of WCF: configuring the services. I looked at the new options for configuring IIS hosted services in code, configuring (from code) service libraries that support multiple endpoints, loading your config files from a central location (in both service libraries and IIS-hosted services).

So what should you do with these new WCF features? I’m still leery of the using code based configuration because, as I move my service from development to test to production, I’ll want to change the service’s configuration. For instance, at the very least, I want all three versions of the service to have different endpoints. I’m also uncomfortable with letting anyone get access to one of my Web Service’s contract just by tacking “?wsdl” to the end of the service’s endpoint. So, while I’ll leave that feature in place for testing, I prefer to turn it off in the production system. Instead, before moving a Web Service to production, I’ll extract the WSDL document, store it some safe place, and make potential consumers request it from me. Among other benefits, that lets me maintain a list of those consumers so I’ll have some clue who I should contact if I make any changes to my Web Service. Finally, while I want to turn to include all the detail in my exceptions in the test version of my service, I want to turn that off in production, also.

If I’m doing my configuration in code (as opposed to in a configuration file), making those changes is harder, though not impossible. If the parameters are all in a configuration file, I can read the current values from the file using NotePad and update them without having to recompile if I need to. Changing my config file means that I don’t need to modify my code as I move the service from development through to production. Often, I will simply create three versions of my config files for development, test, and production, put the files in place, and just not update them during the release process. That way, as the code moves from test to production, it just picks up the config file at the site (that does mean that I need a separate release process on those occasions when I do need to update the config file). But, even then, configuring in code doesn’t really prevent me from doing that: I can just make sure that my configuration code reads in any critical parameters from my application’s settings. That will get me virtually the same benefits as keeping the whole configuration in a file. If I do that, it’s just a matter of managing the application’s settings in each of my development, test, and production environments (and I’m probably doing that already for other parts of my application that are using application settings).

However, I have to admit, that I do like WCF 4.5′s new feature that allows me to programmatically load config files from a central location. That allows me to keep a separate set of configuration files for each of development, test, and production but not have them spread out in several different locations. By keeping my all three versions of the file in one place, the only thing I have to change in the service as I move it from development to production is the name of the file being loaded by my code in the new environment. But, having said that, I’ll probably keep the name of the file in my application’s settings so I really haven’t changed the problem much: instead of keeping multiple pieces of information in application’s settings (address, metadata accessibility, error detail), I’ll be keeping only one (path to the configuration file). If you think managing one piece of information isn’t that more difficult than managing multiple pieces and find configuring your service with code attractive, you may make a different choice than me. However, I will say that, by keeping my configuration in a file, I can make any configuration change I want without recompiling my code—using code means that you can only make those changes that you planned for in writing your Configure method.

Technology is all very good but deciding when and how to use it is “context sensitive”—different value systems will cause developers to make different choices. One of the things I like best about Learning Tree’s .NET Best Practices and Design Patterns course is that it makes that point and lays out the costs and benefits for the best practices it addresses.

Peter Vogel

Streamlined Web Loading in the Visual Studio 11 Beta

One of the features of Visual Studio 11 that I’m really looking forward to taking advantage of is CSS and JavaScript minification and bundling.

As developers, we like to be able to break our applications into reusable components. That makes development and maintenance much more manageable. Sometimes, however, it can have an impact on performance. The more CSS style sheets and JavaScript files you add to a page, the longer that page will take to download – and it’s not just a matter of the size of the files; the number itself is a problem. Http requests are expensive; the more you have, the slower your page is to load, even if the absolute size of the downloaded files is not very large.

Visual Studio 11 comes with two new features that make it more practical to break our JavaScript and CSS into multiple file. Bundling and minification give us a means of ‘componentizing’ our Web applications, without taking the performance hit of too many http requests. Bundling allows you to combine multiple files into a single larger file. Minification removes unnecessary white spaces to ensure that the new file is as small as possible. Taken together, the two techniques have a major impact on performance.

There are two versions of the functionality: the simple, automatic way; and the much more useful custom approach. In the simple version, the contents of folders are automatically bundled and minified if your <link> and <script> tags to point at the default directories and don’t specify individual files, thus:

<link href=”/Content/css” rel=”stylesheet” type=”text/css” />

That gets converted into html along these lines at runtime:

<link rel=”stylesheet” type=”text/css” href=“/Content/themes/base/css?v= UM624qf1uFt8dYtiIV9PCmYhsyeewBIwY4Ob0i8OdW81″ />

That’s fine as far as it goes, but is also rather limiting. You have to use default locations, and there’s no scope for having different bundles for different versions of your application. In my www.cocktailsrus.com site, I have two distinct versions, for mobile and standard browsers, each of which requires different .css and .js files, so I need to be able to create custom bundles.

The MVC4 template comes with a feature that’s designed to support this – ResolveBundleUrl():

<link href=”@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl (“~/Content/css”) rel=”stylesheet” type=”text/css” />

Now we can define our own custom bundles. In my case, I can create two new sub-folders under the style and script paths, one for mobiles and one for the standard Web site:

Then I change the paths passed to ResolveBundleUrl() to point at my new folders….

<link href=”@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(“~/Content/site/css”) rel=”stylesheet” type=”text/css” />

<script src=”@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(“~/Scripts/site/js”)“></script>

and… it doesn’t work.

Although ResolveBundleUrl() supports adding non-default paths, you have to do a little more work and register your new paths in the application start event in the Global.asax before it can use those paths.

code in the global asax adding bundles

This tells the system that we’re adding two bundles – one for .css files and one for .js, and that all the files in the specified directories should be part of the bundle. (You can also specify individual files if you need to control the loading order beyond the default settings, which first prioritize known libraries like jQuery, then load the files alphabetically).

One nice additional feature is that the bundles are cached on the browser using the generated path (e.g. css?v=UM624qf1uFt8dYtiIV9PCmYhsyeewBIwY4Ob0i8OdW81). This means that not only are they loaded faster the first time the user visits the site, they do not need to be downloaded again the next time. More significantly, if any of the files in the bundled folder changes, so does the generated path. That means your users will never be stuck with old versions of your style sheets or JavaScript files.

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET and Ajax

Building Web Applications with ASP.NET MVC

Managing WCF 4.5 Configuration Files in WCF Service Applications

In the last few posts I’ve been looking at the new options that WCF 4.5 gives you for configuring your services. The first two posts showed how to configure a Web Service in an ASP.NET application and how to configure a service both as a Web Service and as higher-performance TCP-based service in a Service Library. My last post was about how to load your service’s configuration from a central file location. However, I only discussed how that process worked in a Service Library—other than a brief note, I ignored a WCF service in an ASP.NET application (a Service Application). In this post, I’m going to address how to load a service’s configuration file from something other than the web.config file.

One note: I am working with the beta version of Visual Studio 11 and the .NET Framework 4.5 so it’s entirely possible that what I say here may change by the time both products get released to manufacturing.

To begin with, the code you use to load the configuration file in a WCF Service Application isn’t any different from the code you’d use in a WCF Service Library. You still add a static/Shared method called Configure to your service class and put this code in it, pointing to the file containing your service’s configuration:

PublicSharedSub Configure(sc AsServiceConfiguration)  Dim cfMap As New System.Configuration.ExeConfigurationFileMap With {  .ExeConfigFilename = "c:\configs\Service1.config"}  Dim cf As System.Configuration.Configuration cf = System.Configuration.ConfigurationManager.  OpenMappedExeConfiguration(cfMap,  System.Configuration.ConfigurationUserLevel.None)  sc.LoadFromConfiguration(cf) End Sub 

The problem is what you should put in that Service1.config file. In the Service Library, you could fundamentally just copy the system.servicemodel element to the configuration file—the only change you had to make was to convert any relative addresses to absolute addresses. You could avoid even that change by leaving the host/baseaddress elements in your app.config file (you didn’t even have to remove the host element from the config file you were loading—WCF 4.5 just ignored them).

Unfortunately, with a Service Application in WCF 4.5 you don’t have a complete set of tags in your Web.config file to copy. This is the result of another change in WCF 4.5: “WCF simplification”. If an element in the config file is setting the default value for the element then, by default, that element is omitted from the Web.config file. This means that a Web.config file in the .NET Framework 4.5 set up for testing/development can look as simple as this:

<system.serviceModel>  <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true"  httpsGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors>  </behaviors>  </system.serviceModel>

If you just copy this to your config file (Service1.config in my sample code) you won’t be able to use the WCF Test Client to test your application because the Test Client won’t be able to retrieve the metadata it needs to figure out what methods your service exposes. To fix that problem, you need to add a service tag (within a services element) that references your service by namespace and name. And, as long as you’re doing that, during development you probably also want to include all the exception detail in any faults your service raises so you should add the serviceDebug element that lets you specify that with its includeExceptionDetailInFaults attribute.

Putting that altogether, your configuration file should look like this:

<configuration>  <system.serviceModel>  <services>  <service name="WcConfigWeb.Service1"/>  </services>  <behaviors>  <serviceBehaviors>  <behavior name="HttpGetMetadata">  <serviceMetadata httpGetEnabled="true" />  <serviceDebug includeExceptionDetailInFaults="true" /> </behavior>  </serviceBehaviors>  </behaviors>  </system.serviceModel>  </configuration> 

That file will be successfully loaded by the code I showed earlier and make your service available for testing.

Peter Vogel

Simplifying Web Development with Page Inspector

I’ve been playing around with the Visual Studio 11 beta for a little while now, and my favorite thing so far is Page Inspector. I like tools that make my life easier – and Page Inspector just saved me a lot of poking around inside the underbelly of an application.

I have been busy porting my cocktails application to MVC4, Entity Framework 4.5 and Visual Studio 11 ready for its release later this year. It has all gone rather smoothly so far, with the biggest problem being that it doesn’t seem to like the System.Transactions namespace. (So I’ve commented out the transactions for the time being and pressed on – I’ll come back to that when I’ve played with some of the new stuff). I managed to recreate my Entity Model using the latest version, created a new MVC4 project and selectively imported my Web site content–and pretty soon I had the site up and running in Visual Studio 11.

When you’re upgrading, the easiest problems to fix are the breaking errors. You run the project, it blows up – you see that you need to add a missing reference. The more difficult problems arise when something works, but not as you expect. And that’s where Page Inspector became enormously useful.

So what is Page Inspector?

Essentially, it’s a tool that takes the DOM inspection approach of client-side tools like Firebug and the IE Developer Toolbar and applies it server-side. You can click on an element on the page, and not only do you get to see the HTML and the CSS – you also get the server-side files that are responsible for that part of the page. Here is a screenshot, showing Page Inspector on the left.

screenshot of page inspector

In the image, I’ve clicked on the selection icon to put Page Inspector in selection mode. This is what the selection icon looks like:

the selection icon

Once I’ve done that, the panel on the right shows me the server context that provides that section of the page.

And how did Page Inspector help?

I noticed that the new MVC4 internet template offered some improvements to the login process (e.g., Ajax) so I wanted to use the new version rather than the current version. I changed the layout pages to point at the new partial page and then ran the app, only for this to happen when I clicked on the login link:

404 error

So I went back to the page with the link in Page Inspector, hit the selection tool and clicked on the login link – which showed me I was still using the old partial page after all.

page discovered via page inspector

So what had I missed? In the old days (i.e., yesterday) I would have had to:

  • Infer that I was still on the old partial page
  • Work out where that partial page was being referenced from
  • Trawl through the site to find the layout page and make the change

Now all I had to do was…

  • Click on the selection tool to activate it
  • Select the HTML element that contained the Log in link

… and there in the right hand panel was the layout page I’d forgotten to change:

layout page discovered via page inspector

What’s more – I could make the change there and then while Page Inspector was still open.

correcting while inspecting

Page Inspector then told me the source had changed and offered me the opportunity to refresh the page.

warning out of synch

The text then changed from “Log on” to “Log in” – so I could see at once that the correction had been successful.

corrected page

So far, I like Visual Studio 11 a lot. I’ll keep you posted on anything else I find out (both good and bad) as I work through the conversion.

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET and Ajax

Building Web Applications with ASP.NET MVC

Manage WCF 4.5 Service Configurations from One Location

In an earlier post, I showed how you can configure a WCF 4.5 Web Service in an ASP.NET site with a few lines of code in the beta version of the .NET Framework 4.5; in a later post, I showed how you could configure a WCF 4.5 service both as a TCP-based service and a Web Service in a WCF service library, again using nothing but code (and, again, in the beta). But the beta of WCF 4.5 has another goodie in its pack: The ability to load configurations from a file location of your choice which lets you centralize your service configurations. By default, when a WCF Service or client starts up, it reads configuration information from the application’s config file. Using this new feature, however, you can override that default to specify any file you want

As in with the other code-based configuration features in WCF 4.5, to use this feature you’ll need to add a Shared/static method to your service class called Configure (WCF will call this method before trying to use your service). WCF passes this method a ServiceConfiguration object that has a LoadConfiguration method you can call to load a configuration from any file you want. To use this feature, you’ll also need to make sure that your project has a reference to System.Configuration to pick up some of the classes you’ll need.

The first step in the process is to define an ExeConfigurationFileMap object. This object allows you to specify which files WCF is to look in for your service’s configuration information. There are a number of properties that you can set, including specifying what file to use instead of the machine config file that controls settings for the .NET installation on the computer and the file to use for a WCF client. However, for a WCF service, you want to set the ExeConfigFilename to the path for the file containing your configuration settings. This example points WCF at a file called Service1.config in a folder called configs off the root folder:

Dim cfMap AsNew System.Configuration.
               ExeConfigurationFileMap With 
                 { .ExeConfigFilename = "c:\configs\Service1.config"} 

This configuration file must contain your system.serviceModel element enclosed in a <configuration> element, like this:

<configuration> 
  <system.serviceModel>  
  </system.serviceModel> 
</configuration> 

Now that you have your filemap object you can create a configuration object from it. To do this, you call the ConfigurationManager’s OpenMappedExeConfiguration method passing your filemap and a ConfigurationUserLevel of None, as this example does:

cf = System.Configuration.ConfigurationManager. 
       OpenMappedExeConfiguration(cfMap, 
           System.Configuration.ConfigurationUserLevel.None) 

Finally, you pass your configuration object to the ServiceConfiguration parameter using its LoadFromConfiguration method:

sc.LoadFromConfiguration(cf)

There is one wrinkle here: You’re not allowed to have any host elements in the configuration file loaded through the LoadFromConfiguration method (well, you can have host elements in your configuration file but they’ll be ignored). The host element is normally used to set the base address of the service’s endpoints and that’s considered the responsibility of the host rather than the service (for instance, in a WCF service hosted in an ASP.NET site, the site sets the base URL for all services). This is an issue if, in a WCF Service library, you’re using relative addresses for the endPoint elements in your service’s configuration. This example, for instance, specifies that the service’s endpoint is “Service1″ added to whatever base address is specified in the host element:


<services>  
  <service name="WCFCentralConfig.Service1">  
    <endpoint address="Service1" binding="basicHttpBinding"  
                                contract="WCFCentralConfig.IService1"> 

If so, you’ll need to leave a host element in your service library’s config file to specify your base address:

 <system.serviceModel>
  <services>
    <servicename="WCFCentralConfig.Service1">
      <host> 
        <baseAddresses>
          <addbaseAddress = "http://localhost:8733/WCFCentralConfig/"/> 
        </baseAddresses> 
      </host>  
    </service> 
  </services> 
</system.serviceModel> 

However, if the endpoints in your Service Library specify absolute addresses then you’ll be able to completely delete the system.serviceModel element in your application’s config file. You’ll need to specify the absolute address not only for the endpoint for your service but also, if you’re testing with the WCF Test Client or using the Discover button in the Add Service Reference dialog, for the endpoint used to retrieve the contract for your service (the mex binding) and the httpGetUrl attribute of the serviceMetaData element. You’ll also probably want to specify that, for testing, all the exception detail is to be included in any fault messages you get from your service. Putting it all together, it means that your configuration file will look something like this in a Service Library:

 <configuration> <system.serviceModel> 
  <services> 
    <service name="WCFCentralConfig.Service1"> 
      <endpoint 
          address="http://localhost:8733/WCFCentralConfig/Service1" 
          binding="basicHttpBinding" 
          contract="WCFCentralConfig.IService1"> 
        <identity> 
          <dns value="localhost"/> 
        </identity> 
      </endpoint> 
      <endpoint 
         address="http://localhost:8733/WCFCentralConfig/Service1/mex" 
         binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
  </services> 
  <behaviors> 
    <serviceBehaviors> 
      <behavior> 
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" 
         httpGetUrl="http://localhost:8733/WCFCentralConfig/Service1/"/> 
        <serviceDebug includeExceptionDetailInFaults="true"/> 
      </behavior> 
    </serviceBehaviors> 
  </behaviors> 
</system.serviceModel> 
</configuration> 

- Peter Vogel

Next Page »


Learning Tree International

.NET & Visual Studio Courses

Learning Tree offers over 245 IT and Management courses, including a full curriculum of over 15 .NET training options.

Free White Papers

Questions on current IT or Management topics? Access our Complete Online Resource Library of over 65 White Papers, Articles and Podcasts

Enter your email address to subscribe to this blog and receive notifications of new posts by e-mail.

Join 9 other followers

Follow Learning Tree on Twitter

Archives

Do you need a customized .NET training solution delivered at your facility?

Last year Learning Tree held nearly 2,500 on-site training events worldwide. To find out more about hosting one at your location, click here for a free consultation.
Live, online training

Follow

Get every new post delivered to your Inbox.