VB Magic

2011/07/25

Getting an ASP.NET MVC Razor site into the cloud

Filed under: ASP.NET MVC, Azure, Learning — Tags: , , , , , — vbmagic @ 12:53 pm

I started to work on a web role to test out experiments with ADO.net code first and ASP.NET MVC 3 with Razor. Out of the box, VS 2010 does not support ASP.net MVC 3 so I created the Azure project, then added a ASP.NET MVC 3 project separately. I then added that MVC project to the Azure project as a web role. Clicked run and all seemed to work fine.

But as with all things Azure, if it works in the developer environment, don’t expect it to automatically work in the cloud.

It didn’t. But I was expecting that. It was a bit hard to track down what the problems were as it only manifested as a web role that never seemed to get started.

Once I had worked out that meant it was missing core components for the web site, I was pleasantly surprised was how easy it was to fix this.

On your MVC 3 project right click the project solution and then select “Add Deployable Dependencies”

Then click the “ASP.NET MVC” and the “ASP.NET Web Pages with Razor syntax” check boxes and click ok.

You will then find a directory added to your project called _bin_deployableAssemblies.

All I did after this was “Deploy” the Azure Project and after waiting for the project to deploy into the cloud, it all started ok and worked.

I wish all problems were as easy to solve as this πŸ™‚

Jas

2011/06/27

Trying to get Entity Framework Code First working : The Solution

Filed under: ASP.NET MVC, Azure, Learning — Tags: , , — vbmagic @ 11:39 am

Hi,

In the light of day the problem is solved. It seems that if the database you are connecting to already exists, then it will not create any new tables that you may try to access.

I basically dropped my local database and re-ran the webserver and it created the tables and the database with no issues.

On with the MVC3 course…

Jas

2011/06/26

Trying to get Entity Framework Code First working : The Problem

Filed under: ASP.NET MVC, Azure, Learning — Tags: , , , , — vbmagic @ 10:44 pm

I’ve added reference to EntityFramework (Downloaded by NuGet) to my MVC 3 project.

I then created the following two classes to represent my tables:

Imports System.ComponentModel.DataAnnotations

Public Class tImage
    <Key()>
    Public Property ID As Int64

    <MaxLength(50)>
    Public Property name As String

    <MaxLength(255)>
    Public Property URL As String

    Public Property type As tImageType

    <MaxLength(50)>
    Public Property tag As String
End Class
Imports System.ComponentModel.DataAnnotations

Public Class tImageType
    <Key()>
    Public Property ID As Integer

    <MaxLength(50)>
    Public Property name As String

    <MaxLength(255)>
    Public Property description As String

End Class

And then created the following class as my data context:

Imports System.Data.Entity

Public Class TyranntDB
    Inherits DbContext

    Public Property images As DbSet(Of tImage)
    Public Property imageTypes As DbSet(Of tImageType)

End Class

I then added the following connection string to my web.config file:

  <connectionStrings>
             .....
    <add name="TyranntDB"
         connectionString="Data Source=.\SQL08;Initial Catalog=jsundb;Integrated Security=True;Pooling=False"
         providerName="System.Data.SqlClient" />
  </connectionStrings>

Everything from this point compiled ok. After this I created an Image Controller

Namespace TyranntServices
    Public Class ImageController
        Inherits System.Web.Mvc.Controller


        Dim _db As New TyranntDB
        '
        ' GET: /Image

        Function Index() As ActionResult

            Dim model = _db.images

            Return View(model)
        End Function
...

And the following View to list Images (Well it was mostly auto generated by using the Add View option with list template):

@ModelType IEnumerable(Of TyranntServices.tImage)

@Code
    ViewData("Title") = "Index"
End Code

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p> 
<table>
    <tr>
        <th></th>
        <th>
            name
        </th>
        <th>
            URL
        </th>
        <th>
            tag
        </th>
    </tr>

