Wrox Programmer Forums
Go Back   Wrox Programmer Forums > ASP.NET and ASP > ASP.NET 4 > BOOK: Beginning ASP.NET 4 : in C# and VB
|
BOOK: Beginning ASP.NET 4 : in C# and VB
This is the forum to discuss the Wrox book Beginning ASP.NET 4: in C# and VB by Imar Spaanjaars; ISBN: 9780470502211
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Beginning ASP.NET 4 : in C# and VB section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old January 27th, 2013, 02:21 PM
Authorized User
 
Join Date: Oct 2012
Posts: 27
Thanks: 4
Thanked 2 Times in 2 Posts
Default Parsing PropertyValuesString in aspnet_Profile

The PropertyValuesString in aspnet_Profile appears like a weird example of non-normalization: instead of containing one data per field, it contains a bunch of data in each field. In the two samples of code below, I'm trying to extract a data from the Profile for a datagrid, but it doesn't work.
Sample_1
Code:
            from u in myEntities.aspnet_Users
             where u.UserName != ""
             select new 
             {
             UserName = u.UserName,
             FirstName = u.aspnet_Profile.PropertyValuesString
             };
        GridView1.DataSource = dataofuser;
        GridView1.DataBind();
That works, but, obviously, the whole strPropertyValuesString is displayed in the grid. I couldn't find any way to extract separate properties.

Sample-2
[code]
Code:
            from u in myEntities.aspnet_Users
             where u.UserName != ""
             select new 
             {
             UserName = u.UserName,
             FirstName = GetPlayerData(string username, string data)
             };
        GridView1.DataSource = dataofuser;
        GridView1.DataBind();
private string GetPlayerData(string username, string data)
    {
      ProfileCommon userProfile = Profile.GetProfile(username);
      return userProfile.FirstName;
    }
That gives errors like "Cannot asign method group to anonymous type property".
Any help will be highly appreciated.
 
Old January 27th, 2013, 03:31 PM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

Hi there,

Yes, this is the biggest problem that I (and many others) have with the built profile.

There are a few solutions:

