WebApi Controller返回类名,而不是Json。我该怎么调试呢?

时间:2017-11-13 16:02:52

标签: c# json asp.net-web-api serialization json.net

试图弄清楚我的序列化问题。

当我向我的LoadById方法发出post请求时,我无法序列化我的User类,获取MyNamespace.User响应而不是JSON序列化User负载。其他方法没有任何问题。

这是Web.Api ApiController ..

public class UserServiceController : System.Web.Http.ApiController
{ 
  [HttpPost]
  public User LoadById(String id)
  {
     using (UserManager mng = new UserManager())
     {         
        user = mng.LoadById(String id);

        //string json = JsonConvert.SerializeObject(user, new JsonSerializerSettings { TraceWriter = traceWriter });
        //Console.WriteLine(traceWriter);
     }
     return user;
  }
}

这是序列化的跟踪:

2017-11-13T15:55:58.237 Info Started serializing MyNamespace.User. Path ''.
2017-11-13T15:55:58.237 Info Finished serializing MyNamespace.User. Path ''.
2017-11-13T15:55:58.237 Verbose Serialized JSON: "MyNamespace.User"

Json为字符串:

 "MyNamespace.User"

用户类:

The user class is quite complex, i only have access to the metadata that 
doesn't show much.

如何获取更多信息以了解正在发生的事情?

2 个答案:

答案 0 :(得分:2)

看起来,NewtonSoft JsonConvert由于某种原因无法序列化你的Users类,而不是提供Json,只是返回类的名称,这与默认的.ToString()行为一致(即没有覆盖)引用类型。

作为替代方案,从WebApi返回数据时,提供干净,专用的ViewModel类,甚至是匿名类投影通常是个好主意。

这样,Domain对象(例如与AspNet标识User一起使用的UserManager对象)之间的关注点分离将封装在WebApi的客户端将耦合到的有效负载上 - 这你可以准确控制Api上暴露的字段。

[HttpPost]
public IHttpActionResult LoadById(String id)
{
   using (var mng = new UserManager())
   {         
      var domainUser = mng.LoadById(String id);

      var apiUser = new MyUserViewModel
      {
          // Map visible properties ...
          Name = domainUser.UserName,
          // Change the shape
          Address = domainUser.Address.Postal,
          ...
          // Hide fields that shouldn't be externally accessed
      };
      return Ok(apiUser);
   }
}

其他原因

如果从System.Web.MvcController而不是WebApi的System.Web.Http.ApiController继承您的Controller,通常会发生这种情况。例如:

public class Foo
{
    public string Name { get; set; }
}

public class MyController : System.Web.MvcController.Controller
{
    [HttpGet]
    public Foo Index()
    {
        return new Foo{Name = "Bob"};
    }
}
GET上的{p> /MyController会返回该类的默认ToString()(默认为该类型的名称)

`MyNameSpace.Foo`

你当然需要做的是:

public class MyController : **ApiController**
{
    [HttpGet]
    public Foo Index()
    {
        return new Foo{Name = "Bob"};
    }
}

将提供所需的

{
   Name: "Bob"
}

答案 1 :(得分:0)

抱歉延迟..

我终于有机会检查我的类User的所有继承类型,在我的分析过程中,我的眼睛停在TypeConverter属性上。

所以我记得用户dbc在评论中建议的内容,尝试使用NoTypeConverterJsonConverter,如以下答案所示。

Newtonsoft.JSON cannot convert model with TypeConverter attribute

感谢大家的帮助!