3

私のコードには基本クラスFooがあり、すべてのオブジェクトはFooオブジェクトから継承しています。だから私はこのようなクラスを持っているとしましょう

public class Bar : Foo {
    public string Heading { get;set; }
}

ApiControllers putメソッドを動的で使用しようとしましたが、このエラーが発生しますhttp://paste2.org/p/1914054

これは私がApiControllerで使用しているコードです

public void Put(string id, dynamic model) {
    //do stuff
}

通常のコントローラーを使用すると、動的にデータを投稿できます。追加してAPIコントローラーを動的に動作させることは可能ですか、それとも独自のモデルバインダーを作成する必要がありますか?

MVC 3でも入力パラメーターを動的にすることはできないと考える人もいるようですが、それは真実ではないため、私はこの質問をします。MVC 3のこのコントローラーは、入力パラメーターとしてダイナミックでうまく機能します。

4

3 に答える 3

3

うーん、ASP.NET Web API メソッドを使用してこれを行うことができました。

    public string Post(dynamic value)
    {
        string s = "";
        foreach (dynamic item in value)
        {
            s = s + item.content + " ";
        }
        return s;
    }

JSON 配列を使用する:

POST http://localhost:6946/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:6946
Content-Length: 327
Content-Type: application/json
[{"content":"Hello","editing":false},{"content":"sfsdf","editing":false},{"content":"sadsdfdsf","editing":false},{"content":"dfsdf","editing":false},{"content":"dsfsd","editing":false},{"content":"sdfsdf","editing":false},{"content":"dsf","editing":false},{"content":"dfg","editing":false},{"content":"fsdfsd","editing":false}]

そしてそれは働いた....

于 2012-04-19T23:35:19.760 に答える
1

MVC 3でも入力パラメータを動的にすることはできないと考える人もいるようです

そう思います。提供された例を見てみましょう。

[HttpPost]
[ValidateInput(false)]
public virtual ActionResult Update(dynamic editorModel) {

    if (!TryUpdateModel(_model, "CurrentModel")) {
        var parentId = _model.Parent != null ? (string)_model.Parent.Id : null;
        var viewModel = new EditViewModel
        {
            RootModel = _session.Query<IPageModel>()
                .Where(model => model.Parent == null)
                .SingleOrDefault(),
            CurrentModel = _model,
            ParentModel = parentId != null ? _session.Load<IPageModel>(parentId) : null,
        };
        return View("edit", viewModel);
    }

    UpdateModel(_model);

    _model.Metadata.Changed = DateTime.Now;
    _model.Metadata.Published = _model.Metadata.IsPublished ? DateTime.Now : default(DateTime?);
    _model.Metadata.ChangedBy = HttpContext.User.Identity.Name;

    _repository.SaveChanges();
    _repository.Refresh(_model);

    var page = _model as IPageModel;

    if (page.Parent != null) {
        _model = _repository.SingleOrDefault<IPageModel>(m => m.Id == page.Parent.Id);
    }

    return RedirectToAction("index", new { model = _model });
}

editorModelこのコントローラーアクション内でこの動的変数がどのように/どこで使用されているか教えていただけますか?

そして、このコントローラー アクションをさらに単純化するために、引数として渡された動的変数を決して使用しないため、これは機能します。モデルバインディングに関してこのアクションが大まかに何をしているのかをよりよく説明するために単純化しました(もちろん、問題を説明するためにここでは関心のないすべてのインフラストラクチャノイズを捨てています):

[HttpPost]
public ActionResult Update(dynamic blablabla)
{
    dynamic model = new MyViewModel();
    UpdateModel(model);
    // at this stage the model will be correctly bound

    return View(model);
}

このアクション内では、コンストラクターに渡され、タイプが であるインスタンス変数でメソッドTryUpdateModelUpdateModelメソッドが呼び出されます。ASP.NET MVC は、(もちろんカスタム モデル バインダーがなければ) 動的アクション引数の型を認識できない可能性があります。このコードを実行し、アクション内にブレークポイントを置き、変数の型を観察してください。単純に になります。奇跡はありません。_modelIPageModelUpdateeditorModelSystem.Object

したがって、これが ASP.NET Web API で同じように機能することは、私にとってはまったく正常なことです。

于 2012-02-25T09:29:47.690 に答える
0

http://www.binaryintellect.net/articles/589f6915-f4c0-4bf9-9f94-4d00bd445c16.aspx

このソリューションは完全に正常に機能します。

すべての入力コントロールが動的な HTML フォームがありました。フォーム データを MVC コントローラーに接続し、次に Web Api 2 コントローラーに接続するのに苦労しました。

サーバー側の Web API メソッドは次のようにする必要があります

public string Post(FormDataCollection form){
... }

FormDataCollection は System.Net.Http.Formatting 名前空間にあります。

Web ページ (jquery) から直接データをポージングしている場合、上記のリンク ソリューションは正常に機能します。

データ Web ページを MVC ページ (C# コード) にポストし、さらに Web API メソッドにポストする場合、コードは次のようになります。

[HttpPost]
    public async Task<string> MasterDraw(FormCollection body)
    {
        HttpClient client = new HttpClient();
        KeyValuePair<string, string>[] list = null;
        string url = ConfigurationManager.AppSettings["BaseServiceUrl"] + "/api/MasterOperation/addrecord";

        if (body != null && body.HasKeys())
        {
            list = new KeyValuePair<string, string>[body.AllKeys.Count()];
            for (int ctr = 0; ctr < body.Keys.Count; ctr++ )
            {
                list[ctr] = new KeyValuePair<string, string>(body.Keys[ctr], body.GetValue(body.Keys[ctr]).AttemptedValue);
            }
        }

        var content = new FormUrlEncodedContent(list);

        HttpResponseMessage response = await client.PostAsync(url, content);

        // Check that response was successful or throw exception
        response.EnsureSuccessStatusCode();

        // Read response asynchronously as JToken and write out top facts for each country
        string contentRes = response.Content.ReadAsStringAsync().Result;

        return contentRes;
    }

ブラウザ側のコード:

$('#btn-save').on('click', function (event) {
            var postUrl = "@Url.Action("masterdraw","masterrender")";

            var result = $.ajax({
                type: "POST",
                data: $('#form').serialize(),
                url: postUrl                    
            });

            // insert your jquery .done and .error methods

        });
于 2015-12-04T13:11:48.503 に答える