Archive

Archive for the ‘.NET’ Category

WCF Data Services Tip

March 31, 2010 1 comment

At work, I’ve been deep diving into OData / ADO.NET Data Services / WCF Data Services or whatever it’s named this week. We had a desire to expose an existing database table internally for Zip Code lookup. Previously, they used operations within an ASMX service, but I wanted to make a more RESTFUL service available.

Within this project, we already were using LINQ-to-SQL for our data access and I decided to use the DataContext exposed by that instead of wiring up an EDM just for that table. Data Services is pretty slick and can handle the LINQ data context. I followed the normal steps and quickly had a service up and running with the following code:

using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
using Location.DataAccess;
using System.Linq.Expressions;
using System.ServiceModel.Activation;

namespace Location.Service
{
    public class ZipCodeService : DataService<ZipCodesDataContext>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("ZIPUSAs", EntitySetRights.AllRead);
            config.DataServiceBehavior.AcceptCountRequests = true;
            config.DataServiceBehavior.AcceptProjectionRequests = true;
            config.SetEntitySetPageSize("*", 25);
            config.DataServiceBehavior.MaxProtocolVersion = System.Data.Services.Common.DataServiceProtocolVersion.V2;

        }
    }
}

This works perfectly. I browse to the service and see the following XML:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<service xml:base="http://localhost:10903/ZipCodeService.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
  <workspace>
    <atom:title>Default</atom:title>
    <collection href="ZIPUSAs">
      <atom:title>ZIPUSAs</atom:title>
    </collection>
  </workspace>
</service>

But that Collection title of “ZIPUSAs” just bugs me. So, I go into my DBML and change it to ZipCodes. Hit F5 to run and I get this error:

The server encountered an error processing the request. The exception message is 'Exception has been thrown by the target of an invocation.'. See server logs for more details. The exception stack trace is:
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Data.Services.DataServiceConfiguration.InvokeStaticInitialization(Type type)
   at System.Data.Services.DataService`1.CreateConfiguration(Type dataServiceType, IDataServiceMetadataProvider provider)
   at System.Data.Services.DataService`1.CreateProvider()
   at System.Data.Services.DataService`1.HandleRequest()
   at System.Data.Services.DataService`1.ProcessRequestForMessage(Stream messageBody)
   at SyncInvokeProcessRequestForMessage(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Yikes! What happened?

Well, I updated the entity name, but did not update the corresponding string in the ZipCodeService.InitializeService method. I need to change this:

config.SetEntitySetAccessRule("ZIPUSAs", EntitySetRights.AllRead);

to this:

config.SetEntitySetAccessRule("ZipCodes", EntitySetRights.AllRead);

But this continued to seem inelegant to me. I wish that there was a way to have the string change when I refactored my DBML entity.

With a hat tip to @brakower, here is a suggested solution:

config.SetEntitySetAccessRule(typeof(ZipCodes).Name, EntitySetRights.AllRead);

Works great.

Categories: .NET, Programming

Why iterators are better than collections

March 22, 2007 Leave a comment
Categories: .NET, Asides

Some C# Coding Guidelines

March 20, 2007 Leave a comment

My goal is to add more to this in the future, but this is a very good start. I need to remember most of these myself. Sources are linked below.
Read more…

Categories: .NET

Access client information server-side

February 2, 2007 Leave a comment

I’ve been a fan of .NET Slave for quite some time. Mads posts tons of interesting code snippets and also has a good “voice”. In “Access client information server-side”, Mads comes up with a clever way to get client properties and use them on the server side.

My only concern about this technique is that it relies on Javascript to do the redirect, so what happens if the user has disabled Javascript?

All in all, a good technique, though.

Categories: .NET