简体   繁体   English

ASP.net WebApi参数从URI绑定到复杂类型

[英]ASP.net WebApi Parameter Binding to complex type from URI

I want to create a REST webservice using ASP.net WebApi on .net 4.5 我想在.net 4.5上使用ASP.net WebApi创建REST Web服务

Urls should be of a format like this: Urls的格式应为:

/values?Age=55&Height=176&Race=1&Weight=80&Gender=male&id=800001

The associated controller looks like this: 关联的控制器如下所示:

[HttpGet]
public string Get(int id, [FromUri]Demographics demographics)
{ // etc.}

Where Demographics is a custom object that is basically just a DTO with certain properties. 其中,受众特征是一个自定义对象,基本上只是具有某些属性的DTO。 However, it contains one property that has the type of a custom enum: 但是,它包含一个具有自定义枚举类型的属性:

enum Gender
{
 Female = 0,
 Male
}

The default mapping works just fine if the URL is of the above format. 如果URL具有以上格式,则默认映射可以正常工作。 However, of course I also need to check whether the parameters provided by the url are correct. 但是,当然,我还需要检查url提供的参数是否正确。

ASP.net WebApi (afaik) per default tries to map each parameter based on the assumed type (or if it can be converted to that type). 默认情况下,ASP.net WebApi(afaik)尝试根据假定的类型(或是否可以将其转换为该类型)映射每个参数。 If it can't find a matching value in the URI it appears to assume it is just 0. 如果在URI中找不到匹配的值,则似乎假定它仅为0。

Now this takes me to a very unfortunate situation where 0 is by definition still a valid value for Gender Demographics.Gender (0 ~ Gender.Female). 现在,这使我陷入非常不幸的境地,根据定义,0仍然是Gender Demographics.Gender(0〜Gender.Female)的有效值。

The simplest solution would be to change the enum so that 0 would be a "indeterminate" state that I could check for. 最简单的解决方案是更改枚举,以使0成为我可以检查的“不确定”状态。 However, I can not change the enum. 但是,我无法更改枚举。 I could create my own overload for the Demographics object but would rather not do this, because I think there must be a nicer way. 我可以为Demographics对象创建自己的重载,但宁愿不这样做,因为我认为必须有更好的方法。

Can I explicitely bind the gender parameter to a parameter in the URI and throw an exception if it was not submitted? 我可以明确地将性别参数绑定到URI中的参数,如果未提交则抛出异常?

I read about type converters but I would have to work on the URI string and think I would have to implement a lot functionality that WebApi apparently already has. 我读过有关类型转换器的信息,但我必须处理URI字符串,并认为我必须实现WebApi显然已经具有的许多功能。

Please keep in mind that I have to work on the URI and can not use the Request Body. 请记住,我必须处理URI,并且不能使用请求正文。

How about making the enum nullable like this? 这样使枚举可为空怎么样?

public class Demographics
{
    public Gender? Gender { get; set; }
}

Inside the action method, you can just check if demographics.Gender is null or not. 在action方法内部,您可以仅检查demographics.Gender是否为null。

WebAPI contains a validation framework through data annotations . WebAPI包含通过数据注释的验证框架。 This allows you to mark the Gender-property in the Demographics object as [Required]: 这使您可以将“人口统计”对象中的性别属性标记为[必需]:

public class Demographics
{
    [Required]
    public Gender Gender { get; set; }
}

Then, mark the controller or the controller method with the [ValidateModel] attribute to force validation (read about other ways to force this, eg globally: model validation ): 然后,用[ValidateModel]属性标记控制器或控制器方法以强制验证(了解其他强制方法,例如,全局: 模型验证 ):

[HttpGet]
[ValidateModel]
public string Get(int id, [FromUri]Demographics demographics)
{ // etc.}

After this, if you miss to provide the parameter, you'll get automatic validation and an error 400 Bad Request with a message: 此后,如果您错过提供参数,则会得到自动验证,并显示一条错误400 Bad Request并显示一条消息:

{"Message":"The request is invalid.","ModelState":{"Gender":["The Gender field is required."]}}

Invalid values are handled correctly by default, even without the required attribute, so an incorrect value of Foo provided to the gender is responded also with a 400 Bad Request message: 默认情况下,即使没有必需的属性,默认情况下也会正确处理无效值,因此,还会使用400 Bad Request消息响应提供给性别的Foo值不正确:

{"Message":"The request is invalid.","ModelState":{"Gender":["The value 'Foo' is not valid for Gender."]}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM