我有MVC应用程序,在处理ResultObjekt
对象后返回FormulaData
。这是通过HTTP-Post
[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"}}
我之前的解决方案适用于Querystring
和HttpGet
而不是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();
}
答案 0 :(得分:9)
正如评论中许多人已经提到的那样,理想情况下应该使用可以保存表单中值的模型。根据我的观点,这也是最干净的方式,因为我觉得它更有条理。
如果您需要同时访问两者,请尽可能尝试重构/重构代码。在我看来,为什么在已经绑定到我们的模型时尝试访问原始表单数据,考虑到表单数据是模型数据的子集。
如果无法进行重构/重组,并且您需要同时访问这两者,那么有几种方法可以做到这一点。
选项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:使用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");
}
希望这有帮助。
更新:正如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)
扩展方法的强大功能可以在这里使用。
定义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;
}
}
将GetResult()中的ConvertToDictionary()调用为:
[HttpPost]
[ActionName("GetResult")]
public ResultObjekt GetResult([FromBody]FormularData values)
{
var dictionary = values.ConvertToDictionary();
}