小编Pre*_*zel的帖子

ASP.NET MVC:如何使用C#中的Reflection使用[Authorize]属性查找控制器?(或如何构建动态Site.Master菜单?)

也许在进入标题问题之前我应该​​备份并扩大范围......

我目前正在ASP.NET MVC 1.0中编写一个Web应用程序(虽然我的PC上安装了MVC 2.0,所以我并不完全限于1.0) - 我已经开始使用标准的MVC项目了基本的"欢迎使用ASP.NET MVC",并在右上角显示[Home]选项卡和[About]选项卡.很标准,对吗?

我添加了4个新的Controller类,我们称之为"天文学家","生物学家","化学家"和"物理学家".附加到每个新控制器类的是[Authorize]属性.

例如,对于BiologistController.cs

[Authorize(Roles = "Biologist,Admin")]
public class BiologistController : Controller
{ 
    public ActionResult Index() { return View(); }
}
Run Code Online (Sandbox Code Playgroud)

这些[授权]标签自然限制哪些用户可以根据角色访问不同的控制器,但我想根据用户所属的角色在Site.Master页面的网站顶部动态构建一个菜单.例如,如果"JoeUser"是角色"天文学家"和"物理学家"的成员,导航菜单会说:

[主页] [天文学家] [物理学家] [关于]

当然,它不会列出"生物学家"或"化学家"控制器索引页面的链接.

或者,如果"JohnAdmin"是角色"Admin"的成员,则所有4个控制器的链接将显示在导航栏中.

好吧,你们大家都有了想法......现在回答真正的问题......


这个关于ASP.NET中动态菜单构建的StackOverflow主题的答案开始,我试图理解如何完全实现它.(我是新手,需要更多指导,所以请和我一起去.)

答案建议扩展Controller类(称之为"ExtController"),然后让每个新的WhateverController继承自ExtController.

我的结论是我需要在这个ExtController构造函数中使用Reflection来确定哪些类和方法附加了[Authorize]属性来确定角色.然后使用静态字典,将角色和控制器/方法存储在键值对中.

我想它是这样的:

public class ExtController : Controller
{
    protected static Dictionary<Type,List<string>> ControllerRolesDictionary;

