2010-06-21 66 views
3

我試圖將示例表配置文件提供程序從http://www.asp.net/downloads/sandbox/table-profile-provider-samples添加到新的MVC 2站點。ASP.NET MVC 2和SQL表配置文件提供程序

經過一番研究和擺弄,我已經到了一個看起來像這樣的配置文件類。

namespace MyNamespace.Models 
{ 
    public class UserProfile : ProfileBase 
    { 
     [SettingsAllowAnonymous(false),CustomProviderData("FirstName;nvarchar")] 
     public string FirstName 
     { 
      get { return base["FirstName"] as string; } 
      set { base["FirstName"] = value; } 
     } 

     [SettingsAllowAnonymous(false),CustomProviderData("LastName;nvarchar")] 
     public string LastName 
     { 
      get { return base["LastName"] as string; } 
      set { base["LastName"] = value; } 
     } 

     public static UserProfile GetUserProfile(string username) 
     { 
      return Create(username,false) as UserProfile; 
     } 

     public static UserProfile GetUserProfile() 
     { 
      return Create(Membership.GetUser().UserName,true) as UserProfile; 
     } 
    } 
} 

而像

<profile enabled="true" defaultProvider="TableProfileProvider" inherits="MyNamespace.Models.UserProfile"> 
    <providers> 
    <clear /> 
    <add name="TableProfileProvider" type="Microsoft.Samples.SqlTableProfileProvider" connectionStringName="ContentDB" table="aspnet_UserProfiles" applicationName="/"/> 
    </providers> 
</profile> 

事情的web.config我覺得我的人生路上發現有

  • 使用與MVC定製的提供者要求「繼承」屬性位於web.config中的<profile>元素上,該元素排除使用具有相同配置文件字段名稱的<properties><add ....>構造。
  • 示例SQL表配置文件提供程序需要CustomProviderData屬性,並且由於上述原因,它不能出現在web.config文件中,因此需要將其作爲屬性添加到配置文件類中的屬性。

這一切似乎工作正常一旦用戶登錄。但是,我想捕獲一些配置文件數據作爲新的用戶註冊過程的一部分,我似乎無法訪問該配置文件對象,直到用戶登錄。

我試過添加一個調用來保存配置文件數據MVC的模板代碼的新用戶註冊部分:

FormsService.SignIn(model.UserName, false /* createPersistentCookie */); 
UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName); 
profile.FirstName = "Doug"; 
Profile.Save(); 
return RedirectToAction("Index", "Home"); 

但是似乎Membership.GetUser()爲空,直到用戶實際登錄我也使用用戶的名字從模型嘗試。

FormsService.SignIn(model.UserName, false /* createPersistentCookie */); 
UserProfile profile = UserProfile.GetUserProfile(model.UserName); 
profile.FirstName = "Doug"; 
profile.Save(); 
return RedirectToAction("Index", "Home"); 

這進一步得到了一點,但未能當試圖設置姓輪廓領域,隨着沿着線的錯誤信息「試圖設置一個屬性作爲匿名用戶,但是這是不允許的」(對不起,我沒有輸入這個確切的信息)。

有沒有什麼辦法呢?它看起來像FormsServer.SignIn方法實際上並沒有記錄用戶,只要表單身份驗證,它需要一個往返才能完全登錄,可能需要將cookie提交回服務器。

如果沒有簡單的方法,我可以使用數據訪問方法直接填充配置文件表(插入到aspnet_UserProfiles ....)。這是一座橋樑,還是一個可行的解決方案?


沒有人有這個問題嗎?沒有?然後就是我!

爲了更新,我嘗試了Franci Penov在他對這個posting的回答中提出的建議。

所以,現在我的代碼看起來像這樣。

  FormsService.SignIn(model.UserName, false /* createPersistentCookie */); 

      GenericIdentity id = new GenericIdentity(model.UserName); 
      HttpContext.User = new GenericPrincipal(id, null); 

      UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName) as UserProfile; 
      profile.FirstName = "Doug"; 
      profile.Save(); 

      return RedirectToAction("Index", "Home"); 

