如何分配configuration文件值?
我不知道我缺less什么,但我在Web.config文件中添加了configuration文件属性,但无法访问configuration文件。 在代码中的项目或创build一个新的configuration文件。
今天我也有同样的问题,并且学到了很多东西。
Visual Studio中有两种项目 – “网站项目”和“Web应用程序项目”。 由于对我来说完全神秘的原因,Web应用程序项目不能使用Profile。 直接…强types的类不是从你的Web.config文件中神奇的生成的,所以你必须自己动手。
MSDN中的示例代码假设您正在使用Web站点项目,并且他们告诉您只需要将<profile>
添加到您的Web.config
和派对上即可Profile.
属性 ,但在Web应用程序项目中不起作用。
你有两个select来推出自己的:
(1)使用Web Profile Builder 。 这是您添加到Visual Studio的自定义工具,它会自动生成Web.config中定义所需的Profile对象。
我select不这样做,因为我不希望我的代码依赖这个额外的工具进行编译,这可能会导致其他人的问题,当他们试图构build我的代码,而没有意识到他们需要这个工具。
(2)让你自己的类从ProfileBase
派生来表示你的自定义configuration文件。 这比看起来更容易。 这是一个非常简单的例子,添加一个“FullName”stringconfiguration文件字段:
在你的web.config中:
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile"> <providers> <clear /> <add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="sqlServerMembership" /> </providers> </profile>
在一个名为AccountProfile.cs的文件中:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Profile; using System.Web.Security; namespace YourNamespace { public class AccountProfile : ProfileBase { static public AccountProfile CurrentUser { get { return (AccountProfile) (ProfileBase.Create(Membership.GetUser().UserName)); } } public string FullName { get { return ((string)(base["FullName"])); } set { base["FullName"] = value; Save(); } } // add additional properties here } }
要设置configuration文件值:
AccountProfile.CurrentUser.FullName = "Snoopy";
获取configuration文件值
string x = AccountProfile.CurrentUser.FullName;
Web应用程序项目仍然可以使用ProfileCommon对象,但只能在运行时。 它的代码只是没有在项目本身生成,但类由ASP.Net生成,并在运行时出现。
获得对象最简单的方法是使用dynamictypes,如下所示。
在Web.config文件中声明configuration文件属性:
<profile ... <properties> <add name="GivenName"/> <add name="Surname"/> </properties>
然后访问属性:
dynamic profile = ProfileBase.Create(Membership.GetUser().UserName); string s = profile.GivenName; profile.Surname = "Smith";
要保存对configuration文件属性的更改:
profile.Save();
上面的工作很好,如果你是舒适的使用dynamictypes,不介意编译时检查和智能感知缺乏。
如果将此与ASP.Net MVC一起使用,那么如果将dynamicconfiguration文件对象传递给您的视图,则必须执行一些额外的工作,因为HTML帮助程序方法不能很好地与dynamic的“模型”对象配合使用。 您必须先将configuration文件属性分配给静态typesvariables,然后再将它们传递给HTML帮助器方法。
// model is of type dynamic and was passed in from the controller @Html.TextBox("Surname", model.Surname) <-- this breaks @{ string sn = model.Surname; } @Html.TextBox("Surname", sn); <-- will work
如果您创build一个自定义configuration文件类,如上面所述的Joel,则ASP.Net仍然会生成ProfileCommon类,但它将inheritance自您的自定义configuration文件类。 如果您不指定自定义configuration文件类,则ProfileCommon将从System.Web.Profile.ProfileBaseinheritance。
如果您创build自己的configuration文件类,请确保您没有在您的自定义configuration文件类中声明的Web.config文件中指定configuration文件属性。 如果您尝试生成ProfileCommon类,则ASP.Net会给出编译器错误。
configuration文件也可以在Web应用程序项目中使用。 这些属性可以在devise时或通过编程的方式在Web.config中定义。 在Web.config中:
<profile enabled="true" automaticSaveEnabled="true" defaultProvider="AspNetSqlProfileProvider"> <providers> <clear/> <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="TestRolesNProfiles"/> </providers> <properties> <add name="FirstName"/> <add name="LastName"/> <add name ="Street"/> <add name="Address2"/> <add name="City"/> <add name="ZIP"/> <add name="HomePhone"/> <add name="MobilePhone"/> <add name="DOB"/> </properties> </profile>
或以编程方式通过实例化ProfileSection并使用ProfilePropertySettings和ProfilePropertySettingsColletion创build个别属性来创build概要文件部分,所有这些都位于System.Web.Configuration Namespace中。 要使用configuration文件的这些属性,请使用System.Web.Profile.ProfileBase对象。 configuration文件属性无法使用configuration文件进行访问。 语法,但可以通过实例化ProfileBase并使用SetPropertyValue (“ PropertyName ”)和GetPropertyValue {“ PropertyName ”)来轻松完成,如下所示:
ProfileBase curProfile = ProfileBase.Create("MyName");
或访问当前用户的configuration文件:
ProfileBase curProfile = ProfileBase.Create(System.Web.Security.Membership.GetUser().UserName); curProfile.SetPropertyValue("FirstName", this.txtName.Text); curProfile.SetPropertyValue("LastName", this.txtLname.Text); curProfile.SetPropertyValue("Street", this.txtStreet.Text); curProfile.SetPropertyValue("Address2", this.txtAdd2.Text); curProfile.SetPropertyValue("ZIP", this.txtZip.Text); curProfile.SetPropertyValue("MobilePhone", txtMphone.Text); curProfile.SetPropertyValue("HomePhone", txtHphone.Text); curProfile.SetPropertyValue("DOB", txtDob.Text); curProfile.Save();
当您在Visual Studio中创build新的Web站点项目时,将从(自动)为您生成从configuration文件返回的对象。 当你创build一个Web应用程序项目或一个MVC项目时,你将不得不推出自己的。
这可能听起来比它更困难。 您需要执行以下操作:
- 使用aspnet_regsql.exe创build数据库此工具与.NET框架一起安装。
- 编写从ProfileGroupBase派生的类,或者从Web.Config中的定义中安装可为您生成类的Web Profile Builder(WPB)。 我一直在使用WPB,直到现在它已经完成了预期的工作。 如果你有很多属性,使用WPB可以节省相当多的时间。
- 确保在Web.Config中正确configuration了到数据库的连接。
- 现在,您将被设置为创build您的configuration文件类的实例(在控制器中)
- 您可能需要视图中的configuration文件属性值。 我喜欢将configuration文件对象本身传递给视图(而不是单独的属性)。
如果您正在使用Web应用程序项目,则无法在devise时即时访问Profile对象。 这是一个实用工具,可以帮你: http : //weblogs.asp.net/joewrobel/archive/2008/02/03/web-profile-builder-for-web-application-projects.aspx 。 就个人而言,该实用程序在我的项目中导致了一个错误,所以我最终滚动我自己的configuration文件类从ProfileBaseinheritance。 一点也不难。
用于创build自定义类(又名Joel的方法)的MSDN演练:
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
我也遇到了同样的问题。 但是,而不是创build一个inheritance自ProfileBase的类,我使用HttpContext。
在web.config文件中指定属性,如下所示: –
现在,写下面的代码:
编译并运行代码。 您将得到以下输出:
networkingconfiguration文件生成器为我工作的很好。 它产生的类比Joel的post中描述的要多得多。 无论其实际需要或有用,我不知道。
无论如何,对于那些寻找一个简单的方法来生成类,但不想有一个外部构build工具的依赖,你可以随时
- 使用networkingconfiguration文件生成器
- 删除它的所有痕迹!
- 继续使用生成的Profile类
或(未经testing,但可能只是工作)
- 创build一个网站项目
- 创造你的元素
- 捕捉生成的类并将其复制到您的Web 项目项目中
如果第二种方法确实有效,可以让我知道以备将来参考
只是想补充Joel Spolsky的回答
我实施他的解决scheme,工作出色btw – Cudos!
对于任何想要获取用户个人资料的用户,我都不是这样login的用户:
web.config中:
<connectionStrings> <clear /> <add name="LocalSqlConnection" connectionString="Data Source=***;Database=***;User Id=***;Password=***;Initial Catalog=***;Integrated Security=false" providerName="System.Data.SqlClient" /> </connectionStrings>
和
<profile defaultProvider="SqlProvider" inherits="NameSpace.AccountProfile" enabled="true"> <providers> <clear/> <add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="LocalSqlConnection"/> </providers>
然后我的自定义类:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Profile; using System.Web.Security; namespace NameSpace { public class AccountProfile : ProfileBase { static public AccountProfile CurrentUser { get { return (AccountProfile) (ProfileBase.Create(Membership.GetUser().UserName)); } } static public AccountProfile GetUser(MembershipUser User) { return (AccountProfile) (ProfileBase.Create(User.UserName)); } /// <summary> /// Find user with matching barcode, if no user is found function throws exception /// </summary> /// <param name="Barcode">The barcode to compare against the user barcode</param> /// <returns>The AccountProfile class with matching barcode or null if the user is not found</returns> static public AccountProfile GetUser(string Barcode) { MembershipUserCollection muc = Membership.GetAllUsers(); foreach (MembershipUser user in muc) { if (AccountProfile.GetUser(user).Barcode == Barcode) { return (AccountProfile) (ProfileBase.Create(user.UserName)); } } throw new Exception("User does not exist"); } public bool isOnJob { get { return (bool)(base["isOnJob"]); } set { base["isOnJob"] = value; Save(); } } public string Barcode { get { return (string)(base["Barcode"]); } set { base["Barcode"] = value; Save(); } } } }
奇迹般有效…
伟大的职位,
只要在web.config上注释一下,如果你没有在profile元素中指定inherit属性,你将需要在web.config的profile元素中指定每个独立的profile属性,如下所示
<properties> <clear/> <add name="property-name-1" /> <add name="property-name-2" /> .......... </properties>