MVC将post参数传递给字典

时间:2017-01-30 13:47:17

标签: c# asp.net-mvc

我有MVC应用程序,在处理ResultObjekt对象后返回FormulaData。这是通过HTTP-Post

调用的其他API
[HttpPost]
[ActionName("GetResult")]
public ResultObjekt GetResult([FromBody]FormularData values)
{

}

问题:有没有办法将values中的所有属性都读入Dictionary<string, string>IEnumerable<KeyValuePair<string, string>>

e.g。

public class FormularData
{
    public string Item1 { get; set; }
    public string Item2 { get; set; }
}

应该会产生Dictionary<string,string>()IEnumerable<KeyValuePair<string, string>>

值为{ {"Item1","Value1"}, {"Item2","Value2"}}

我之前的解决方案适用于QuerystringHttpGet而不是HttpPost,自从我更改后,Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value)不再有效。

这是我当前的 - 不是那么漂亮的解决方案:

[HttpPost]
[ActionName("GetResult")]
public ResultObjekt GetResult([FromBody]FormularData values)
{
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
    if (!string.IsNullOrEmpty(values.Item1))
    {
        list.Add(new KeyValuePair<string, string>("Item1", values.Item1));
    }
    if (!string.IsNullOrEmpty(values.Item2))
    {
        list.Add(new KeyValuePair<string, string>("Item2", values.Item2));
    }
    IEnumerable<KeyValuePair<string, string>> result = list.AsEnumerable();
}

4 个答案:

答案 0 :(得分:9)

正如评论中许多人已经提到的那样,理想情况下应该使用可以保存表单中值的模型。根据我的观点,这也是最干净的方式,因为我觉得它更有条理。

如果您需要同时访问两者,请尽可能尝试重构/重构代码。在我看来,为什么在已经绑定到我们的模型时尝试访问原始表单数据,考虑到表单数据是模型数据的子集。

如果无法进行重构/重组,并且您需要同时访问这两者,那么有几种方法可以做到这一点。

  1. 选项1:使用FormCollection

    [HttpPost]
    public ResultObjekt GetResult(FormCollection formCol, FormularData model)
    {
        //Note that here both FormCollection and FormularData are used.
        //To get values from FormCollection use something like below:
        var item1 = formCol.Get("Item1");
    }
    
  2. 选项2:使用Request.Form

    [HttpPost]
    public ResultObjekt GetResult(FormularData model)
    {
        //To get values from Form use something like below:
        var formData = Request.Form;
        var item1 = formData.Get("Item1");
    }
    
  3. 希望这有帮助。

    更新:正如Lali所指出的,无论您使用FormCollection还是Request.Form,都可以将其转换为字典:{{1} }(未经测试),因为它们都是formData.AllKeys.ToDictionary(k => k, v => formData[v])

    类型

答案 1 :(得分:4)

虽然使用反射可能会影响性能,但您可以使用带反射的linq将模型转换为字典。

[HttpPost]
[ActionName("GetResult")]
public ResultObjekt GetResult([FromBody]FormularData values)
{
    var result = values.GetType()
                     .GetProperties()
                     .ToDictionary(pi => pi.Name, pi => (string)pi.GetValue(values));
}

通过缓存从GetProperties返回的属性信息可以提高性能。如果需要,上述linq也可以转换为扩展方法以供重用。

答案 2 :(得分:1)

我认为你无缘无故地让你的生活变得困难 如果您需要将您的类视为字典,只需实现一个隐式运算符,如下例所示

如果您只想迭代该对象,则可以实现IEnumerable

using System;
using System.Collections;
using System.Collections.Generic;

namespace ConsoleApplication5
{
    class Program
    {

        static void Main(string[] args)
        {
            FormularData data = new FormularData() { Item1 = "aa", Item2 = "bb" };
            //Dictionary<string, string> dictionary = data;
            foreach (var item in data)
                Console.WriteLine(item);

            Console.ReadLine();
        }
    }

    public class FormularData : IEnumerable<KeyValuePair<string,string>>
    {
        public string Item1 { get; set; }
        public string Item2 { get; set; }

        public static implicit operator Dictionary<string, string>(FormularData obj)
        {
            var list = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(obj.Item1))
                list.Add("Item1", obj.Item1);
            if (!string.IsNullOrEmpty(obj.Item2))
                list.Add("Item2", obj.Item2);
            return list;
        }

        public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
        {
            return ((Dictionary<string, string>)this).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
}

答案 3 :(得分:1)

扩展方法的强大功能可以在这里使用。

  1. 定义FormularData类的扩展名:

             public static class FormularDataExtensions
             {
                public static Dictionary<string, string> ConvertToDictionary(this FormularData formularData)
                {
                  var dictionary = new Dictionary<string, string>();
                  if (!string.IsNullOrEmpty(formularData.Item1))
                      dictionary.Add(nameof(formularData.Item1), formularData.Item1);
                  if (!string.IsNullOrEmpty(formularData.Item2))
                      dictionary.Add(nameof(formularData.Item2), formularData.Item2);
    
                 return dictionary;
                }
             }
    
  2. 将GetResult()中的ConvertToDictionary()调用为:

    [HttpPost]
    [ActionName("GetResult")]
    public ResultObjekt GetResult([FromBody]FormularData values)
    {
        var dictionary = values.ConvertToDictionary();
    }
    
相关问题