5

我正在使用 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 代码但有人正在使用提琴手正文请求会发生什么。

如果我被迫提出,[FromUri]那么我认为提琴手正文请求不会起作用。

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

4

1 回答 1

11

Web API 参数绑定(从此处摘录:路由和操作选择)执行此操作:

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

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

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

如标准定义超文本传输​​协议 4.3 消息体中所述

消息中何时允许消息正文的规则因请求和响应而异。

请求中消息体的存在通过在请求的消息头中包含 Content-Length 或 Transfer-Encoding 头字段来表示。如果请求方法的规范(第 5.1.1 节)不允许在请求中发送实体主体,则消息主体不得包含在请求中。

因此,虽然 Web API 提供了一些通用功能,但它试图通用。可能存在带有或不带有消息正文的请求。因此,有了这个,动作选择和参数绑定是常见的,没有推断“当前”请求特定的,可能是明显的设置(我们会认为,GET 将始终StoreDm在 URI 中包含所有参数(对象的属性).. . 但引擎没有)

POST将绑定StoreDm开箱即用,因为它的属性将在主体中找到,这是复杂对象的标准绑定。

GET打破了规则,属性(复杂类型)在 URI 中,所以我们只需要通知框架:[FromUri]。在其他情况下,将找到 Method,将传递 null(从消息体开始)

于 2013-06-05T03:51:40.690 回答