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

时间:2021-10-29 08:04:14

Is there a way to differentiate between an empty value and one that is not mentioned at all?

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

For example, I'd like to the client to be able to update a Profile and only affect values which are specified in the request... EVEN empty/null ones.

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

so given a profile with name="Sherlok" and Birthdate="January 6":

所以给出一个名称=“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

Is there a way to differentiate between the birthdate parameter in those two situations, or do I need to resort to magic values?

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

2 个解决方案

#1


0  

If you use ASP.NET Web API binding, it is not possible. Say, you have a DTO class and use it for binding like this.

如果使用ASP.NET Web API绑定,则无法实现。比如说,你有一个DTO类,并将它用于这样的绑定。

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

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

When you leave out BirthDate or have it in the query string with an empty value, it is basically the same and BirthDate property will be null in both cases. However, you can read the query string yourself like this.

当您遗漏BirthDate或将其放在具有空值的查询字符串中时,它基本相同,并且在两种情况下BirthDate属性都将为null。但是,您可以像这样自己读取查询字符串。

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

In this case, pairs["BirthDate"] will be null, if you leave out the field from the query string (?name=Sherlock).

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

If you have it in the query string with an empty value (?birthdate=&name=Sherlock), then pairs["BirthDate"] will be empty string ("").

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

#2


0  

There are actually quite a few ways to do this.

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

  1. As @Badri suggested, you can use the Request object directly in your actions. This is a very straightforward and simple approach but mixes controller logic with formatting/binding logic. If you want to create a better separation of concerns, try one of the following.
  2. 正如@Badri建议的那样,您可以直接在您的操作中使用Request对象。这是一种非常简单和简单的方法,但将控制器逻辑与格式化/绑定逻辑混合在一起。如果要创建更好的关注点分离,请尝试以下方法之一。

  3. There are a number of parameter binding mechanisms you can choose from. Looks to me like a custom model binder could work well in this case. You can access the Request object in the model binder and use something similar to @Badri's code to set up the values you expect (String.Empty or null) before they get passed to your action.
  4. 您可以选择许多参数绑定机制。在我看来,自定义模型绑定器在这种情况下可以很好地工作。您可以访问模型绑定器中的Request对象,并使用类似于@ Badri的代码来设置您期望的值(String.Empty或null),然后再将它们传递给您的操作。

  5. A value provider for the birthdate field might be a better option. You're passing a string that can ultimately be converted to a DateTime object. If you specify that that parameter should use a custom value provider (such as an IntuitiveDateTimeValueProvider), you can actually change the type of the parameter in your action to DateTime or Nullable<DateTime> (DateTime?) and let the value provider fill the value appropriately. You can also use a similar strategy for simpler strings for which you want to differentiate between empty and null (e.g., ExistenceTestingStringValueProvider).
  6. birthdate字段的值提供者可能是更好的选择。您传递的字符串最终可以转换为DateTime对象。如果指定该参数应使用自定义值提供程序(例如IntuitiveDateTimeValueProvider),则实际上可以将操作中的参数类型更改为DateTime或Nullable (DateTime?)并让值提供程序填充值适当。您还可以对更简单的字符串使用类似的策略,以便区分空和空(例如,ExistenceTestingStringValueProvider)。

  7. Create additional routes/actions. This isn't a good option if there are a lot of parameters because there are just too many possible combinations, but if there are just a few, this is a very simple solution. One way to do this is to simply create method overloads for each combination. If an overload that only has name is hit, it means birthdate wasn't specified, but if an overload with both parameters was hit, it means that birthdate was specified, even if its value is null, giving you a way to distinguish between specified but empty parameter values and unspecified parameter values.
  8. 创建其他路线/操作。如果有很多参数,这不是一个好的选择,因为有太多可能的组合,但如果只有少数,这是一个非常简单的解决方案。一种方法是简单地为每个组合创建方法重载。如果命中了只有名称的重载,则表示未指定birthdate,但如果同时遇到包含这两个参数的重载,则表示已指定birthdate,即使其值为null,也为您提供了区分指定的方法但是空参数值和未指定的参数值。

#1


0  

If you use ASP.NET Web API binding, it is not possible. Say, you have a DTO class and use it for binding like this.

如果使用ASP.NET Web API绑定,则无法实现。比如说,你有一个DTO类,并将它用于这样的绑定。

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

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

When you leave out BirthDate or have it in the query string with an empty value, it is basically the same and BirthDate property will be null in both cases. However, you can read the query string yourself like this.

当您遗漏BirthDate或将其放在具有空值的查询字符串中时,它基本相同,并且在两种情况下BirthDate属性都将为null。但是,您可以像这样自己读取查询字符串。

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

In this case, pairs["BirthDate"] will be null, if you leave out the field from the query string (?name=Sherlock).

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

If you have it in the query string with an empty value (?birthdate=&name=Sherlock), then pairs["BirthDate"] will be empty string ("").

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

#2


0  

There are actually quite a few ways to do this.

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

  1. As @Badri suggested, you can use the Request object directly in your actions. This is a very straightforward and simple approach but mixes controller logic with formatting/binding logic. If you want to create a better separation of concerns, try one of the following.
  2. 正如@Badri建议的那样,您可以直接在您的操作中使用Request对象。这是一种非常简单和简单的方法,但将控制器逻辑与格式化/绑定逻辑混合在一起。如果要创建更好的关注点分离,请尝试以下方法之一。

  3. There are a number of parameter binding mechanisms you can choose from. Looks to me like a custom model binder could work well in this case. You can access the Request object in the model binder and use something similar to @Badri's code to set up the values you expect (String.Empty or null) before they get passed to your action.
  4. 您可以选择许多参数绑定机制。在我看来,自定义模型绑定器在这种情况下可以很好地工作。您可以访问模型绑定器中的Request对象,并使用类似于@ Badri的代码来设置您期望的值(String.Empty或null),然后再将它们传递给您的操作。

  5. A value provider for the birthdate field might be a better option. You're passing a string that can ultimately be converted to a DateTime object. If you specify that that parameter should use a custom value provider (such as an IntuitiveDateTimeValueProvider), you can actually change the type of the parameter in your action to DateTime or Nullable<DateTime> (DateTime?) and let the value provider fill the value appropriately. You can also use a similar strategy for simpler strings for which you want to differentiate between empty and null (e.g., ExistenceTestingStringValueProvider).
  6. birthdate字段的值提供者可能是更好的选择。您传递的字符串最终可以转换为DateTime对象。如果指定该参数应使用自定义值提供程序(例如IntuitiveDateTimeValueProvider),则实际上可以将操作中的参数类型更改为DateTime或Nullable (DateTime?)并让值提供程序填充值适当。您还可以对更简单的字符串使用类似的策略,以便区分空和空(例如,ExistenceTestingStringValueProvider)。

  7. Create additional routes/actions. This isn't a good option if there are a lot of parameters because there are just too many possible combinations, but if there are just a few, this is a very simple solution. One way to do this is to simply create method overloads for each combination. If an overload that only has name is hit, it means birthdate wasn't specified, but if an overload with both parameters was hit, it means that birthdate was specified, even if its value is null, giving you a way to distinguish between specified but empty parameter values and unspecified parameter values.
  8. 创建其他路线/操作。如果有很多参数,这不是一个好的选择,因为有太多可能的组合,但如果只有少数,这是一个非常简单的解决方案。一种方法是简单地为每个组合创建方法重载。如果命中了只有名称的重载,则表示未指定birthdate,但如果同时遇到包含这两个参数的重载,则表示已指定birthdate,即使其值为null,也为您提供了区分指定的方法但是空参数值和未指定的参数值。