現在,至少需要致電會員。的getUser()返回一個有效MembershipUser對象,但試圖設置姓配置文件屬性仍然會導致消息This property cannot be set for anonymous users.

所以,用戶只要成員而言登錄,但檔案系統仍然認爲沒有。

任何想法?

+0

好東西,非常有用,謝謝。 只想補充一點,您可能希望在自定義配置文件類的屬性設置器中包含this.Save()方法。當我試圖找出爲什麼我的更改沒有持續時,我發現這很有幫助。 – randomsequence 2011-07-08 13:42:16

+0

嗨@Doug,偉大的職位!我想知道是否使用tableprofileprovider創建了匿名標識的解決方案。它似乎工作很好,當用戶通過身份驗證,但我想不出如何與匿名用戶合作,以​​登錄到他們的配置文件的東西,如語言等。在獲得他們註冊之前... – 2012-01-11 13:41:23

回答

4

萬歲!

更仔細地讀這posting,我想我會嘗試顯式調用配置文件Initialize方法,它的工作!對寄存器的操作方法

最後的完整的代碼:

[HttpPost] 
public ActionResult Register(RegisterModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Attempt to register the user 
     MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email); 

     if (createStatus == MembershipCreateStatus.Success) 
     { 
      FormsService.SignIn(model.UserName, false /* createPersistentCookie */); 

      GenericIdentity id = new GenericIdentity(model.UserName); 
      HttpContext.User = new GenericPrincipal(id, null); 

      UserProfile profile = UserProfile.GetUserProfile(Membership.GetUser().UserName) as UserProfile; 
      profile.Initialize(Membership.GetUser().UserName, true); 
      profile.FirstName = "Doug"; 
      profile.Save(); 

      return RedirectToAction("Index", "Home"); 
     } 
     else 
     { 
      ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus)); 
     } 
    } 

    // If we got this far, something failed, redisplay form 
    ViewData["PasswordLength"] = MembershipService.MinPasswordLength; 
    return View(model); 
} 

希望這有助於。

Doug

+0

你幫我很多! brgds – 2011-12-09 22:56:09

0

我有一個更簡單的方法來解決這個問題。

我設置在我的web.config文件中的以下內容:

<profile enabled="true"> 
    <providers> 
    <clear /> 
    <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" /> 
    </providers> 
    <properties> 
    <add name="InfoID" /> 
    <add name="FirstName" /> 
    <add name="LastName" /> 
    <add name="Address" /> 
    <add name="City" /> 
    <add name="State" /> 
    <add name="PostalCode" /> 
    <add name="Country" /> 
    <add name="Phone" /> 
    </properties> 
</profile> 

要在我的AccountController類更新它,我用了以下內容:

var user = db.UserInformations.FirstOrDefault(u => u.InfoID == infoID); 
var profile = Request.RequestContext.HttpContext.Profile; 
profile.Initialize(register.UserName, true); 
profile.SetPropertyValue("InfoID", user.InfoID.ToString()); 
profile.SetPropertyValue("LastName", user.LastName); 
profile.SetPropertyValue("FirstName", user.FirstName); 
profile.SetPropertyValue("Address", user.Address); 
profile.SetPropertyValue("City", user.City); 
profile.SetPropertyValue("State", user.State); 
profile.SetPropertyValue("Country", user.Country); 
profile.SetPropertyValue("PostalCode", user.PostalCode); 
profile.SetPropertyValue("Phone", user.Phone); 
profile.Save(); 

而不是使用字符串鍵,你可以創建一個動態包裝並用profile變量初始化它。

這對我來說很好。它爲用戶指定的用戶更新標準的aspnet_Profile數據庫。我從一個登錄系統轉換到標準登錄,所以我有額外的InfoID字段(它鏈接到另一個數據庫)。我在登錄時通過這種方式傳輸信息。

您應該先檢查特定用戶的信息是否存在於任何字段,然後在登錄時進行不必要的設置或僅更新那些需要更改的字段。

注意:您必須首先初始化配置文件,否則任何更改都會導致黃色屏幕錯誤。

相關問題