2017-01-30 3 views
6

FormulaDataオブジェクトを処理した後にResultObjektを返すMVCアプリケーションがあります。それは辞書にポストパラメータを渡すMVC

[HttpPost] 
[ActionName("GetResult")] 
public ResultObjekt GetResult([FromBody]FormularData values) 
{ 

} 

質問HTTPポスト経由で呼ばれる残りのAPIです:Dictionary<string, string>またはIEnumerable<KeyValuePair<string, string>>valuesからすべてのプロパティを読み取るする方法はありますか?

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

は、私の以前のソリューションではなくHttpPostQuerystringHttpGetで働いていたと私は変更するので、Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value)はもう動作しない値{ {"Item1","Value1"}, {"Item2","Value2"}}

Dictionary<string,string>()またはIEnumerable<KeyValuePair<string, string>>

になるはずです。ここで


私の現在のさ - いないので、かなり解決策:

[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(); 
} 
+2

あなただけの 'values'を定義することができませんでしたparamをあなたのFormularDataクラスにバインドする必要がないかぎり、 'IDictionary 'としてください。 – Corporalis

+3

@Toshi、 'ResultObjekt GetResult([FromBody] Dictionary values)'でも動かなければならない – Nkosi

+0

@Corporalisは両方を使うことはできませんか? FormularDataクラスとDictionary? – Toshi

答えて

8

は、すでに述べたように、理想的に1は、フォームからの値を保持できるモデルを使用する必要がありますコメントで多くの人に言及しました。これは私がそれがより構造化されているのを見て、私の意見としては最もきれいな方法です。

同時にアクセスする必要がある場合は、可能であれば、まずコードをリファクタリング/再構成してみてください。私の意見では、フォームデータがモデルデータのサブセットであることを考慮すると、未加工フォームデータに既にアクセスしているのはなぜですか。

リファクタリング/リストラが不可能で、両方にアクセスする必要がある場合は、その方法をいくつか使用してください。

  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"); 
    } 
    

は、この情報がお役に立てば幸いです。

更新:としてもあなたがFormCollection又はRequest.Formを使用するかどうか、Laliによって指摘、次のように辞書にそれを変換することができ:リフレクションを使用している間、両方のタイプのNameValueCollection

4

ているように、formData.AllKeys.ToDictionary(k => k, v => formData[v])(未テスト)を有していてもよいですパフォーマンスヒットは、リバースで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は、必要に応じて再利用のための拡張メソッドに変換することもできます。

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(); 
     } 
    } 
} 
1

電源を実装することができますExtensionメソッドをここで使用することができます。

  1. はFormularDataクラスの拡張機能を定義しますのgetResultで

      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. コールConvertToDictionary()()のように:

    [HttpPost] 
    [ActionName("GetResult")] 
    public ResultObjekt GetResult([FromBody]FormularData values) 
    { 
        var dictionary = values.ConvertToDictionary(); 
    } 
    
関連する問題