5

私はMVCを初めて使用するWCF開発者です。私のWCFAPIをApiControllersとしてMVCアプリケーションに統合しようとしています(それが価値のある取り組みであるかどうかはまだ大きな問題です)。

jQueryプラグインからこのリクエストがあります:

 POST http://localhost:18698/Api/Public/DoAction HTTP/1.1 
 ....
 Content-Type: application/json; charset=UTF-8 Accept:
 application/json, text/javascript, */*; q=0.01

 {"myParam":"test"}

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

public class PublicController : ApiController
{
    [HttpPost]
    public string DoAction(string myParam)
    {
        return "Test";
    }
} 

そして、ルーティングピースは次のようになります。

    config.Routes.MapHttpRoute(
        name: "PublicApi",
        routeTemplate: "api/{controller}/{action}"
    );

このエラーが発生します:

{
    "Message": "No HTTP resource was found that matches the request URI 'http://localhost:18698/Api/Public/DoAction'.",
    "MessageDetail": "No action was found on the controller 'Public' that matches the request."
}

JSONパラメーターを受け入れないメソッドは正常に機能しますが、JSONパラメーターを受け入れるメソッドは機能しません。複雑なJSONをメソッドに渡すことができなければなりません。WCFでは、JSONからオブジェクトへの変換はWCFによって処理されていました。

なぜこのエラーが発生するのか知っていますか?WCFで行ったのと同じようにMVCでもシームレスに複雑なJSONを送受信できますか?

4

2 に答える 2

6

送信したJSONを調べると、{"myParam":"test"}Darinが指摘していることがわかります。つまり、プロパティを含めるためのモデルが必要です。たとえば、次のツールで{"myParam":"test"}を実行します。http://json2csharp.com/およびあなたが得る:

public class RootObject
{
    public string myParam { get; set; }
}

単純なタイプの文字列を使用した以前のメソッドシグネチャは、デフォルトでWebApiによってUrlParameterとして扱われていました(と同じpublic string DoAction([FromUri]string myFoo))。このURLが機能するので、コードを残すことでこれを証明できます。

http://localhost:50381/Api/Public/DoAction?myParam=something

JSON.NETを使用するボディシリアライザーは、それ自体で単純な.NETタイプを解析できないため、それをホストするための単純なモデルを作成する必要があります。次に、frombodyバインダーを使用しますpublic string DoAction([FromBody]RootObject myFoo)

于 2012-11-20T13:10:35.527 に答える
2

いつものように、ビューモデルを定義することから始めます。

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

次に、コントローラーアクションにこのビューモデルをパラメーターとして使用させます。

public class PublicController : ApiController
{
    [HttpPost]
    public string DoAction(MyModel model)
    {
        return "Test_" + model.MyParam;
    }
}

最後に、コントローラーアクションを呼び出します。

<script type="text/javascript">
    $.ajax({
        url: '@Url.HttpRouteUrl("PublicApi", new { controller = "public", action = "doaction" })',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({ "myParam": "test" }),
        sucecss: function (result) {
            console.log(result);
        }
    });
</script>

備考:ルートにアクション名を含めることにより、RESTful規則に違反しています。RESTfulルートでは、アクションではなくリソースを操作します。したがって、コントローラーは操作しているリソースを表し、HTTP動詞は呼び出しているアクションを表します。したがって、Get、Post、Patch、Deleteなどのアクション名を使用し、クライアントが使用するHTTP動詞に基づいて、ルーティングエンジンが対応するアクションに自動的にディスパッチします。

于 2012-11-20T12:56:45.003 に答える