【问题标题】:DataMember's Name property is ignored with [FromUri] property in WebApi serviceWebApi 服务中的 [FromUri] 属性忽略了 DataMember 的 Name 属性
【发布时间】:2016-02-10 06:35:48
【问题描述】:

我们正在使用 Asp.Net WebApi 创建 RestService。但是由于某种原因,当尝试使用 [FromURI] 属性反序列化复杂属性时,DataMember 属性中的 Name 属性会被忽略。

例如,我们可能有: 方法:

public IHttpActionResult Get([FromUri]User user)

型号:

[DataContract]
public class User
{
    [DataMember(Name = "username")]
    public string Username{ get; set; }
    [DataMember(Name = "isActive", IsRequired = false)]
    public bool? Active { get; set; }
}

当反序列化user 时,我们得到了预期的用户名,但null 得到Active。另一方面,在序列化数据时,我们得到了isActiveusername,正如预期的那样。如果我们在查询字符串中发送带有active 的请求,它将按预期工作。

IModelBinder 显然有问题。由于某种原因,它不使用DataMemberName 属性。我检查了包含哪些格式器,并注册了 4 个默认格式器:

System.Net.Http.Formatting.JsonMediaTypeFormatter
System.Net.Http.Formatting.XmlMediaTypeFormatter
System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
System.Net.Http.Formatting.JQueryMvcFormUrlEncodedFormatter

我没有办法检查哪个是应要求使用的。我会假设它是FormUrlEncodedMediaTypeFormatter,但我不能确定。另外,我不确定它是否支持Name 属性。

我已经检查了一个解决方案,我能找到的最接近的主题是WebAPI DataMember Name not used when de/serializing via application/x-www-form-urlencoded,但它没有使用[FromUri],而是使用application/x-www-form-urlencoded 属性,它并没有真正解决。

任何想法、指示或建议将不胜感激。

【问题讨论】:

  • 你有没有发现,出了什么问题?我也面临同样的问题。
  • 不幸的是没有...我在 WebApi 中解决了这个错误并解决了它...
  • 这也被报告在这里forums.asp.net/t/…。如果您想使用 DataContract,那么我建议您从 HttpGet 更改为 HttpPost。否则,您将需要处理该错误。我的 2 美分。
  • 您能说明如何以 JSON 格式发送对象吗?
  • Heya @jaroslaw,这个问题已有 5 年历史,因此有点过时了,不确定它在当今时代是否仍然相关......如果你有一个特别相关的问题,我建议您在 SO 上打开一个单独的问题。

标签: c# rest asp.net-web-api2 datamember


【解决方案1】:

使用[FromQuery] 代替其他属性。

根据您的要求制作模型 http://localhost:8080/api/users?username=John&isActive=true

[Route("api/users")]
public class UsersController : Controller
{
    [HttpGet]
    public IHttpActionResult Get(User user)
    {
        //...
    }
}

看起来像

public class User
{
    [FromQuery(Name = "username")]
    public string Username{ get; set; }
    [FromQuery(Name = "isActive")]
    public bool? Active { get; set; }
}

无论如何,最佳实践是将名称保留在模型中,因为它在查询中为名称提供参数。 在这种情况下,您不必提供“名称”参数,只需在 queryClass 上保留[FromQuery],并且 .Net 会自动提供小写。

【讨论】:

    【解决方案2】:

    您必须检查您的“获取”请求。你的get请求一定是这样的;

    GET api/foo?username=fooname&active=false
    

    您不必使用 DataContract 和 DataMember 属性来实现这一点。这些属性只是为了另一件事,它不是使用的主要原因。

    在你的get方法获得有效命中后,你可以在你的方法中检查模型状态;

    if (ModelState.IsValid) {
    /// your code goes here    
    }
    

    【讨论】:

    • 您好 orhun.begendi,感谢您的帮助。不幸的是,这不是问题。请求通过,我“得到”它:) 问题在于 DataMember 描述符中定义的名称被忽略。尝试再次阅读整个描述:)
    • 您好,您看这篇文章了吗? aspnetwebstack.codeplex.com/workitem/270 我觉得这个主题非常有用,你可以通过这个配置强制在 web api 请求中使用 datamember 属性, GlobalConfiguration.Configuration.Services.RemoveAll( typeof(System.Web.Http.Validation.ModelValidatorProvider), v => v 是 InvalidModelValidatorProvider);我希望它有用。
    • 你好,你可以尝试构建自己的模型绑定。继承自 IModelBinder。可能会有帮助,你可以查看这篇文章strathweb.com/2013/04/…
    • OP 想要使用..&isActive=false,例如。这里没有什么要检查的,因为没有分配要检查..
    猜你喜欢
    • 2012-02-02
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2011-05-06
    • 2016-06-13
    相关资源
    最近更新 更多