1. Use the Profile Table provider (http://www.asp.net/downloads/sandbox...ovider-samples) that stores data in multiple columns.

2. Use Profile as you did in your example. However, you need to fix the code. This:

FirstName = GetPlayerData(string username, string data)

should probably be:

FirstName = GetPlayerData(u.UserName)

You could also make a property of type ProfileCommon on the anonymous object.

Yet another alternative is to ditch profile altogether and use EF. The biggest benefit of Profile is that you don't have to write a lot of code to interact with the database. But that's also true for EF, so if you're using EF already, you might as well change the current profile data into a new Profile entity in your EF model.

Cheers,

Imar
__________________
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Follow me on Twitter

Author of Beginning ASP.NET 4.5 : in C# and VB, Beginning ASP.NET Web Pages with WebMatrix
and Beginning ASP.NET 4 : in C# and VB.
Did this post help you? Click the button below this post to show your appreciation!
 
Old January 27th, 2013, 04:36 PM
Authorized User
 
Join Date: Oct 2012
Posts: 27
Thanks: 4
Thanked 2 Times in 2 Posts
Default

Thank you very much.
1. The Profile Table provider looks very fit to my application and I'll try to implement it.

2. The Sample-1 code I tested initially was:
Code:
        var dataofplayer =
            from u in myEntities.aspnet_Users
             where u.UserName != ""
             select new 
             {
             UserName = u.UserName,
             FirstName = GetPlayerData(u.UserName,"FirstName")
             };

        GridView1.DataSource = dataofplayer;
        GridView1.DataBind();
      }
    }

    private string GetPlayerData(string username, string data)
    {
      ProfileCommon userProfile = Profile.GetProfile(username);
      switch (data)
      {
        case "FirstName":
          return userProfile.FirstName;
          break;
        case "LastName":
          return userProfile.FirstName;
          break;
      }
This doesn't compile: "break"appears underlined in green and the following exeption is thown: "Unreachable code detected"

I eliminated the "switch" and simplified the code to:
Code:
var dataofplayer =
            from u in myEntities.aspnet_Users
             where u.UserName != ""
             select new 
             {
             UserName = u.UserName,
             FirstName = GetPlayerData(u.UserName,"FirstName")
             };
private string GetPlayerData(string username, string data)
    {
      ProfileCommon userProfile = Profile.GetProfile(username);
      return userProfile.FirstName;
    }
This compiles well, but when I click the button which runs it, I get an exception:
"LINQ to Entities does not recognize the method 'System.String GetPlayerData(System.String, System.String)' method, and this method cannot be translated into a store expression."

3. In fact, I was trying to copy all the data from Profile into a table, and then use it as source after. "aspnet_Profile" is already an entity in my EF, since I configured my database for application services, as explained in Appendix B, page 771. However, aspnet_Profile entity still keeps all the properties in one string.

Again, thank you very much.
 
Old January 28th, 2013, 07:51 AM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

>> This doesn't compile: "break"appears underlined in green and the following exeption is thown: "Unreachable code detected"

I think it does compile, but just gives you a warning. Take a look at this:

case "FirstName":
return userProfile.FirstName;
break;

The return statement causes the code to return immediately, and thus break is never fired (and is thus unreachable). Remove the break statement and the warning goes away.

LINQ to Entities does not recognize the method 'System.String GetPlayerData

Ah, yes that makes sense. LINQ to EF tries to convert that into something that can be executed against SQL Server which fails.

You could query the user name from EF and use it later to create a Profile. Alternatively, you could use a view model-like class that has a lazy loaded property. In your query you assign the UserName and then later use the lazy loaded property to get at other data.

>> "aspnet_Profile" is already an entity in my EF, since I configured my database for application services, as explained in Appendix B, page 771. However, aspnet_Profile entity still keeps all the properties in one string.

Yes, but you shouldn't do that. The format the data is stored in is very specific to profile. Either use Profile or your own custom tables. Never use aspnet_Profile as an entity.

Cheers,

Imar
__________________
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Follow me on Twitter

Author of Beginning ASP.NET 4.5 : in C# and VB, Beginning ASP.NET Web Pages with WebMatrix
and Beginning ASP.NET 4 : in C# and VB.
Did this post help you? Click the button below this post to show your appreciation!
 
Old January 28th, 2013, 07:06 PM
Authorized User
 
Join Date: Oct 2012
Posts: 27
Thanks: 4
Thanked 2 Times in 2 Posts
Default Follow up

Thank you very much. Your explanations help me a lot.
You are also clarifying an issue which I encounterd when I configured the database for application services: whether to include the aspnet_* tables or not. I kind of knew that all * were already classes, but I opted to include them to see if it works: it does. For instance, the code below works fine:
Code:
var profile1 =
        (from p in myEntities.aspnet_Profile
         where p.UserId == user.UserId
         select p).SingleOrDefault();
      {
        Label1.Text = profile1.PropertyValuesString;
      }

      ProfileCommon userProfile = Profile.GetProfile(user.UserName);
      Label2.Text = userProfile.LastName;
However, I understand that the good practice is to exclude them from the entity.
Thanks again.
 
Old January 29th, 2013, 05:28 AM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

Profile and EF are really two separate concepts. Profile doesn't use EF; it uses direct ADO.NET to read and write to the aspnet_Profile table. When it retrieves the data, it parses the denormalized properties data and makes it available when individual properties are accessed. When saving, it does the reverse and combines all values into a single column. Profile hasn't turned the aspnet_Profile table into a class as EF does; it just reads and writes to that table using ADO.NET.

EF, on the other hand, doesn't know anything about Profile. For EF, aspnet_Profile is just another table. Reading and writing should work fine (as shown in your example) but unfortunately it's also a bit useless because of the awkward internal format of the PropertyValuesString column.

Cheers,

Imar
__________________
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Follow me on Twitter

Author of Beginning ASP.NET 4.5 : in C# and VB, Beginning ASP.NET Web Pages with WebMatrix
and Beginning ASP.NET 4 : in C# and VB.
Did this post help you? Click the button below this post to show your appreciation!
 
Old January 29th, 2013, 07:20 AM
Authorized User
 
Join Date: Oct 2012
Posts: 27
Thanks: 4
Thanked 2 Times in 2 Posts
Default aspnet_* tables

Thank you for this very useful information.
It appears to me that the Profile class doesn't include properties for all the columns in aspnet_Profile table, for instance the UserId. The same is true for the User class, which offers very limited choices in Intellisense. I was trying to transfer most of the user properties in a table, but I couldn't find UserId and Email in any class. The solution I figured out was to get it from aspnet_Users and aspnet_Membership entities(which I still keep), as follows:
Code:
 var user1 =
            (from u in myEntities.aspnet_Users
             where u.UserName == Profile.UserName
             select u).SingleOrDefault();
          myData.UserID = user1.UserId;

          var user2 =
            (from m in myEntities.aspnet_Membership
             where m.UserId == user1.UserId
             select m).SingleOrDefault();
          myData.Email = user2.Email;
That seems to work.
Are there better ways to get the UserId and Email of the current user or of a certain user?
Thanks again.
 
Old January 29th, 2013, 07:48 AM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

>> Are there better ways to get the UserId and Email of the current user or of a certain user?

Yes, don't use the aspnet_* tables in your EF model; instead use the Membership API. By directly going to the database using EF you bypass all the Membership logic such as checking for duplicate names and e-mail addresses. I mentioned Profile in my previous post, but the same applies to Membership and Users.

If you do want to continue, look into JOINs in your LINQ queries so you can join the Membership and Users tables to get the data with a single query.

BTW: you should treat the user ID as internal. Instead, use a combination of the Application's Name and the UserName to get a unique way to identify a user.

Cheers,

Imar
__________________
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Follow me on Twitter

Author of Beginning ASP.NET 4.5 : in C# and VB, Beginning ASP.NET Web Pages with WebMatrix
and Beginning ASP.NET 4 : in C# and VB.
Did this post help you? Click the button below this post to show your appreciation!
 
Old January 30th, 2013, 07:55 AM
Authorized User
 
Join Date: Oct 2012
Posts: 27
Thanks: 4
Thanked 2 Times in 2 Posts
Default Membership

Very useful information.
I'm exploring System.Web.Security Namespace at http://msdn.microsoft.com/en-us/libr...v=vs.100).aspx.
Thank you very much.





Similar Threads
Thread Thread Starter Forum Replies Last Post
Parsing a String? MBowen SQL Server 2000 9 December 1st, 2006 01:17 PM
Parsing JSP's? edga Excel VBA 0 November 8th, 2005 07:33 PM
Parsing mwviola98 SQL Language 4 July 21st, 2005 10:35 AM
XML Parsing tgopal Javascript 2 July 27th, 2004 08:54 AM
XML Parsing tgopal .NET Web Services 1 June 15th, 2004 03:25 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.