0

クエリ文字列変数をミラーリングするモデル クラスを作成して、それが Web API コントローラー アクションに入ったときにモデルに値が入力されるようにする方法を知っています。

ただし、モデル クラスのプロパティとしてクエリ文字列変数名にロックされないようにする方法はありますか?

例:

public class MyModel {
    public string o {get;set;}
}

public class MyController {
    public string Get(MyModel model) {

    }
}

次に、クエリ文字列が次のようになっている場合: GET http://domain.com/?o=12345

そのモデル プロパティに「o」の代わりに「Order」などの名前を付けて、「o=」の値を入力する方法はありますか?

4

2 に答える 2

1

必要に応じてデータをモデルにバインドするカスタム モデル バインダーを作成できます。それを使用するには、次のことを行う必要があります。

public string Get([ModelBinder(typeof(MyComplexTypeModelBinder))]MyModel model)
{
...
}

カスタム モデル バインダーを作成するには、IModelBinder または DefaultModelBinder から継承できます。

public class MyComplexTypeModelBinder : IModelBinder
{

  public Object BindModel(ControllerContext controllerContext,
                          ModelBindingContext bindingContext)
  {
     if (bindingContext == null)
         throw new ArgumentNullException("bindingContext");

     // Create the model instance (using the ctor you like best)
     var obj = new MyComplexType();

     // Set properties reading values from registered value providers
     obj.Order = FromPostedData<string>(bindingContext, "o");
     ...
     return obj;
}


private T FromPostedData<T>(ModelBindingContext context, String key)
{
   // Get the value from any of the input collections
   ValueProviderResult result;
   context.ValueProvider.TryGetValue(key, out result);

   // Set the state of the model property resulting from 
   context.ModelState.SetModelValue(key, result);
   // Return the value converted (if possible) to the target type
   return (T) result.ConvertTo(typeof(T));
}
于 2012-12-05T05:21:09.477 に答える
0

このシナリオのソリューションは customIValueProviderです。QueryStringこの ASP.NET MVC 拡張ポイントは、キーを Model.Property 名にブリッジできる正しい場所です。と比較してModelBinder、これは必要なものを正確にターゲットにします(ただし、他の値プロバイダー (FORM) でさえ誤ってそのキーが含まれている場合に、後で問題が発生することはありません...)

カスタムを導入するための良いチュートリアルがありますIValueProvider

また、モデルの「Order」プロパティの値を QueryString の「o」キーとして提供できる簡単な例があります。

工場

// Factory
public class MyValueProviderFactory : ValueProviderFactory
{
  public override IValueProvider GetValueProvider(ControllerContext ctx)
  {
    return new MyValueProvider(ctx);
  }
}

プロバイダー

// Provider
class MyValueProvider : IValueProvider
{
  protected HttpRequestBase Request { get; set; }    
  public MyValueProvider(ControllerContext ctx)
  {
    Request = ctx.HttpContext.Request;
  }

  // our custom logic to test QueryString keys, and expected prefixes
  public bool ContainsPrefix(string prefix)
  {
    var containsSpecial =
      "Order".Equals(prefix, StringComparison.OrdinalIgnoreCase)
      && Request.QueryString.AllKeys.Contains("o"
                    , StringComparer.InvariantCultureIgnoreCase);
    return containsSpecial;
  }

  // Handling "Order" key
  public ValueProviderResult GetValue(string key)
  {
    if (!ContainsPrefix(key))
    {
      return null;
    }
    var values = Request.QueryString.GetValues("o");

    if (values.Any())
    {
      return new ValueProviderResult(values, values.First()
                                    , CultureInfo.CurrentCulture);
    }
    return null;
  }
}

そして、global.asaxそれを注入する必要があります:

protected void Application_Start()
{
  ValueProviderFactories.Factories.Add(new MyValueProviderFactory());
  ...
于 2012-12-05T07:13:14.567 に答える