可选参数:“空”与“未提供”

时间:2014-02-25 03:23:20

标签: .net asp.net-mvc-4 asp.net-web-api default-parameters

有没有办法区分空值和根本没有提到的空值?

例如,我希望客户端能够更新配置文件,并且只影响请求中指定的值...即使是空/空的。

所以给出一个名字=“Sherlok”和Birthdate =“1月6日”的个人资料:

POST api/profiles/update?name=Sherlock >> only modifies name

POST api/profiles/update?birthdate=&name=Sherlock >> modifies name AND clears birthdate

有没有办法区分这两种情况下的birthdate参数,还是需要求助于魔术值?

2 个答案:

答案 0 :(得分:1)

实际上有很多方法可以做到这一点。

  1. 正如@Badri建议的那样,您可以直接在行动中使用Request对象。这是一种非常简单和简单的方法,但将控制器逻辑与格式化/绑定逻辑混合在一起。如果您想要更好地分离关注点,请尝试以下方法之一。
  2. 您可以选择多种parameter binding mechanisms。在我看来,自定义模型绑定器在这种情况下可以很好地工作。您可以访问模型绑定器中的Request对象,并使用类似于@ Badri的代码来设置您期望的值(String.Emptynull),然后再将它们传递给您的操作。
  3. birthdate字段的值提供者可能是更好的选择。您传递的字符串最终可以转换为DateTime对象。如果您指定该参数应使用自定义值提供程序(例如IntuitiveDateTimeValueProvider),您实际上可以将操作中参数的类型更改为DateTimeNullable<DateTime>({{ 1}})让值提供者适当地填充值。您还可以对更简单的字符串使用类似的策略,以区分空和空(例如,DateTime?)。
  4. 创建其他路线/操作。如果有很多参数,这不是一个好的选择,因为有太多可能的组合,但如果只有少数,这是一个非常简单的解决方案。一种方法是简单地为每个组合创建方法重载。如果命中只有ExistenceTestingStringValueProvider的重载,则表示未指定name,但如果同时遇到包含这两个参数的重载,则表示已指定birthdate,即使其已{值为birthdate,为您提供了区分指定但空的参数值和未指定参数值的方法。

答案 1 :(得分:0)

如果使用ASP.NET Web API绑定,则无法实现。比如说,你有一个DTO类,并使用它来进行绑定。

public class MyDto
{
    public string Name { get; set; }
    public string BirthDate { get; set; }
}

public void Update([FromUri]MyDto dto) { }

如果省略BirthDate或将其放在具有空值的查询字符串中,它基本相同,BirthDate属性在两种情况下都将为空。但是,您可以像这样自己阅读查询字符串。

string qs = Request.RequestUri.Query.Substring(1); // leave out ?
var pairs = System.Web.HttpUtility.ParseQueryString(qs);

在这种情况下,如果您从查询字符串(?name = Sherlock)中省略字段,pairs["BirthDate"]将为null。

如果你在查询字符串中有空值(?birthdate =&amp; name = Sherlock),那么pairs["BirthDate"]将为空字符串(“”)。

相关问题