ASP.NET Membership not populating new users - asp.net

I'm using the ASP.NET Membership provider to handle all membership activities on my current site.
I've run into a weird problem. As you know, if you are familiar with Asp.Net membership, the data is stored in ProfileCommon.
So you could do ProfileCommon.UserId to get the userID.
This all works fine on my production server, my staging server and for old accounts on my local dev server.
However, if I create a new user on my local dev server, the Profilecommon object is not being populated and it is throwing errors because pages reference ProfileCommon.UserId for instance and it's null, thus throwing an exception. The user is Authenticated, but ProfileCommon is not being populated.
Does anyone have any ideas/suggestions as to why this might be happening?
Edit: here's my web.config entry. I'm not sure why we remove AspnetSqlProfileProvider then add it. This is a site I took over and I'm not 100% familiar with asp.net membership yet.
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<remove name="AspNetSqlProfileProvider"/>
<add name="AspNetSqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="ConnectionString"/>
</providers>
Actual profile info;
<profile defaultProvider="SqlProfileProvider">
<providers>
<remove name="AspNetSqlProfileProvider"/>
<add name="SqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="FiftyMillionDBConnection"/>
</providers>
<properties>
<add name="FirstName" type="String" serializeAs="String"/>
<add name="LastName" type="String" serializeAs="String"/>
<add name="EmailAddress" type="String" serializeAs="String"/>
<add name="ScreenName" type="String" serializeAs="String"/>
<add name="BirthDay" type="DateTime" serializeAs="String"/>
<group name="Address">
<add name="AddressLine1" type="String" serializeAs="String"/>
<add name="AddressLine2" type="String" serializeAs="String"/>
<add name="City" type="String" serializeAs="String"/>
<add name="State" type="String" serializeAs="String"/>
<add name="Zip" type="String" serializeAs="String"/>
</group>
<group name="PersonalInfo">
<add name="Gender" type="String" serializeAs="String"/>
<add name="Height" type="String" serializeAs="String"/>
</group>
<group name="OtherInfo">
<add name="Agent" type="String" serializeAs="String"/>
<add name="Employee" type="String" serializeAs="String"/>
<add name="Source" type="String" serializeAs="String"/>
<add name="EventRegistration" type="String" serializeAs="String"/>
</group>
<group name="AuthInfo">
<add name="GUID" type="String" serializeAs="String"/>
<add name="RegSource" type="String" serializeAs="String"/>
<add name="ReceiveMail" type="String" serializeAs="String"/>
</group>
</properties>
</profile>
Thank you!

Is the Profile section in web.config using the same connectionStringName value as the Membership section? This is the first thing I would check.
Edit: Can you post your full profile config block? You should have something that defines the properties like
<profile enabled="true">
<properties>
<add name="UserId" type="Int32"/>
<add name="Gender" type="string"/>
<add name="Age" type="Int32"/>
</properties>
</profile>

In addition to the connectionStringName, you may also want to double-check applicationName. If they don't match, or you define the application name in one section and not the other, you'll run into issues.
<membership defaultProvider="SqlProvider">
<providers>
<add name="SqlProvider"
type="..."
connectionStringName="SomeConnString"
applicationName="SomeApp"
...
... />
</providers>
</membership>
<profile defaultProvider="ProfileProvider">
<providers>
<clear />
<add name="ProfileProvider"
type="..."
applicationName="SomeApp"/>
</providers>
<properties>
...
</properties>
</profile>

Related

Prevent Membership Tables From Being Created

I am in the process of converting an old WebForms app that used membership to using Identity.
I have the Identity tables in my SQL server database and I can do the necessary CRUD operations on them.
But, then, once I start my app and I login with one of my users, all of the Membership tables ('UsersInRoles', 'Roles', 'Profiles', 'Memberships', 'Users', and 'Applications') are recreated.
I need to know how to keep those tables from being created (because of our policies), so any help would be appreciated.
Thanks for any help,
Bob
So, I think that have found what is causing it, but I still have no idea what to do about it.
In my web.config, I have the following section:
<profile defaultProvider="ProfileProviderSql" automaticSaveEnabled="true">
<providers>
<clear />
<add name="ProfileProviderSql" connectionStringName="AppServices" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" applicationName="GMSApp" />
</providers>
<properties>
<add name="CurrentAppId" type="string" defaultValue="" />
<add name="ProjectNumber" type="string" defaultValue="" />
<add name="ProjectAdjustmentNumber" type="int" defaultValue="0" />
<add name="Theme" type="string" defaultValue="Pachanga" />
<add name="UserAgencyID" type="int" defaultValue="0" />
<add name="UserFirstName" type="string" defaultValue="" />
<add name="UserLastName" type="string" defaultValue="" />
<add name="UserContactPhone" type="string" defaultValue="" />
<add name="ProjectHeader" type="string" defaultValue="" />
<add name="IsBaselined" type="bool" defaultValue="false" />
</properties>
</profile>
And the tables are being created when a line of code calls:
if (!PageBase.IsBaselined)
My PageBase code for IsBaselined is:
public static bool IsBaselined
{
get { return ((bool)(HttpContext.Current.Profile.GetPropertyValue("IsBaselined"))); }
set { HttpContext.Current.Profile.SetPropertyValue("IsBaselined", value); }
}
So, I assume that the "profile defaultProvider="ProfileProviderSql" is what is causing the tables to be created, but I'm not sure what I should use to keep the functionality but not keep the table creation.
I hope this is a better explanation.

