2

このSOの質問と同様の問題があります。ASP.NETMVC3ではデフォルトコンストラクターを使用せずにJSONをオブジェクトに逆シリアル化するが、MVC4では引用されたソリューションが機能しませんでした。

基本的に、次のようなクラスがある場合。

public class MyObject
{
    public string name = "foo";
    public int age = 33;
    public MyObject(string n)
    {
        name = n;
    }
}

そして私はそれをWebAPIメソッドから返そうとします。

    // GET api/values/5
    public **MyObject** Get(int id)
    {
        return new MyObject("Getted");
    }

配管はちょうど私の要求を床に投げます。500エラーでサイレントに失敗します。今、私はそれが苦労することを期待するかもしれませんが、私は例外を好みます。これがどこで生成されているかは明確ではありませんが、いくつかのポイント(FilterProvider、ValueProvider、ModelBinder)でインターセプトを試みましたが、配管のどの部分がそれをスローしているのかわかりません。

このカスタムモデルバインダーは、たとえば呼び出されることさえありません。

public class MyObjectModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        return new MyObject("bound model");
    }
}

完全を期すために、これはglobal.asax.csに登録されました。

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // other stuff...

        ModelBinders.Binders.Add(typeof(MyObject), new MyObjectModelBinder());
    }
}

不思議なことに、デフォルトのコンストラクターを追加すると、実際に呼び出されることはありませんが、WebAPIの配管はそれなしでは機能しないようです。

これ(奇妙なことに)機能します。

public class MyObject
{
    public string name = "foo";
    public int age = 33;
    public MyObject()
    {
        throw new Exception("I am never called! But I must exist");
    }
    public MyObject(string n)
    {
        name = n;
    }
}

サイレント障害に関してconnect.microsoft.comで問題を提起することを検討していましたが、おそらく回避策が必要です。

誰かが私が間違っていることに光を当てることができますか?

4

1 に答える 1

0

次のコードで問題を再現しようとしましたが、正常に動作します。レプロを付けてみては?

class Program
{
    private const string baseAddress = "http://localhost:8080/";

    static void Main(string[] args)
    {   
        HttpSelfHostConfiguration configuration = new HttpSelfHostConfiguration(baseAddress);
        configuration.Routes.MapHttpRoute("default", "api/{controller}");
        HttpSelfHostServer server = new HttpSelfHostServer(configuration);

        try
        {
            server.OpenAsync().Wait();

            RunClient();
        }
        finally
        {
            server.CloseAsync().Wait();
        }
    }

    static void RunClient()
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(baseAddress);
        HttpResponseMessage response = client.GetAsync("api/Test?id=1").Result;
        response.EnsureSuccessStatusCode();
        Console.WriteLine(response.Content.ReadAsStringAsync().Result);
    }
}

public class MyObject
{
    public string name = "foo";
    public int age = 33;
    public MyObject(string n)
    {
        name = n;
    }
}

public class TestController : ApiController
{
    // GET api/values/5
    public MyObject Get(int id)
    {
        return new MyObject("Getted");
    }
}

これのレプロを添付していただけますか?

ところで、問題の詳細を調べるために使用できるトレース パッケージがあります。

http://www.nuget.org/packages/Microsoft.AspNet.WebApi.Tracing/0.3.0-rc

これを使用する方法の詳細については、http://blogs.msdn.com/b/roncain/archive/2012/08/16/asp-net-web-api-tracing-preview.aspxを参照してください。

ありがとう!

最高のホンメイ

于 2013-01-17T07:29:06.353 に答える