@For Each item In Model
    @<tr>
        <td>
            @Html.ActionLink("Edit", "Edit", New With {.id = item.ID}) |
            @Html.ActionLink("Details", "Details", New With {.id = item.ID}) |
            @Html.ActionLink("Delete", "Delete", New With {.id = item.ID})
        </td>
        <td>
            @item.name
        </td>
        <td>
            @item.URL
        </td>
        <td>
            @item.tag
        </td>
    </tr>
Next
</table>

This all seems to compile well. When I run though, the tables do not get generated and I get an error stating that the dbo.tImages does not exist.

It’s late now so will post this and hope I can soon update it with what is wrong.

Jas

2011/04/01

Client/Server experiment with MVC3 and Windows Phone 7 (Part 2.2 – Login Page)

Filed under: Learning — Tags: , , , , , , — vbmagic @ 3:59 pm

After getting over the “Add Service Reference” problem mentioned in the previous post, the Login page was created:

login page graphic

Login Page

XAML file below:

https://vbmagic.wordpress.com/wp-admin/edit.php
<phone:PhoneApplicationPage 
    x:Class="TyranntPhone.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="TYRANNT" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="login" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid x:Name="LoginGrid" Background="Transparent">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock x:Name="usernameTextBlock" Grid.Row="0" Grid.Column="0" Text="Username" VerticalAlignment="Center" />
                <TextBox x:Name="usernameTextBox" Grid.Row="0" Grid.Column="1" Text="" VerticalAlignment="Center" />
                <TextBlock x:Name="passwordTextBlock" Grid.Row="1" Grid.Column="0" Text="Password" VerticalAlignment="Center" />
                <PasswordBox x:Name="passwordPasswordBox" Grid.Row="1" Grid.Column="1" Password="" VerticalAlignment="Center" IsEnabled="False" />
                <CheckBox x:Name="rememberMeCheckBox" Grid.Row="2" Grid.Column="1" Content="Remember Me" IsEnabled="False" />
                <Button x:Name="loginButton" Grid.Row="3" Grid.ColumnSpan="2" Content="Login" IsEnabled="False" />
                <Button x:Name="logoutButton" Grid.Row="4" Grid.ColumnSpan="2" Content="Logout" Visibility="Collapsed" />
            </Grid>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>

Then helper methods were created to adjust the page layout and to help with passing information between pages. Also, to help with the application tomb-stoning, the following routines were created in the App.xaml.vb page to store and retrieve information:

    Private Sub StoreDetails()
		' The PhoneApplicationService stores information while the application is "Active"
        Dim phoneAppService As PhoneApplicationService = PhoneApplicationService.Current
		' The IsolatedStorageSettings will store informaiton on the phones flash memory to be
		' retrieved after the app has shut down and re-started.
        Dim settings As IsolatedStorageSettings = IsolatedStorageSettings.ApplicationSettings

		' Pull the token GUID from temp storage in the phones memory and write into the 
		' permanante storage on the phone's flash disk. Only if it exists
        Dim token As Guid
        If phoneAppService.State.TryGetValue("token", token) = True Then
            settings("token") = token
        End If
		' The same for the remembered username, this will allow the name to be recalled
		' after the app has been shut down in any way.
        Dim rname As String = ""
        If phoneAppService.State.TryGetValue("rememberedUsername", rname) = True Then
            settings("rememberedUsername") = rname
        End If
		' This stores the user group, for the moment, this should only really be done
		' if the app is paused to allow another app to run. If the app is exited the
		' user will have to log on again anyway.
        Dim group As String = ""
        If phoneAppService.State.TryGetValue("group", group) = True Then
            settings("group") = group
        End If
    End Sub

    Private Sub GetDetails()
		' The PhoneApplicationService stores information while the application is "Active"
        Dim phoneAppService As PhoneApplicationService = PhoneApplicationService.Current
		' The IsolatedStorageSettings will store informaiton on the phones flash memory to be
		' retrieved after the app has shut down and re-started.
        Dim settings As IsolatedStorageSettings = IsolatedStorageSettings.ApplicationSettings

		' The token us used to identify the user without the need for a username and password.
        Dim token As Guid
        If settings.TryGetValue("token", token) = True Then
            phoneAppService.State("token") = token
        End If
		' if the user has ticked the remember me box, this is the name they used to log on.
        Dim rname As String = ""
        If settings.TryGetValue("rememberedUsername", rname) = True Then
            phoneAppService.State("rememberedUsername") = rname
        End If
		' this will show if the user is a member of any special user group such as administrator
        Dim group As String = ""
        If settings.TryGetValue("group", group) = True Then
            phoneAppService.State("group") = group
        End If
    End Sub

