Wednesday, 27 March 2013

debugger; the command i keep forgetting !

So i'm trying to debug ajax responses in a webpage so i go to my chrome browser dev tools, check the src code and nothing....

I keep forgetting to add :

debugger; 

to the ajax response, if we do this, then chrome swings into action and we get our breakpoint so we can debug the response. Hepefully this will help anyone reading this in the future if they are as absent minded as myself.

A.

Wednesday, 23 January 2013

The EntitySet name 'X' from the object's EntityKey does not match the expected EntitySet name, 'Y'.

Go this one tonight, and caused me some grief for a bit.

Basically, I have a foreign key mapping to my company into my user profile and I was trying to perform an update on the foreign key.  Here's my user profile:


    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string EmailAddress { get; set; }
        public string Firstname { get; set; }
        public string Surname { get; set; }

        [ForeignKey("CompanyId")]
        public Company Company { get; set; }

        public int CompanyId { get; set; }
    }

if you want to update the company you have to set the company to null but set the foreign key seperately :


using (var context = new UsersContext())
            {
                profile.UserName = userViewModel.UserName;
                profile.EmailAddress = userViewModel.EmailAddress;
                profile.Firstname = userViewModel.FirstName;
                profile.Surname = userViewModel.Surname;
                profile.Company = null;
                profile.CompanyId = userViewModel.CompanyId;
                //profile.Company = userViewModel.Companies.FirstOrDefault(c => c.Id == userViewModel.CompanyId);
                context.Entry(profile).State = EntityState.Modified;
                context.SaveChanges();
            }

now it works !

Tuesday, 22 January 2013

Making your website fonts a touch better

Hi there,

So until all the browser vendors decide to implement font-smoothing in css (not holding out any hope), here's a little trick I learn't of and started using that makes the fonts look a touch better when in your website.

there are a couple of other techniques out there like cufon and phark which tbh seem a little bit like overkill for the sake of having your text look good. So whilst browsing round, I noticed an article that mentioned the text shadow effect and having a shadow that is between the backgound and your text colour will help smooth out those nasty jaggies....

I have tried the line
    -webkit-font-smoothing: antialiased;

which doesn't seem to give me any kind of different result.  Instead, lets use the shadow ,method here's a quick example:


     font-size: 75%;
     background-color: #f0f0f0;
     text-shadow: 0 0 1px rgba(51, 51, 51, 0.5);
     font-family: Helvetica, arial, freesans, clean, sans-serif;

I've set up the a text size and family (seems to look better on helvetica based fonts on the ones I have tried). then I have set a text shadow up with no offset but a slight blur (1px) and semi transparent grey (the rgba).

coming to set a heading up, I have set its colour to a darker grey too:

