为什么我必须指定[FromUri]才能使其正常工作?

时间:2013-06-04 21:33:29

标签: c# rest asp.net-web-api restsharp

我使用的是Asp.NET WebApi,让我感到困惑的一件事就是请求完成时的绑定。

我有这个ViewModel:

[DataContract(Name="Store")]
public class StoreDm
{
    [DataMember(IsRequired = true)]
    [MinLength(3)]
    public string Name { get; set; }

    [DataMember(IsRequired = true)]
    public double Latitude { get; set; }

    [DataMember(IsRequired = true)]
    public double Longitude { get; set; }
}

public HttpResponseMessage GetStoreNames(StoreDm vm)
{
    if (ModelState.IsValid)
    {

    }
}

RestClient c = new RestClient("http://localhost:3333/api/store");
RestRequest r = new RestRequest("/GetStoreNames", Method.GET);
r.AddParameter("Name", autoComplete);
r.AddParameter("Latitude", "4");
r.AddParameter("Longitude", "-7");
var d =  c.BuildUri(r);
c.ExecuteAsync(r, response2 =>
  {
      var content = response2.Content;
  });

我的StoreDm是空的。

我不会在很多层面上得到这个。首先,我在所有属性上设置了IsRequired,无论出于何种原因,ModelState认为“null”ViewModel有效。

其次我不明白为什么它是null。我必须添加[FromUri]才能让它绑定。如果这可能是Post并且具有相同的restClient代码但是有人正在使用fiddler body请求会发生什么。

如果我被迫放[FromUri],那么我认为小提琴体请求不起作用。

我怎么能拥有它,以便两个请求都能正常进行并正确绑定?

1 个答案:

答案 0 :(得分:10)

Web API参数绑定(从此处提取:Routing and Action Selection)执行此操作:

参数绑定。参数绑定是Web API为参数创建值的方式。以下是参数绑定的默认规则:

  • 简单类型取自URI。
  • 复杂类型来自请求正文。

因此,任何复杂类型(如类StoreDm都是)默认情况下应该是正文的一部分

如标准定义中所述超文本传输​​协议 4.3 Message Body

  

邮件中允许邮件正文的规则有所不同   请求和回复。

     

请求中存在消息正文   包含Content-Length或Transfer-Encoding标头字段   请求的邮件标题。邮件正文不得包含在邮件中   如果请求方法的规范请求(第5.1.1节)   不允许在请求中发送实体主体。

因此,虽然Web API提供了一些常用功能,但它会尝试通用。可能有或没有消息体的请求。所以,有了这个,动作选择和参数绑定很常见,没有推断特定的“当前”请求,也许显而易见的设置(我们认为,GET将始终具有所有参数({{1}的属性) }对象)在URI ...但引擎没有)

POST 会绑定StoreDm开箱即用,因为它的属性可以在正文中找到,是复杂对象的标准绑定。

GET 打破规则,属性(复杂类型)在URI中,因此我们只需通知框架:[FromUri]。在其他情况下,将找到Method,null(从message-body限定)将被传递