6

MVC のコントローラーにデータを送信する次のスクリプトがあります。

$.ajax({
    url: '/products/create',
    type: 'post',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify({
        'name':'widget',
        'foo':'bar'
    })
});

私のコントローラーは次のようになります。

[HttpPost]
public ActionResult Create(Product product)
{
    return Json(new {success = true});
}

public class Product 
{ 
    public string name { get; set; }
}

コントローラーアクションなしで「foo」変数を取得する方法はありますか

  • モデルの修正
  • アクションの署名を変更する

通常のフォーム送信であれば、Request.Form["foo"] にアクセスできますが、application/json 経由で送信されたため、この値は null です。

アクション フィルターからこの値にアクセスできるようにしたいので、署名/モデルを変更したくありません。

4

3 に答える 3

4

今日もほぼ同じことをしたかったのですが、この質問には答えがありませんでした。私もマークと同様の解決策で解決しました。

これは、asp.net MVC 4で私にとって非常にうまく機能します。古いものであっても、この質問を読んでいる他の人を助けることができるかもしれません。

        [HttpPost]
        public ActionResult Create()
        {
            string jsonPostData;
            using (var stream = Request.InputStream)
            {
                stream.Position = 0;
                using (var reader = new System.IO.StreamReader(stream))
                {
                    jsonPostData = reader.ReadToEnd();
                }
            }
            var foo = Newtonsoft.Json.JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonPostData)["foo"];

            return Json(new { success = true });
        }

重要な部分は、ストリームの位置をリセットすることでした。これは、MVC 内部コードなどによって既に読み取られているためです。

于 2013-09-27T12:27:34.500 に答える
1

アクション フィルターからこの値にアクセスできるようにしたいので、署名/モデルを変更したくありません。

メソッドのシグネチャを変更しないと、Action フィルターから値にアクセスするのは難しいでしょう。その理由は、この投稿からよく理解できます。

このコードは、承認フィルターまたはモデル バインディングの前に実行されるコードのどこかで機能します。

public class CustomFilter : FilterAttribute, IAuthorizationFilter
  {
    public void OnAuthorization(AuthorizationContext filterContext)
    {
      var request = filterContext.RequestContext.HttpContext.Request;

      var body = request.InputStream;
      var encoding = request.ContentEncoding;
      var reader = new StreamReader(body, encoding);
      var json = reader.ReadToEnd();

      var ser = new JavaScriptSerializer();

      // you can read the json data from here
      var jsonDictionary = ser.Deserialize<Dictionary<string, string>>(json); 

      // i'm resetting the position back to 0, else the value of product in the action  
      // method will  be null.
      request.InputStream.Position = 0; 
    }
  }
于 2012-06-01T04:14:59.227 に答える
-2

この「foo」がバインドされていない場合でも、次のアクション フィルターで使用できます。

filterContext.HttpContext.Current.Request.Params

パラメータが表示されている場合は、これらのコレクションを調べてください。

そうです、アクションフィルターを作成するだけで、署名を変更しないでください。

念のため、フィルターをデバッグして、値がどこにあるかを確認してください。

最後に、json の値プロバイダーを global.asax に登録する必要があります。

protected void Application_Start() 
{
  RegisterRoutes(RouteTable.Routes);
  ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
}

パラメータが間違っているだけでなく、次のようにする必要があります。

$.ajax({
    url: '/products/create',
    type: 'post',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify({
        name:'widget',
        foo:'bar'
    })
});

引用なし。

編集(より正確に):

フィルターにはこれらのメソッドが含まれます

public void OnActionExecuting(ActionExecutingContext filterContext)
{

}
public void OnActionExecuted(ActionExecutedContext filterContext)
{

}
于 2012-05-31T16:00:31.660 に答える