为什么ModelState.IsValid失败有空的参数的我ApiController的方法? [英] Why does ModelState.IsValid fail for my ApiController method that has nullable parameters?

查看:229
本文介绍了为什么ModelState.IsValid失败有空的参数的我ApiController的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个接受多个参数,像这样的ApiController方式:

  // POST API /文件
    公众的Htt presponseMessage UploadFile
    (
        FileDto fileDto,
        诠释? existingFileId,
        布尔linkFromExistingFile,
        GUID? previousTrackingId
    )
    {
        如果(!ModelState.IsValid)
            返回Request.CreateResponse(的HTTPStatus code.BadRequest);        ...
    }

当我要在此我把 FileDto 对象请求的尸体,并在查询字符串的其它参数。

我已经发现,我不能简单地省略空的参数的 - 我需要把它们放在查询字符串空值。所以,我的查询看起来是这样的,当我不想指定空的参数的值:

<$p$p><$c$c>http://myserver/api/files?existingFileId=&linkFromExistingFile=true&$p$pviousTrackingId=

这不符合我的控制器方法,并执行该方法时,空的参数的确实是(如你所期望)。

然而后,调用 ModelState.IsValid 收益,当我检查它在抱怨这两个空的参数的相应的错误。 (该模型的其他位没有错误)。该消息是:


  

是必需的,但不是在请求present的值。


为什么会认为这个值是要求/未present?当然,(一)值的的要求可为空值,和(b)的值是(在某种程度上)present - 在某种程度上空十岁上下的排序


解决方案

在addtion的第一个答案,你应该能够得到您的code工作让preFIX年代漏报的网址,如果你移动所有可选的的方法声明的末尾,我总是将它们设置为NULL的好措施:

  FileDto fileDto,
布尔linkFromExistingFile,
GUID? previousTrackingId = NULL,
诠释? existingFileId = NULL

但是

好一点回复:使用preFIX一个空的URL值...是一样的NULL ...关于字符串的思考,是 Q = 一个空字符串或空??

我试图找到该框架的具体逻辑(继续寻找)引发这些错误,但我在实验过程中我也发现,直接在URL参数中指定的粘合剂似乎绕过逻辑,并允许空值后没有模型绑定错误preFIX。

像这样:

 公共类Values​​Controller:ApiController
{
    //获取API /值
    公共IEnumerable的&LT;串GT;得到(
        [FromUri(BinderType = typeof运算(TypeConverterModelBinder))]串Q = NULL,
        [FromUri(BinderType = typeof运算(TypeConverterModelBinder))INT?值= NULL)
    {
        如果(!ModelState.IsValid)
        {
            抛出新的Htt presponseException(的HTTPStatus code.BadRequest);
        }        返回新的String [] {value.HasValue? value.Value.ToString():,Q};
    }
}

I have an ApiController method that accepts several parameters, like so:

    // POST api/files
    public HttpResponseMessage UploadFile
    (
        FileDto fileDto,
        int? existingFileId,
        bool linkFromExistingFile,
        Guid? previousTrackingId
    )
    {
        if (!ModelState.IsValid)
            return Request.CreateResponse(HttpStatusCode.BadRequest);

        ...
    }

When I POST to this I'm putting the FileDto object in the body of the request, and the other parameters on the query string.

I've already discovered that I cannot simply omit the nullable parameters - I need to put them on the query string with an empty value. So, my query looks like this when I don't want to specify a value for the nullable parameters:

http://myserver/api/files?existingFileId=&linkFromExistingFile=true&previousTrackingId=

This does match my controller method, and when the method is executed, the nullable parameters are indeed null (as you'd expect).

However, the call to ModelState.IsValid returns false, and when I examine the erorrs it's complaining about both the nullable parameters. (The other bits of the model have no errors). The message is:

A value is required but was not present in the request.

Why does it think that a value was required / not present? Surely (a) a value is not required for a nullable, and (b) a value was (sort of) present - in a null-ish sort of a way?

解决方案

In addtion to the first answer you should be able to get your code working allow the omitting of the prefix's on the url if you move all the optional's to the end of the method declaration and I always set them to NULL for good measure:

FileDto fileDto,
bool linkFromExistingFile,
Guid? previousTrackingId = null,
int? existingFileId = null

But

Good point re: an empty URL value with a prefix... is it the same as a NULL... Thinking about strings, Is ?q= an empty string or a null??

I have attempted to find the exact logic in the framework (and continue to look) that raises these errors but during my experimentation I did find that specifying a binder directly on a URL parameter seems to bypass the logic and allow an empty value after a prefix without a model binding error.

Like so:

public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get(
        [FromUri(BinderType = typeof(TypeConverterModelBinder))] string q = null,
        [FromUri(BinderType = typeof(TypeConverterModelBinder))] int? value = null)
    {
        if (!ModelState.IsValid)
        {
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        }

        return new string[] { value.HasValue ? value.Value.ToString() : "", q };
    }     
}

这篇关于为什么ModelState.IsValid失败有空的参数的我ApiController的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