Web.Config.Release Transform not updating Keys,etc

It appears that my release config is not transforming properly.
This is the setup:
Web.Config
<appSettings>
<add key="key1" value="1"/>
<add key="key2" value="1"/>
<add key="key3" value="1"/>
<add key="key4" value="1"/>
<add key="key5" value="1"/>
<add key="key6" value="1"/>
<appSettings>
Web.Config.Release
<appSettings>
<add key="key1" value="0" xdt:Transform="Replace"/>
<add key="key2" value="0" xdt:Transform="Replace"/>
<add key="key3" value="0" xdt:Transform="Replace"/>
<appSettings>
And this is what gets published
Web.Config (Published)
<appSettings>
<add key="key3" value="0"/>
<add key="key1" value="1"/>
<add key="key2" value="1"/>
<add key="key3" value="1"/>
<add key="key4" value="1"/>
<add key="key5" value="1"/>
<add key="key6" value="1"/>
<appSettings>
Weird, anyone know why this is happening?
For appSettings, since all tag is <add>, the way to transform is different:
<add key="key1" value="0" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />

Right way to Handle URL Errors with %20 and %3F in ASP.NET 4.0

90% of the pages on my website follows this syntax
http://www.thisismysite.com/ShowProduct.aspx?ID=29
http://www.thisismysite.com/BrowseProducts.aspx?CatID=58
I was checking Google webmaster tools and saw that my site is generating errors for the following url's
http://www.thisismysite.com/ShowProduct.aspx%20ID=50
http://www.thisismysite.com/BrowseProducts.aspx%20CatID=58
http://www.thisismysite.com/ShowProduct.aspx%3FID%3D900
http://www.thisismysite.com/ShowProduct.aspx%3FID=727
http://www.thisismysite.com/ShowProduct.aspx%3FID=64
http://www.thisismysite.com/GetProductsRss.aspx%3FCatID%3D60
When I browsed these url's, I got the error
Server Error in '/' Application.
Runtime Error
Description: An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
How can I fix these errors? I know about the relaxedUrlToFileSystemMapping="true" but isn't that a hack? What's the proper way to handle these url's
A portion of my web.config looks like this
<system.web>
<httpRuntime requestValidationMode="2.0" />
<authentication mode="Forms">
<forms cookieless="UseCookies" loginUrl="~/AccessDenied.aspx" name="TBFORMAUTH" />
</authentication>
<pages theme="TemplateM" masterPageFile="~/Template.master" maintainScrollPositionOnPostBack="false" validateRequest="false" enableEventValidation="false" viewStateEncryptionMode="Never" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
</pages>
<!--
Possible modes are "transitional", "strict", and "legacy".
<xhtmlConformance mode="transitional" />
-->
<compilation debug="false" targetFramework="4.0">
<assemblies>
<add assembly="System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C53R34E089" /></assemblies></compilation>
<sessionState mode="InProc" cookieless="false" timeout="15" />
<roleManager enabled="true" cacheRolesInCookie="true" cookieName="TBROLES" defaultProvider="TB_RoleProvider">
<providers>
<add connectionStringName="LocalSqlServer" applicationName="/" name="TB_RoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f22f50a3a" />
</providers>
</roleManager>
<anonymousIdentification cookieless="UseCookies" enabled="false" />
<profile defaultProvider="TB_ProfileProvider">
<providers>
<add name="TB_ProfileProvider" connectionStringName="LocalSqlServer" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f64f1d50a3a" />
</providers>
<properties>
<add name="FirstName" type="String" />
<add name="LastName" type="String" />
<add name="Gender" type="String" />
<add name="BirthDate" type="DateTime" />
<add name="Occupation" type="String" />
<add name="Website" type="String" />
<group name="Forum">
<add name="Posts" type="Int32" />
<add name="AvatarUrl" type="String" />
<add name="Signature" type="String" />
</group>
<group name="Address">
<add name="Street" type="String" />
<add name="PostalCode" type="String" />
<add name="City" type="String" />
<add name="State" type="String" />
<add name="Country" type="String" />
</group>
<group name="Contacts">
<add name="Phone" type="String" />
<add name="Fax" type="String" />
</group>
<group name="Preferences">
<add name="Theme" type="String" allowAnonymous="false" />
<add name="Culture" type="String" defaultValue="en-US" />
</group>
</properties>
</profile>
<webParts enableExport="true">
<personalization defaultProvider="TB_PersonalizationProvider">
<providers>
<add name="TB_PersonalizationProvider" connectionStringName="LocalSqlServer" type="System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
<authorization>
<allow roles="Administrators,Editors" verbs="enterSharedScope" />
</authorization>
</personalization>
</webParts>
<machineKey validationKey="287C5D125D6B7E7223E1F719E3D58D17BB9677030175D6B7E7223E1F719E3D58D17BBC7E59800B5D4C2EDD5B5D6B7E7223E1F719E3D58D17BBBAF260D9D374A74C76CB741803" decryptionKey="5C1D8BD9DF3E1B4E1D05C1D8BD9DF616E0D5C1D8BD9DF" validation="SHA1" />
<customErrors defaultRedirect="~/Error.aspx" redirectMode="ResponseRewrite">
</customErrors>
<urlMappings>
<add url="~/articles/beer.aspx" mappedUrl="~/BrowseProducts.aspx?CatID=28" />
<add url="~/articles/events.aspx" mappedUrl="~/BrowseProducts.aspx?CatID=41" />
<add url="~/articles/news.aspx" mappedUrl="~/BrowseProducts.aspx?CatID=31" />
<add url="~/articles/photos.aspx" mappedUrl="~/BrowseProducts.aspx?CatID=40" />
<add url="~/articles/blog.aspx" mappedUrl="~/BrowseProducts.aspx?CatID=29" />
<add url="~/articles/faq.aspx" mappedUrl="~/BrowseProducts.aspx?CatID=42" />
</urlMappings>
<healthMonitoring heartbeatInterval="10800">
<providers>
<remove name="SqlWebEventProvider" />
<add name="SqlWebEventProvider" connectionStringName="LocalSqlServer" buffer="false" bufferMode="Notification" maxEventDetailsLength="1073741823" type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7fse350a3a" />
</providers>
<eventMappings>
<add name="TB Events" type="MB.Customs.WebCustomEvent, MB.Customs.CustomEvents" />
</eventMappings>
<rules>
<clear />
<add name="TB Events" eventName="TB Events" provider="SqlWebEventProvider" profile="Critical" />
<add name="All Errors" eventName="All Errors" provider="SqlWebEventProvider" profile="Critical" />
<add name="Failure Audits" eventName="Failure Audits" provider="SqlWebEventProvider" profile="Critical" />
<add name="Heartbeats" eventName="Heartbeats" provider="SqlWebEventProvider" profile="Critical" />
</rules>
</healthMonitoring>
</system.web>
Because these external links are URL encoded, ASP.NET will try to find files or routes with that name. You could try messing around with the routing framework to be smart about looking for URLs that start with the routes in your application. However, this would probably mean each page needs additional logic within them to parse the improperly encoded requests. Another solution is to add custom error handling for the 404 that ASP.NET will generate when you know how to best redirect the user.
Probably the best way you could handle this error would be to intercept errors in your Applications Global.asax.cs file. You could try something like the following in your Application_Error method:
protected void Application_Error(Object sender, EventArgs e)
{
bool httpError = Context.Error is HttpException;
if (httpError && ((HttpException)Context.Error).GetHttpCode() == 404)
{
// Convert the path to lowercase. This should ONLY be used to make finding indices easier, but NOT used when generating the redirect path since case could be important.
string absolutePath = Request.Url.AbsolutePath.ToLowerInvariant();
int extensionLength = ".aspx".Length;
int questionMarkIdx = absolutePath.IndexOf("?");
int encodedQuestionMarkIdx = absolutePath.IndexOf(".aspx%3F") + extensionLength;
int encodedSpaceIdx = absolutePath.IndexOf(".aspx%20") + extensionLength;
// Handle encoded question mark
if ((questionMarkIdx == -1) && (encodedQuestionMarkIdx > extensionLength))
{
string correctPath = Request.Url.AbsolutePath.Substring(0, absolutePath.Length - encodedQuestionMarkIdx);
// Add 3 here to exclude the "%3F" in the result
string encodedQueryString = Request.Url.AbsolutePath.Substring(encodedQuestionMarkIdx + 3);
Response.Redirect(correctPath + "?" + HttpUtility.UrlDecode(encodedQueryString));
}
// Handle encoded space
if ((questionMarkIdx == -1) && (encodedSpaceIdx > extensionLength))
{
string correctPath = Request.Url.AbsolutePath.Substring(0, absolutePath.Length - encodedSpaceIdx);
// Add 3 here to exclude the "%20" in the result
string encodedQueryString = Request.Url.AbsolutePath.Substring(encodedSpaceIdx + 3);
Response.Redirect(correctPath + "?" + HttpUtility.UrlDecode(encodedQueryString));
}
}
}
I wrote this answer on a non-Windows machine, so I don't have a way to test it but this should be enough to get you in the general direction you should go in solving this problem.
The important point is to make a distinction between 404s that happened because the URL was improperly encoded and 404s that happened because of some other generic reason you're unable to handle. You only want to handle 404s due to URL encoding issues. All other errors and other 404 messages should be propagated back to your default handlers.
Also an important thing to check is what the referrer is on these requests to bad URLs. You should look in Google Webmaster tools to see if they tell you. If they don't you need to check your logs (or ensure you make some!) to find out where they're coming from. Once you know the source you should contact the site owner to let them know they're serving out bad URLs. Trying to compensate for broken external links is not foolproof and is a very difficult challenge that can become a full-time job on its own, so you're best off trying to stop them from being generated in the first place if it's within your power to make it happen.