    protected override void OnActionExecuted(ActionExecutedContext filterContext)   
    {   
        // build list of menu items based on user's permissions, and add it to ViewData  
        IEnumerable<MenuItem> menu = BuildMenu();  
        ViewData["Menu"] …
Run Code Online (Sandbox Code Playgroud)

c# asp.net reflection asp.net-mvc authorize-attribute

9
推荐指数
1
解决办法
5572
查看次数

A或B,不是两者,都不是

自从阅读清洁代码以来,我一直在努力保持代码的描述性和易于理解.我有一个条件,必须填写A或B.但不是两者.而不是.目前if,检查这种情况的声明很难一目了然.您将如何编写以下内容,以便一目了然地查看正在检查的内容

if ((!string.IsNullOrEmpty(input.A) && !string.IsNullOrEmpty(input.B)) 
    || string.IsNullOrEmpty(input.A) && string.IsNullOrEmpty(input.B))
{
    throw new ArgumentException("Exactly one A *OR* B is required.");
}
Run Code Online (Sandbox Code Playgroud)

language-agnostic if-statement coding-style xor

9
推荐指数
4
解决办法
1605
查看次数

如何在C#中清空/刷新Windows READ磁盘缓存?

如果我试图确定驱动器的读取速度,我可以编写例程来将文件写入文件系统然后再读取这些文件.不幸的是,由于Windows执行磁盘读取缓存,因此无法提供准确的读取速度.

有没有办法在C#/ .Net(或者可能使用Win32 API调用)中刷新驱动器的磁盘读取缓存,以便我可以直接从驱动器读取文件而不缓存它们?

.net c# caching disk flush

7
推荐指数
3
解决办法
1万
查看次数

ASP.NET:存储应用程序设置的位置?

最近,我发现"Web.Config"文件包含一个<appSettings>看起来适合存储应用程序设置的部分.哎呀,它甚至有一种通过标准系统库访问文件的编程方式.所以聪明一点,我写了一个接口来访问它,然后是接口的具体实现,如下所示:

public interface IAppSettings
{
    IEnumerable<string> GetValues(string componentName, string settingName);
    IEnumerable<KeyValuePair<string, string>> GetValuePairs(string componentName, string settingName);
    void SetValues(string componentName, string settingName, IEnumerable<string> valueList, bool append);
    void SetValuePairs(string componentName, string settingName, IEnumerable<KeyValuePair<string, string>> pairList, bool append);
}
Run Code Online (Sandbox Code Playgroud)

然后我发现在应用程序运行时将设置保存回"web.config"会导致整个应用程序重新启动.这对我来说似乎是完全不合理的,因为如果我回写web.config并且应用程序每次都重新启动,那么像HttpRuntime.Cache这样的东西会被完全清空,这会使我的Cache无用,因为它会不断地清空和重新填充.

所以我想知道:我应该在哪里存储我的应用程序设置?

有没有一个很好的解决方案,所以我不必自己滚?

编辑:

好的,感谢所有建议使用数据库和潜在表模式的人.我想我将采用以下架构:

settings:
    index NUMBER NOT NULL AUTO_INCREMENT   <== Primary Key
    component NVARCHAR(255) NOT NULL
    setting NVARCHAR(255) NOT NULL
    key   NVARCHAR(255)
    value NVARCHAR(255) NOT NULL
Run Code Online (Sandbox Code Playgroud)

虽然我不认为我会"设置"P-Key,但使用Auto-Incr索引代替.这样,如果我有一个需要将内容邮寄到多个管理器的应用程序,我可以存储许多:

index     component       setting        value
1         RequestModule   ManagerEmail   manager1@someplace
2         RequestModule   ManagerEmail …
Run Code Online (Sandbox Code Playgroud)

asp.net web-config appsettings application-settings

7
推荐指数
4
解决办法
9539
查看次数

如何加速慢速/滞后的Windows Phone 7(WP7)TCP Socket传输?

最近,我开始使用WP7芒果版本中引入的System.Net.Sockets类,并且一直很喜欢它,但是注意到在调试模式下传输数据的延迟与在手机上正常运行的延迟存在差异.

我正在编写一个"远程控制"应用程序,当用户点击应用程序中的按钮时,该应用程序通过Wifi将单个字节传输到我的LAN上的本地服务器.因此,应用程序的感知响应性/及时性对于良好的用户体验非常重要.

通过USB电缆将手机连接到我的电脑并在调试模式下运行应用程序,TCP连接似乎可以像用户点击按钮一样快速传输数据包.

当手机与PC断开连接时,用户最多可以点击7个按钮(因此在发送所有7个字节之前,用1个字节的有效负载进行7个"发送"命令.)如果用户点击按钮并在点击之间等待一点,似乎有1秒的延迟.

我已经尝试将Socket.NoDelay设置为True和False,它似乎没有任何区别.

为了了解发生了什么,我使用了一个数据包嗅探器来查看流量是什么样的.

  • 当手机通过USB连接到PC(使用Wifi连接)时,每个字节都在自己的数据包中间隔约200ms.

  • 当手机在自己的Wifi连接(与USB断开连接)上运行时,字节仍然有自己的数据包,但它们都以4或5个数据包的突发组合在一起,每个组与下一个相距约1000毫秒.

顺便说一句,我的Wifi网络到服务器的Ping时间是从我的笔记本电脑测量的低2ms.

我意识到缓冲"发送"可能会让手机节省能量,但有没有办法禁用这种"延迟"?应用程序的响应能力比节省电力更重要.

sockets system.net latency windows-phone-7 windows-phone-7.1

7
推荐指数
1
解决办法
3657
查看次数

@ mock.patch如何知道每个模拟对象使用哪个参数?

查看此网页:http://www.toptal.com/python/an-introduction-to-mocking-in-python - 作者在Python中讨论了Mocking和Patching,并提供了一个非常可靠的"真实世界"示例.绊倒我的部分是理解单元测试框架如何工作知道哪个模拟对象传递给哪个补丁.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
Run Code Online (Sandbox Code Playgroud)

代码示例很容易理解.对OS库/模块的硬编码依赖性.首先使用该os.path.isfile()方法检查文件是否存在,如果是,则使用删除它os.remove()

测试/模拟代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):

    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False

        rm("any path")

        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")

        # …
Run Code Online (Sandbox Code Playgroud)

python unit-testing mocking

7
推荐指数
1
解决办法
923
查看次数

在运行时更改WSDL EndPointAddress的地址/端口?

所以我目前在我的解决方案中添加了2个WSDL作为服务引用.它们在我的app.config文件中看起来像这样(我删除了"bindings"字段,因为它不感兴趣):

<system.serviceModel>
  <client>
    <endpoint address="http://localhost:8080/query-service/jse" binding="basicHttpBinding" bindingConfiguration="QueryBinding" contract="QueryService.Query" name="QueryPort" />
    <endpoint address="http://localhost:8080/dataimport-service/jse" binding="basicHttpBinding" bindingConfiguration="DataImportBinding" contract="DataService.DataImport" name="DataImportPort" />
  </client>   
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

当我使用WSDL时,它看起来像这样:

using (DataService.DataClient dClient = new DataService.DataClient())
{
  DataService.importTask impt = new DataService.importTask();
  impt.String_1 = "someData";
  DataService.importResponse imptr = dClient.importTask(impt);
}
Run Code Online (Sandbox Code Playgroud)

在"using"语句中,在实例化DataClient对象时,我有5个构造函数可供我使用.在这种情况下,我使用默认构造函数:

   new DataService.DataClient()
Run Code Online (Sandbox Code Playgroud)

它使用内置的端点地址字符串,我假设它是从app.config中提取的.但我希望应用程序的用户可以选择更改此值.

1)以编程方式获取此字符串的最佳/最简单方法是什么?

2)然后,一旦我允许用户编辑和测试值,我应该在哪里存储它?

我希望将它存储在一个地方(如app.config或等效的),这样就不需要检查值是否存在以及我是否应该使用备用构造函数.(为了保持我的密码,你知道吗?)

有任何想法吗?建议?

编辑

也许我应该问一下这些替代构造函数.

例如,其中一个看起来像这样:

   new DataService.DataClient(string endPointConfigurationName, 
                              string remoteAddress)
Run Code Online (Sandbox Code Playgroud)

可以为"endPointConfigurationName"和"remoteAddress"传递什么值?

EDIT2

在这里回答我自己的问题,"endPointConfigurationName"看起来与app.config XML中的"name"相同,"remoteAddress"的格式与app.config XML中的"endpoint address"相同.

也!关于获取EndPointAddresses的第一个问题的答案如下:

ClientSection clSection =
   ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;

ChannelEndpointElementCollection endpointCollection =
   clSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;

Dictionary<string, string> nameAddressDictionary = 
   new …
Run Code Online (Sandbox Code Playgroud)

wcf wsdl web-services app-config

5
推荐指数
1
解决办法
4193
查看次数

LINQ-to-XML to DataGridView:无法编辑字段 - 如何修复?

我目前正在使用LINQ-to-XML并使用我的查询填充DataGridView.我遇到的麻烦是,一旦加载到DataGridView中,值似乎是不可编辑的(ReadOnly).这是我的代码:

var barcodes = (from src in xmldoc.Descendants("Container")
                where src.Descendants().Count() > 0
                select
                new
                {
                   Id = (string)src.Element("Id"),
                   Barcode = (string)src.Element("Barcode"),
                   Quantity = float.Parse((string)src.Element("Quantity").Attribute("value"))
                }).Distinct();

dataGridView1.DataSource = barcodes.ToList();
Run Code Online (Sandbox Code Playgroud)

我在某处读到"使用匿名类型时,DataGridView将处于ReadOnly模式".但我无法找到解释为什么或究竟该怎么办.

有任何想法吗?

编辑 - 这是我想出的答案......

所以我添加了一个"容器"类(使用Get和Set < - 非常重要!)以避免Anonymous类型成为ReadOnly问题:

    public class Container
    {
        public string Id { get; set; }
        public string Barcode { get; set; }
        public float Quantity { get; set; }
    }

    // For use with the Distinct() operator
    public class ContainerComparer : IEqualityComparer<Container>
    {
        public bool Equals(Container x, …
Run Code Online (Sandbox Code Playgroud)

c# linq datagridview linq-to-xml c#-3.0

5
推荐指数
1
解决办法
1875
查看次数

可以在运行时更改数据注释吗?(ASP.NET MVC的[范围] [必需] [StringLength]等)

通常,类成员的ModelBinding验证可能就像这个例子一样:

public Class someclass
{
    [StringLength(50)]
    public string SomeValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

SomeValue最多限制为50个字符.

是否可以在运行时将常量(50)更改为其他内容,例如,在构造该类的每个实例期间,以便可以使用具有不同StringLength限制的不同实例?

如果是这样,那怎么做呢?

validation asp.net-mvc model-binding data-annotations

5
推荐指数
1
解决办法
4665
查看次数

如何以编程方式将 SMTP 服务器详细信息存储(保存)回 web.config

搜索 StackOverflow,我发现了有关如何从 Web.Config 检索 SMTP 设置的问题,但没有有关如何将 SMTP 更新回 web.config 文件的详细信息。

我从以下代码开始:

Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~");
MailSettingsSectionGroup settings =
  (MailSettingsSectionGroup)webConfig.GetSectionGroup("system.net/mailSettings");
SmtpSection smtp = settings.Smtp;
SmtpNetworkElement net = smtp.Network;
Run Code Online (Sandbox Code Playgroud)

但很快就被 Intellisense 发现了,这SmptSection.Network是一个 Get(又名“只读”)访问器。

那么我应该如何以编程方式将 SMTP 数据写回 web.config 呢?

asp.net web-config system.net.mail

4
推荐指数
1
解决办法
1559
查看次数