I got the idea for this from the WP7 course at http://learnvisualstudio.net a good resource for learning most things .net.

Here is the code to handle the enabling and disabling of sections of the login page:

Partial Public Class MainPage
    Inherits PhoneApplicationPage

    Private _phoneAppService As PhoneApplicationService = PhoneApplicationService.Current

    ' Constructor
    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub EnableLogin(ByVal state As Boolean)
        usernameTextBox.IsEnabled = state
        passwordPasswordBox.IsEnabled = state
        loginButton.IsEnabled = state
    End Sub

    Private Sub usernameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs) Handles usernameTextBox.TextChanged
        If usernameTextBlock.Text.Length > 3 And passwordPasswordBox.IsEnabled = False Then
            passwordPasswordBox.IsEnabled = True
            rememberMeCheckBox.IsEnabled = True
        ElseIf usernameTextBox.Text.Length <= 3 And passwordPasswordBox.IsEnabled = True Then
            passwordPasswordBox.IsEnabled = False
        End If
    End Sub

    Private Sub passwordPasswordBox_PasswordChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles passwordPasswordBox.PasswordChanged
        If passwordPasswordBox.Password.Length > 3 And loginButton.IsEnabled = False Then
            loginButton.IsEnabled = True
        ElseIf passwordPasswordBox.Password.Length <= 3 And loginButton.IsEnabled = True Then
            loginButton.IsEnabled = False
        End If
    End Sub

    Private Sub PhoneApplicationPage_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        If RetrieveDetails() = True Then
            passwordPasswordBox.Focus()
            rememberMeCheckBox.IsChecked = True
        Else
            usernameTextBox.Focus()
        End If

    End Sub

    Private Sub PhoneApplicationPage_BackKeyPress(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.BackKeyPress
        Dim res As MessageBoxResult = MessageBox.Show("Are you sure you wish to exit", "Exit", MessageBoxButton.OKCancel)
        If res = MessageBoxResult.Cancel Then
            e.Cancel = True
        End If
    End Sub

    Private Sub StoreDetails()
        _phoneAppService.State("rememberedUsername") = usernameTextBox.Text
    End Sub

    Private Function RetrieveDetails() As Boolean
        Dim tmp As String = ""
        If _phoneAppService.State.TryGetValue("rememberedUsername", tmp) = False Then
            Return False
        Else
            usernameTextBox.Text = tmp
            Return True
        End If
    End Function

    Private Sub rememberMeCheckBox_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles rememberMeCheckBox.Checked
            StoreDetails()
    End Sub

    Private Sub DeleteDetails()
        _phoneAppService.State.Remove("rememberedUsername")
    End Sub

    Private Sub rememberMeCheckBox_Unchecked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles rememberMeCheckBox.Unchecked
        DeleteDetails()
    End Sub

End Class

Now that this infrastructure is in place we get to the good bit, consuming the login service. The following routines were created to handle the login button click event and code to handle the call back for the login service.

    Private Sub loginButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles loginButton.Click
        Dim client As New userServiceReference.UserServiceClient
        AddHandler client.LoginCompleted, AddressOf client_LoginCompleted
        Dim login As New userServiceReference.LoginType
        login.Username = usernameTextBox.Text
        login.Password = passwordPasswordBox.Password
        client.LoginAsync(login)
        EnableLogin(False)
        If rememberMeCheckBox.IsChecked = True Then
            StoreDetails()
        End If
    End Sub

    Private Sub client_LoginCompleted(ByVal sender As Object, ByVal e As userServiceReference.LoginCompletedEventArgs)
        If e.Error Is Nothing Then
            Dim res As userServiceReference.TokenType = e.Result
            If res.errorMessage <> "" And res.errorMessage <> "fail" Then
                MessageBox.Show(res.errorMessage)
                EnableLogin(True)
            ElseIf res.errorMessage = "fail" Then
                MessageBox.Show("Username/Password incorrect")
                EnableLogin(True)
            Else
                _phoneAppService.State("token") = res.TokenGUID
                _phoneAppService.State("group") = res.UserGroup
                NavigationService.Navigate(New Uri("/pages/MemberPivotPage.xaml", UriKind.Relative))
                loginButton.Visibility = Windows.Visibility.Collapsed
                logoutButton.Visibility = Windows.Visibility.Visible
            End If
        Else
            MessageBox.Show(e.Error.Message)
            EnableLogin(True)
        End If
    End Sub

The contents of the username and password from the boxes on the page are used to generate a login type which is defined in the web service but I’ll re-show here:

<DataContract()>
Public Class LoginType

    <DataMember()>
    Public Property Username() As String

    <DataMember()>
    Public Property Password() As String
 
End Class

Then the callback routine to handle the completed login web service call was created and an event handler put into place. Then the ASYNC version of the service (Which is the only one available on Silverlight for Windows Phone) is called and the UI is changed to stop the user from trying to log in twice.
At the server end, the Membership service will attempt to validate the credentials. (A side note: To add a new user, you need to register on the website. Which is all handled automatically if you create an MVC3 website rather than a blank project.)

When the service returns the result of the login, firstly the app checks to see if the e.Error object has been set, this will indicate something went wrong with the service call and for now, it will just display the error message in a message box on the phone (Example of this is a timeout). Next the app will have a look at the returned object which is a TokenType which again is defined in the web service and I’ve shown again below:

<DataContract()>
Public Class TokenType

    <DataMember()>
    Public Property UserGroup() As String

    <DataMember()>
    Public Property TokenGUID() As Guid

    <DataMember()>
    Public Property errorMessage() As String

End Class

The errorMessage property of the TokenType class is used to pass back in the login failed for a username/password error. Basically if errorMessage is “” then everything went OK. If it contains the text “fail” then the username/password combination isn’t valid so the phone app will display that in a message box and reset the display to allow the user to attempt to log on again. If an exception occurred during the login process this is captured by the service and put into the errorMessage property. The phone app will check this and for now display that error message to aid in debugging.

If everything went well, then there should be a GUID in the TokenGUID property which will be used from that point onwards to identify that user. Later I will make every attempt to access the services change this GUID and pass the new one back. I will also add a time out so that the app can get the user to re-login after a period of inactivity has occurred.

If the login was successful we then enable a Logout button and collapse the login button and navigate to the “Member” section of the app using the following command:

NavigationService.Navigate(New Uri("/pages/MemberPivotPage.xaml", UriKind.Relative))

Next post on this experiment will be about what happens on this page.

2011/03/28

Error 0x80070643 installing MVC 3 on a VS 2010 ultimate installation (Service Pack 1)

Filed under: Uncategorized — Tags: , , , — vbmagic @ 11:30 am

Hi,

I was getting the following error when trying to install MVC 3 on my Visual Studio 2010 ultimate installation. It happened in the initial part of the install. After some web searching I managed to find a solution that worked so I thought I would post the link to the blog post that helped.

http://blog.williamhilsum.com/2011/03/error-0x80070643-installing-aspnet-mvc.htm

Look for the second update on the page and follow those instructions to make it work. I hope Microsoft will fix this and re-release the installer.

Jas

2011/03/24

Client/Server experiment with MVC3 and Windows Phone 7 (Part 1 – The back end)

Filed under: Learning — Tags: , , , , — vbmagic @ 4:27 pm

I thought I might as well start with what I’m currently working on outside of work. It’s mainly a learning exercise to (re)teach myself WCF/MVC and learn to develop using windows phone 7.

I decided to start with the back end so created a new VB MVC3 project using Razor. (I’ve not used Razor yet so this is something else new to learn)

The reason I used MVC rather than just hosting a WCF service was to make use of the Membership system that automatically gets created with a new MVC site.

On this new site, I created a services directory and created a service called UserService which will make use of the ASP.net membership provider. I have also created a few Data Contracts that make the passing of data around a lot easier:

Imports System.ServiceModel
Imports System.Runtime.Serialization

<DataContract()>
Public Class LoginType

    <DataMember()>
    Public Property Username() As String

    <DataMember()>
    Public Property Password() As String

End Class

<DataContract()>
Public Class IntegerType

    <DataMember()>
    Public Property IntegerValue() As Integer

    <DataMember()>
    Public Property ErrorMessage() As String

End Class

<DataContract()>
Public Class TokenType

    <DataMember()>
    Public Property UserGroup() As IntegerType

    <DataMember()>
    Public Property TokenGUID() As Guid

    <DataMember()>
    Public Property errorMessage() As String

End Class

<DataContract()> _
Public Class UserDetailsType

    <DataMember()>
    Public Property name As String

    <DataMember()>
    Public Property email As String

    <DataMember()>
    Public Property lastLogin As Date

    <DataMember()>
    Public Property errorMessage As String

End Class

These are much smaller since VB10 where you do not need to put in the setter and getter part of properties.

I have also created a table call Players which will contain information about the user which is not already stored in the membership databases and then added a Linq to SQL class so that the service can make use of it:

Linq to SQL Class

Linq to SQL Class

Behind this class is the code to interrogate and update the database:

Partial Class TyranntDataContext
#Region "Player"

    Public Function GeneratePlayer(ByVal username As String) As Guid
        ' We first need to access the user ID from the Users table
        Dim usr = From user In aspnet_Users
                  Where user.UserName = username
                  Select user
        ' now check to see if the user record exists in the Player Table
        If usr.Count <> 1 Then
            Return Nothing
        End If
        Dim q = From player In Players
                Where player.userID = usr.Single().UserId
                Select player
        ' if player exists then exit
        If q.Count > 0 Then
            Return q.Single.guid
        End If
        ' Create the player entry
        Dim aPlayer As New Player
        aPlayer.userID = usr.Single.UserId
        aPlayer.creationDate = DateTime.Now
        aPlayer.displayName = usr.Single.UserName
        aPlayer.lastLogin = aPlayer.creationDate
        ' Create a false guid for now, this is only used by the client
        aPlayer.guid = System.Guid.NewGuid
        Players.InsertOnSubmit(aPlayer)
        SubmitChanges()
        Return aPlayer.guid
    End Function

    Public Function GeneratePlayerGuid(ByVal username As String) As Guid
        ' generate new guid
        Dim g As Guid = System.Guid.NewGuid

        ' find the player record
        Dim p = From player In Players
                Where player.aspnet_User.UserName = username
                Select player
        ' Update player record with new GUID
        p.Single.guid = g
        SubmitChanges()
        Return g
    End Function

    Public Function GetPlayerDetails(token As Guid) As UserDetailsType
        Dim p = From player In Players
                Where player.guid = token
                Select player

        Dim details As New UserDetailsType
        details.name = p.Single.displayName
        details.email = p.Single.aspnet_User.aspnet_Membership.Email
        details.lastLogin = p.Single.aspnet_User.LastActivityDate

        Return details
    End Function

    Public Sub UpdatePlayerDetails(token As Guid, details As UserDetailsType)
        Dim p As Player = GetPlayer(token)
        p.displayName = details.name
        p.aspnet_User.aspnet_Membership.Email = details.email
        SubmitChanges()
    End Sub

    Private Function GetPlayer(token As Guid) As Player
        Dim p = From player In Players
                Where player.guid = token
                Select player

        Return p.Single
    End Function
#End Region

End Class

And now the Service contract which allows users to log in, get their details and update part of the details. The Service Contract code is:

Imports System.ServiceModel

' NOTE: You can use the "Rename" command on the context menu to change the interface name "IUserService" in both code and config file together.
<ServiceContract()>
Public Interface IUserService

    ' User management routines

    ' Log in to website created user
    <OperationContract()>
    Function Login(ByVal loginData As LoginType) As TokenType

    ' Get user details
    <OperationContract()>
    Function GetUserDetails(token As String) As UserDetailsType

    ' Update user details
    <OperationContract()>
    Function UpdateUserDetails(token As String, details As UserDetailsType) As String

End Interface

And now the Bit the does all the work:

' NOTE: You can use the "Rename" command on the context menu to change the class name "UserService" in code, svc and config file together.
Public Class UserService
    Implements IUserService

    Public Function Login(loginData As LoginType) As TokenType Implements IUserService.Login
        Dim token As New TokenType
        Try
            If Membership.ValidateUser(loginData.Username, loginData.Password) = True Then
                ' User is valid so now update the player record with GUID
                Using db As New TyranntDataContext
                    ' Make sure that the user has a player record
                    Dim playerGUID As Guid = db.GeneratePlayer(loginData.Username)
                    If IsNothing(playerGUID) Then
                        ' something went wrong
                    End If
                    token.TokenGUID = playerGUID
                    token.errorMessage = ""
                End Using
            Else
                token.errorMessage = "fail"
            End If
        Catch ex As Exception
            token.errorMessage = ErrorMessage(ex)
        End Try

        Return token
    End Function

    Public Function GetUserDetails(token As String) As UserDetailsType Implements IUserService.GetUserDetails
        Dim details As New UserDetailsType
        Dim playerGUID As Guid = New Guid(token)
        Try
            Using db As New TyranntDataContext
                details = db.GetPlayerDetails(playerGUID)
            End Using
        Catch ex As Exception
            details.errorMessage = ErrorMessage(ex)
        End Try
        Return details
    End Function

    Public Function UpdateUserDetails(token As String, details As UserDetailsType) As String Implements IUserService.UpdateUserDetails
        Dim playerGUID As Guid = New Guid(token)
        Try
            Using db As New TyranntDataContext
                db.UpdatePlayerDetails(playerGUID, details)
            End Using
        Catch ex As Exception
            Return ErrorMessage(ex)
        End Try
        Return ""
    End Function

    Private Function ErrorMessage(ex As Exception) As String
        Dim err = ex.Message
        If Not IsNothing(ex.InnerException) Then
            err += +vbCr + ex.InnerException.Message
        End If
        Return err
    End Function
End Class

For now the idea is if an exception occurs, it displays on the phone to try to help debug the code.

I did not have to code a membership system as this is already handled by asp.net so all I needed the service to do was to call this function:

'...
If Membership.ValidateUser(loginData.Username, loginData.Password) = True Then
'...

I have used a token based system so that once the user is logged in, and has received a GUID token, that will be used to identify them from that point onwards. I plan to put an expiry date and time on the token which will make the user have to re-login after a period of inactivity.

I’ve not really gone into using MVC3 yet as I’m mainly working on learning to code on the Windows Phone 7, but I needed something for the phone to connect to.

The code above is in early stages and will most likely change but setting up basic web services is a very easy thing to do in .net

Next entry will show the code for the Windows Phone 7 project.

You may have noticed Tyrannt mentioned above. For anyone interested, it’s a link to this project I’ve been toying with for years πŸ™‚

http://www.tyranntrpg.org/

Blog at WordPress.com.