asp.net getting error when trying to get or set profile properties

I'm having trouble figuring out why I'm getting this error message:
A network-related or instance-specific error occurred while establishing a connection to
SQL Server. The server was not found or was not accessible. Verify that the instance name
is correct and that SQL Server is configured to allow remote connections. (provider: SQL
Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
I have a simple membership and rolemanager set up and working properly like this:
<connectionStrings>
<add name="GustaafConnectionString" connectionString="Data Source=ROBBIE-PC\PHL;Initial Catalog=Gustaaf;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
<authentication mode="Forms">
<forms timeout="1440" protection="All" slidingExpiration="true"/>
</authentication>
<anonymousIdentification enabled="true"/>
<roleManager enabled="true" defaultProvider="RoleProvider">
<providers>
<add connectionStringName="GustaafConnectionString" applicationName="Gustaaf" name="RoleProvider" type="System.Web.Security.SqlRoleProvider"/>
</providers>
</roleManager>
<membership defaultProvider="MembershipProvider">
<providers>
<clear/>
<add name="MembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="GustaafConnectionString"
applicationName="Gustaaf" enablePasswordRetrieval="true" enablePasswordReset="false" requiresQuestionAndAnswer="true"
requiresUniqueEmail="false" passwordFormat="Encrypted"/>
</providers>
</membership>
That's great and all, but the error happens here:
<profile>
<properties>
<add
name="numberOfVisits"
type="Int32"
defaultValue="0"
allowAnonymous="true" />
<group name="Address">
<add name="City"
defaultValue="NA"/>
<add name="PostalCode"
type="Int32"
defaultValue="0"/>
<add name="Street"
defaultValue="NA" />
<add name="Number"
type="Int32"
defaultValue="0" />
</group>
<add name="PhoneNumber"
defaultValue="NA"/>
<add name="DateOfBirth" type="DateTime"
defaultValue="GetDate()"/>
</properties>
</profile>
As soon as I try to access these properties from a website like for example the masterpage, I get the error message above. Here's what I'm doing:
protected void Page_PreRender()
{
if (Profile.IsAnonymous)
{
Profile.numberOfVisits++;
}
}
Could someone explain to me why I'm getting this message?
You need to define a provider for the profile like you have done for Roles/Membership so
something like this -
<profile defaultProvider="SqlProvider">
<providers>
<clear/>
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="GustaafConnectionString"
applicationName="Gustaaf" />
</providers>
<properties>
<!-- Properties Here -->
</properties>
</profile>
See here for full reference http://msdn.microsoft.com/en-us/library/system.web.profile.sqlprofileprovider.aspx

UserName parameter from ProfileParameter comes back null

I am trying to call a method with the username of the logged in user. I have the following code.
<asp:ObjectDataSource ID="odsFiles" runat="server" SelectMethod="getFiles" TypeName="MyProject.FileSystemBrowser">
<SelectParameters>
<asp:ProfileParameter Name="username" PropertyName="UserName" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
When I debug, and look at the getFiles the username parameter is null.
I suspect it has to do with my web.config setup, so here's the profile section from it.
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>

Resources