h1 { font-size: 1.8em; font-weight: normal; color: #666; padding: 0; margin: 0;}

The results are as below (before and after)



Not perfect, but a great quick solution.  i'm sure if you played more with the colours, you could get it a touch better.

A.




Saturday, 5 January 2013

Simple membership in MVC 4 quick setup guide

Hi folks,

Just working on a project at home and thought I would use the simple membership in mvc 4 as it's pretty neat.  We have a database already created so i'm using it from a database first perspective and thought i'd share the findings here in case someone else needs to do this.  Most of this can be gleaned from creating a blank internet application and getting the bits necessary but thought I would put it in one place for ease of use.

the usual way to go about simple membership is to create an internet application which will do all the gubbins for you and create these tables :


In the old membership we used to run the aspnet_regsql command to register the membership tables. if you need to tables in this example, fear not, the scripts are below. PLEASE NOTE I TAKE NO RESPONSIBILITY IF THEY DESTROY YOUR DB.  these were just generated with create script on the tables.



/****** Object:  Table [dbo].[UserProfile]    Script Date: 01/05/2013 23:09:00 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[UserProfile](
[UserId] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](56) NOT NULL,
PRIMARY KEY CLUSTERED 
(
[UserId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
[UserName] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO


/****** Object:  Table [dbo].[webpages_Membership]    Script Date: 01/05/2013 22:55:24 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[webpages_Membership](
[UserId] [int] NOT NULL,
[CreateDate] [datetime] NULL,
[ConfirmationToken] [nvarchar](128) NULL,
[IsConfirmed] [bit] NULL,
[LastPasswordFailureDate] [datetime] NULL,
[PasswordFailuresSinceLastSuccess] [int] NOT NULL,
[Password] [nvarchar](128) NOT NULL,
[PasswordChangedDate] [datetime] NULL,
[PasswordSalt] [nvarchar](128) NOT NULL,
[PasswordVerificationToken] [nvarchar](128) NULL,
[PasswordVerificationTokenExpirationDate] [datetime] NULL,
PRIMARY KEY CLUSTERED 
(
[UserId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[webpages_Membership] ADD  DEFAULT ((0)) FOR [IsConfirmed]
GO

ALTER TABLE [dbo].[webpages_Membership] ADD  DEFAULT ((0)) FOR [PasswordFailuresSinceLastSuccess]
GO


/****** Object:  Table [dbo].[webpages_Roles]    Script Date: 01/05/2013 22:56:30 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[webpages_Roles](
[RoleId] [int] IDENTITY(1,1) NOT NULL,
[RoleName] [nvarchar](256) NOT NULL,
PRIMARY KEY CLUSTERED 
(
[RoleId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
[RoleName] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/****** Object:  Table [dbo].[webpages_OAuthMembership]    Script Date: 01/05/2013 22:56:56 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[webpages_OAuthMembership](
[Provider] [nvarchar](30) NOT NULL,
[ProviderUserId] [nvarchar](100) NOT NULL,
[UserId] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
[Provider] ASC,
[ProviderUserId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/****** Object:  Table [dbo].[webpages_UsersInRoles]    Script Date: 01/05/2013 22:57:21 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[webpages_UsersInRoles](
[UserId] [int] NOT NULL,
[RoleId] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
[UserId] ASC,
[RoleId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[webpages_UsersInRoles]  WITH CHECK ADD  CONSTRAINT [fk_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[webpages_Roles] ([RoleId])
GO

ALTER TABLE [dbo].[webpages_UsersInRoles] CHECK CONSTRAINT [fk_RoleId]
GO

ALTER TABLE [dbo].[webpages_UsersInRoles]  WITH CHECK ADD  CONSTRAINT [fk_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[UserProfile] ([UserId])
GO

ALTER TABLE [dbo].[webpages_UsersInRoles] CHECK CONSTRAINT [fk_UserId]
GO

With the tables created, add the following to the web.config :


    <roleManager enabled="true" defaultProvider="SimpleRoleProvider">
      <providers>
        <clear/>
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
      </providers>
    </roleManager>
    
  
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <clear/>
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>

Which adds the standard providers for simple membership.  The project includes a filter attribute which you can place at the top of any of your controllers that need to make use of membership, the default class is the InitializeSimpleMembershipAttribute and looks like this:


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                Database.SetInitializer<UsersContext>(null);
                try
                {
                    using (var context = new UsersContext())
                    {
                        if (!context.Database.Exists())
                        {
                            // Create the SimpleMembership database without Entity Framework migration schema
                            ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                        }
                    }

                    WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
                    
                    if (!WebSecurity.UserExists("Administrator"))
                    {
                        WebSecurity.CreateUserAndAccount("Administrator", "password");
                    }

                    if (!Roles.RoleExists("Administrator")) Roles.CreateRole("Administrator");

                    if (!Roles.GetRolesForUser("Administrator").ToList().Contains("Admin"))
                    {
                        Roles.AddUsersToRoles(new[] { "Administrator" }, new[] {"Admin" });
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                }
            }
        }



So Basically, lazy loads the initialisation of the membership stuff.  It is worth noting the InitializeDatabaseConnection call, the default is the name of the connection string, the UserProfile is the name of the users table (in our case UserProfile) and the next 2 fields specify the id and the username fields which is pretty much all simple membership needs in order to operate.

I have added a few lines below to show how you add other bits to the roles and users table.

OK, so if you need to use this functionality in a controller, decorate the controller class with the attribute :

 [InitializeSimpleMembership]

and you use the WebSecurity class to get access to things like the user id e.g.:

WebSecurity.CurrentUserId;

Hope that helps !
A.

Thursday, 27 December 2012

Typescript Visual Studio Plugin - getting started

So the Christmas break is here and i'm full of turkey and rather than watch some sort of BBC shrek creation or watch who dies this year in eastenders, i'd rather exercise the brain.  Been looking at a couple of bits of "newer" tech this period (take a look at the meteor framework with node.js, looks really promising) but i've also decided to use typescript in my latest project as i like the idea of simulating class typing in a dynamic language.. I also thought the breville maker was a great invention....

For those unfamiliar with typescript, it provides a bit of structure to javascript with the ability to create classes, define types etc.  It's the brain child of Anders, the man who brought you Delphi and our beloved C#

Anyways, there is a Visual Studio plugin available that allows us to write in typescript and handles calling the typescript compiler and giving us our javascript out the other end.

The plugin can be downloaded from the Typescript site

http://www.typescriptlang.org/Tutorial/

and once done, you can create a typescript file (i couldn't find it under the web templates, i found it under the Visual c# option instead)


So if you select typescript and add you file you will get a .ts file with its .js compiled equivilent underneath.  If you have downloaded the web essentials for visual studio, you can set some options to compile the typescript on build and show hide the preview pane etc:



I tried setting these whilst working on an existing project and could'nt get them to compile the typescript for me, so a bit of project file editing is necessary.  Unload your web project by right clicking the web project in the solution explorer and select "unload project".  Once done, right click the web project again and select edit project file

Down the bottom are examples of ms build targets.  We add the before build target and call the typescript compiler:


  <Target Name="BeforeBuild">
    <Exec Command="&quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript\0.8.1.1\tsc&quot; @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
  </Target>


You then can go ahead and start using Typescript !

A.

Sunday, 28 October 2012

Windows 8 - Halloween on a desktop

I am an apple fanboy, or at least the guys at work say I am, I own 2 ipads, a 27 inch mac, a macbook pro, apple T.V. and the accompanying duvet and pillow set.

What they don't know is that I also wanted the new Windows 8 to succeed and it is for the reason that I think Apple are too damn cocky with their "new" IPad mini (its like an IPad but smaller), IOS6 with its "cloud based" mapping (that's right, all you can see is clouds) which is rubbish and some of their software which just annoys the hell out of me with its "Leatherbound retro" look and don't get me started on ITunes which i'm sure will be responsible for the inception of skynet.

I thought Microsoft were making a really bold move with Windows 8 and its metro design which I love, it looks simple and beautiful and goes back to how things should be.  And whilst I'm making good bets that windows 8 looks great and works well on a touch device, I am looking at it as a developer on a laptop device to see how cool its is, sadly, it ain't.

Why? Consistency is key we are told at work and its right, I want a system that's the same throughout, predictable, easy to use ;its anything but,  its just a mess.

For starters, we have windows 7 with an invisible start menu and its bloody awkward to get too situated in the bottom left and I often find myself clicking on or hovering on other items on the menu bar at the bottom of the screen.


If you get the crappy little icon visible, you can expect more crappy icons coming down from the top left which feature other areas you can access, good luck in recognising any of em.

Answers on a postcard to WTF is this, P.O.Box 23, redmond, USA.

Then we have the charm bar on the right (aptly named as you are charmed if you can get it to work), which appears if you manage to point to the 2x2 pixel grid in the top right hand side of the screen to make it appear.

So once we have got to the start bar, then the fun really happens as it really is just a start bar, it shows a bunch of apps to start with


that's not all your apps of course, you can right click and get all your apps :


Then I get this (an implementation of the launch pad found on IMac and just as bad I might add - hated it on mac and I do on this) Its a scrollable menu of a thousand icons which makes my eyes bleed.


So what if I want to see the reduced set of app's again? I right click of course and click... erm... All apps again???


yep, familiar territory here.  You may be asking where shu tdown is?  oh yeah its under the charm bar which you can't get too under settings... self explanatory really.

So lets go to the store, Microsoft's app store and this has a distinctly XBox feel about it except half finished. Scroll left and right and get categories of apps to buy which is nice and does actually work ok (again would work really well on a touch device) so I select the Games category :


Once i'm in there, I can use another way of selecting stuff by right clicking in the top.... sigh....


Most of the time you'll be working in the desktop that looks exactly like windows 7 so it's not all bad.

To conclude, if you have windows 7, I wouldn't bother if you are only using this on a desktop unless you really want to like I did.  Touch devices I think would be quite nice, I stand to be corrected on all of this.

A






  






Friday, 19 October 2012

Overriding an importer class for a part Remember the id attribute !

So we are overriding the importer in orchard in our driver and its not getting called.  Remember the id attribute in your xml.  We have organisations and our xml looked like :


<Orchard>
  <Data>
    <Organisation>
      <OrganisationPart Code="XXX" Name="YYY" ProviderId="1" Enabled="1" />
    </Organisation>
  </Data>
</Orchard>

So add the id attribute in the organisation wrapper like so :


<Orchard>
  <Data>
    <Organisation Id="">
      <OrganisationPart Code="XXX" Name="YYY" ProviderId="1" Enabled="1" />
    </Organisation>
  </Data>
</Orchard>

and the driver.importing gets called and i'm happy !