Skip to main content
 首页 » 编程设计

c#之对于没有默认无参数构造函数的数据类型,Web API 静默失败

2024年01月01日53yyy_WW

我有一个与这个 SO 问题类似的问题:Deserializing JSON to object with no default constructor in ASP.NET MVC 3但在 MVC4 中,引用的解决方案对我不起作用。

本质上,如果我有一个类似的类;

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

然后我尝试从 Web API 方法返回它;

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

管道只是把我的要求扔到地板上。它静静地失败并返回 500 错误。现在我可能希望它会挣扎,但我更希望有一个异常(exception)。目前尚不清楚这是在哪里生成的,但我已经尝试在多个点(FilterProvider、ValueProvider、ModelBinder)进行拦截,但我看不到管道的哪一部分将其丢弃。

例如,这个自定义模型绑定(bind)器不会甚至被调用;

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()); 
    } 
} 

奇怪的是,如果我添加了一个默认构造函数,它实际上从未被调用过,但是 Web API 管道似乎没有它就无法工作。

这确实有效(奇怪地);

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 上提出一个关于静默失败的问题,但大概必须有一个解决方法。

任何人都可以阐明我做错了什么吗?

请您参考如下方法:

我正在尝试使用以下代码重现您的问题,但效果很好。你能尝试附上一个复制品吗?

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 了解更多关于如何使用它的信息

谢谢!

最好的, 红梅