【问题标题】:Validating a large dictionary of set strings with user input使用用户输入验证大型集合字符串字典
【发布时间】:2015-09-21 19:05:51
【问题描述】:

我有一个配置文件表单,其中包含很多用户选择,当传递将这些值映射到对象属性的验证时,我有点难过验证用户输入内容的好方法。

例如我有一本字典

public static Dictionary<string, string> objProfileSelections = new Dictionary<string, string>();

public static string MySelections(string key)
{
    objProfileSelections.Add("1", "No Answer");
    objProfileSelections.Add("3", "Less Than $25,000");
    objProfileSelections.Add("5", "$35,000 to $50,000");
    objProfileSelections.Add("7", "$50,000 to $75,000");
    objProfileSelections.Add("9", "$75,000 to $100,000");
    objProfileSelections.Add("11", "$100,000 to $150,000");
    objProfileSelections.Add("13", "$150,000+");
    objProfileSelections.Add("2", "No Answer");
    objProfileSelections.Add("4", "Less Than $25,000");
    objProfileSelections.Add("6", "$35,000 to $50,000");
    objProfileSelections.Add("8", "$50,000 to $75,000");
    objProfileSelections.Add("10", "$75,000 to $100,000");
    objProfileSelections.Add("12", "$100,000 to $150,000");
    objProfileSelections.Add("14", "$150,000+");
    string item;
    objProfileSelections.TryGetValue(key, out item);
    return item;
}

我想从用户那里传递一个键字符串列表,然后传递这些项目来填充一个对象。问题是我不知道如何对其进行编码,因此它知道要转到哪个属性,我查看了反射,但我找不到任何具有映射到属性名称的值字典的示例。

为了更清楚一点,当用户进行选择时,它作为参数传递到字典中,然后字典输出项目。来自键 1 的值是 No Answer。如果用户选中了所有复选框,则值为 - (1,3,5,7,9,11,13)。当匹配属性存在匹配键时,我需要提取这些值。例如,如果用户单击 1,5 但未选中其余部分,我如何知道用户做出了哪些选择?如何让程序知道根据结果填充哪个属性?

*编辑 我希望它映射到的一些属性

public string MyAnnualIncome{ get; set; }
public List<string> InterestAnnualIncome{ get; set; }

所以第一个属性将采用一个值,而第二个属性将采用多个值。

当一个键与字典中的一个值匹配时,我需要奇数值进入 MyAnnualIncome,偶数值进入 InterestAnnualIncome。


  • 所以没有人会混淆奇数和偶数键是出于某种目的设置的,奇数属于某一组属性,偶数属于基于 html 选择的另一个属性(即使是我的选择,奇数是我的选择)感兴趣)

*更新 有没有办法我可以使用像 1,3,5 这样的键并使用 except 扩展方法将其传递到列表中。然后把结果取出来,用一个方法把枚举数据类型的值转换成字符串?

【问题讨论】:

  • 显然,有人理解了这个问题,因为您获得了支持。但我真的不明白你想做什么。
  • 让我尝试更清楚一点,上面的字典设置为静态字典以验证用户选择。 html 表单有一个带有这些值(1、2、3、4、5、6 等)的复选框列表。所以当用户点击no answer,Less Than $25,000, $35,000 to $50,000时,他选择了值1,3,5。如果用户决定篡改表单和输入 (Z238),它将返回 null。但是,如果用户正确地做所有事情,我觉得正确的做法是将其映射到名为 List 年收入的用户属性。
  • 这有帮助,谢谢。您可以扩展帖子中的代码以包含您想要映射到的这些属性吗?没有关于这些是什么、在哪里定义、如何返回它们的信息。如果有助于说明您希望完成的工作,您甚至可以发布一些无效代码。
  • 您想将键转换为 c# 属性名称吗?一旦你得到了属性,你想设置它吗?属性的类型是什么(bool、string、enum、...)?要分配给属性的值是什么?我们可以假设您从复选框值接收或构建键列表吗?
  • 只是字符串,个人资料就像约会网站一样。头发颜色、收入和职业等属性。对于其他数据类型,我单独处理。我拥有大量字符串,我只是对如何使用键提取的值填充用户配置文件对象感到困惑。

标签: c# asp.net dictionary


【解决方案1】:

希望我能理解您的问题。 我会添加一个小助手类(这是一个不使用反射,而是使用委托的解决方案):

public class PropertyModifier
{
   private string text;
   private Func<string> modifier;

   public PropertyModifier(Func<string> modifier)
   {
       this.modifier = modifier;
   }

   public PropertyModifier With(string text)
   {
       PropertyModifier newModifier = new PropertyModifier(modifier);
       newModifier.text = text;
       return newModifier;
   }

   public void Modify()
   {
       modifier(Text);
   }
}

然后我会重写你的代码并将字典映射到这个类而不是字符串:

public static Dictionary<string, PropertyModifier> objProfileSelections = new Dictionary<string, PropertyModifier>();

public static MyUserProfile Profile; //Assuming this is the object you want to modify

public static string MySelections(string key)
{
    PropertyModifier myIncome = new PropertyModifier(text => Profile.MyAnnualIncome = text);
    PropertyModifier interestIncome = new PropertyModifier(text => Profile.InterestAnnualIncome.Add(text)); 

    objProfileSelections.Add("1", myIncome.With("No Answer"));
    objProfileSelections.Add("3", myIncome.With("Less Than $25,000"));
    ...
    objProfileSelections.Add("2", interestIncome.With("No Answer"));
    objProfileSelections.Add("4", interestIncome.With("Less Than $25,000"));
    ...
}

然后,在处理用户的选择时,从字典中获取映射的 PropertyModifier 并调用其Modify 方法。

【讨论】:

    【解决方案2】:

    我尝试在此代码中说明如何修改可能构成配置文件的不同类的属性。修改仅通过反射完成,即只提供类名、每个类中不同的属性名以及要分配给属性的字符串值。

    不确定它是否符合您的期望:(

    Profile profile = new Profile() ;
    profile.SetPropertyValue("hair","color","brown") ;        
    
    internal class Profile()
    {
      private Hair hair_ = new Hair();   
      private Job  job_  = new Job ();
    
      internal Hair hair { get { return hair_ ; } } 
      internal Job  job  { get { return job_  ; } } 
    
      private void SetPropertyValue(string profileItemName, string ItemPropertyName, string value)
      { // it is assumed that the different items (hair or job) of the Profile are accessible 
        // with a a property
    
        // first find the Item object, i.e. hair or job                  
        object itemObj = this.GetType().GetProperty(profileItemName).GetValue(this,null);
        // assign to Item property the input value, e.g. hair.color=Brown
        itemObj.GetType().GetProperty(ItemPropertyName).SetValue(itemObj, value, null);
       }
     }
    
    internal class Hair()
    {
      private string color_ ;   
      private string style_ ;
    
      internal string   color { get { return color_  ; } set {color_ = value ; } } 
      internal string   style { get { return style_  ; } set {style_ = value ; } } 
     }
    

    【讨论】:

    • 我的期望?伙计,你抽出时间来帮助我,这真是太棒了。在我检查之前先去吃点健脑食品,非常感谢!
    猜你喜欢
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多