我已经学习了很多浏览C#的隐藏功能,当我找不到类似于VB.NET的东西时,我感到很惊讶.
那么它的一些隐藏或鲜为人知的特征是什么?
我通过继承来在ac#类库中创建了一个自定义配置部分ConfigurationSection.我在我的Web应用程序(也是c#,ASP.NET)中引用类库,填写适当的属性,一切都很好.当我开始添加验证器时,问题就开始了.
例如,这个属性:
[ConfigurationProperty("appCode", IsRequired = true)]
public string ApplicationCode
{
get
{
return (string)base["appCode"];
}
set
{
base["appCode"] = value;
}
}
Run Code Online (Sandbox Code Playgroud)
因为它工作正常,但只要我添加这个:
[StringValidator(MinLength=1)]
Run Code Online (Sandbox Code Playgroud)
它轰炸了以下错误:
属性"appCode"的值无效.错误是:字符串长度必须至少为1个字符.
即使appCode我的web.config文件中有有效值,我也会收到此错误.如果我删除验证器,它可以完美地工作.有谁知道怎么解决这个问题?
根据MSDN:
如果未使用Start方法启动进程,则StartInfo属性不会反映用于启动进程的参数.例如,如果使用GetProcesses获取计算机上运行的进程数组,则每个进程的StartInfo属性不包含用于启动进程的原始文件名或参数.
好的,这很有道理.我的问题是,即使你使用Process.Start(),为什么这些参数都是空白的?
例如:
Dim startInfo As New ProcessStartInfo("firefox.exe")
startInfo.Arguments = "www.stackoverflow.com"
startInfo.WindowStyle = ProcessWindowStyle.Minimized
Process.Start(startInfo)
For Each proc As Process In Process.GetProcessesByName("firefox")
Debug.Print(String.Format("ProcessID={0}; Arguments={1}", _
proc.Id, proc.StartInfo.Arguments))
Next proc
Run Code Online (Sandbox Code Playgroud)
在这种情况下,即使我提供了Arguments,该属性仍为空:
替代文字http://www.sg-squared.com/images/startinfo.png
是什么赋予了?
我习惯于在C#中嵌入资源,我喜欢它自动将命名空间添加到嵌入式资源的方式.这允许我做这样的事情:
files\version1\config.xml
files\version2\config.xml
files\version2\config.xml
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果你在VB.NET项目中尝试相同的操作,你将会遇到编译错误,因为它试图将所有嵌入的资源放入根命名空间.为了解决这个问题,我可以.vbproj像这样手动编辑文件:
<EmbeddedResource Include="files\version1\config.xml">
<LogicalName>$(RootNamespace).files.version1.config.xml</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="files\version2\config.xml">
<LogicalName>$(RootNamespace).files.version2.config.xml</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="files\version3\config.xml">
<LogicalName>$(RootNamespace).files.version3.config.xml</LogicalName>
</EmbeddedResource>
Run Code Online (Sandbox Code Playgroud)
虽然这是有效的,但它是手动的,耗时且容易出错的,所以我的问题是:构建任务或构建事件是否可以自动执行?
我有一个继承自基类的类,并实现以下...
Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
Run Code Online (Sandbox Code Playgroud)
现在它继承的基类也实现了这个System.IComparable.CompareTo所以我得到以下编译器警告:
警告:'System.IComparable.CompareTo'已由基类实现.重新实现假定的功能.
我很好,所以我的问题是我怎么能只为这个功能压制这个警告(即不是所有这些警告).
澄清:
解决方案:
我希望使用System.Diagnostics.CodeAnalysis.SuppressMessage属性或类似C#的#pragma,但看起来没有办法抑制单行警告.有一种方法可以为此项目关闭此消息,但不会关闭所有警告.
我手动编辑了.vbproj文件,并在节点中包含42015用于调试和发布编译.不理想但比总是在IDE中看到警告更好.
如果有人有更好的解决方案,请添加它,我很乐意尝试标记答案.
作为这个问题的后续,我希望有人可以帮助CredEnumerate API.
据我从文档中了解,PCREDENTIALS out参数是"指向凭证指针数组的指针".我能够使用C#成功调用CredEnumerate API,但我不确定如何将PCREDENTIALS转换为有用的东西(如凭证列表).
编辑:这是我正在使用的代码:
int count = 0;
IntPtr pCredentials = IntPtr.Zero;
bool ret = false;
ret = CredEnumerate(null, 0, out count, out pCredentials);
if (ret != false)
{
IntPtr[] credentials = new IntPtr[count];
IntPtr p = pCredentials;
for (int i = 0; i < count; i++)
{
p = new IntPtr(p.ToInt32() + i);
credentials[i] = Marshal.ReadIntPtr(p);
}
List<Credential> creds = new List<Credential>(credentials.Length);
foreach (IntPtr ptr in credentials)
{
creds.Add((Credential)Marshal.PtrToStructure(ptr, typeof(Credential)));
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,虽然这适用于阵列中的第一个凭证 - …
我正在使用LINQ to SQL与Sql Server Compact Edition 3.5和VS2008.
我有一个非常简单的表(Tokens),带有uniqueidentifier主键(TokenID)和另外两个可空字段(UsedBy和UsedOn).我试图使用LINQ在表中插入新行,但由于某种原因,它们不会持久化.
这是我的代码:
var connectionstring = "Data Source=|DataDirectory|\\MyData.sdf";
MyData db = new MyData(connectionstring) { Log = Console.Out };
Tokens token = new Tokens { TokenID = Guid.NewGuid() };
db.Tokens.InsertOnSubmit(token);
//db.GetChangeSet();
db.SubmitChanges();
var tokens = from t in db.Tokens
select t;
foreach (var t in tokens)
{
Debug.Print(t.TokenID.ToString());
}
Run Code Online (Sandbox Code Playgroud)
如果我取消注释db.GetChangeSet(); 我可以看到挂起的插入,当我迭代并将它们打印到调试窗口时,每次都会增加令牌数.但是,如果我在VS中查询表(通过显示表数据)它是空的?查看这样的数据也会"重置"LINQ返回的令牌的原始状态.
我很确定我犯了一些简单的错误,但我看不出来.有任何想法吗?
我需要以另一个用户开始一个进程,这是一个轰炸.
我将我的代码缩减为一个简单的参考示例.此代码可以正常启动进程:
var info = new ProcessStartInfo("notepad.exe")
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardError = true,
RedirectStandardOutput = true
};
Run Code Online (Sandbox Code Playgroud)
但是,如果我添加UserName和Password值:
var info = new ProcessStartInfo("notepad.exe")
{
UserName = "user",
Password = StringToSecureString("password"),
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardError = true,
RedirectStandardOutput = true
};
Process.Start(info);
Run Code Online (Sandbox Code Playgroud)
它轰炸了一个非常有用的System.ComponentModel.Win32Exception消息:
无法启动该服务,因为它已被禁用,或者因为它没有与之关联的已启用设备.
以防万一,这是安全字符串转换方法:
private static SecureString StringToSecureString(string s)
{
var secure = new SecureString();
foreach (var c in s.ToCharArray())
{
secure.AppendChar(c);
}
return secure;
}
Run Code Online (Sandbox Code Playgroud)
任何想法或替代解决方案将非常感谢!