ModelState.IsValid是假的时,我有一个可空参数 [英] ModelState.IsValid is false when I have a nullable parameter

查看:1153
本文介绍了ModelState.IsValid是假的时,我有一个可空参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我转载我在一个全新的MVC的Web API项目遇到的问题。

I reproduced the issue I am having in a brand new MVC Web API project.

这是默认的code有轻微的修改。

This is the default code with a slight modification.

public string Get(int? id, int? something = null)
{
    var isValid = ModelState.IsValid;
    return "value";
}

如果你去的http://本地主机/ API /价值/ 5 =东西123 那么这工作得很好,并且是的isValid

If you go to http://localhost/api/values/5?something=123 then this works fine, and isValid is true.

如果你去的http://本地主机/ API /价值/ 5 =东西然后是的isValid

If you go to http://localhost/api/values/5?something= then isValid is false.

我遇到的问题是,如果你提供的是可空项为空或省略数值,ModelState.IsValid标志验证错误说法的值是必需的,但没有present请求。

The issue I am having is that if you provide a null or omitted value for an item that is nullable, the ModelState.IsValid flags a validation error saying "A value is required but was not present in the request."

该ModelState中词典还看起来像这样:

The ModelState dictionary also looks like this:

有两个条目的东西一空的,这我不知道,如果它是显著与否。

with two entries for something, one nullable, which I am not sure if it is significant or not.

任何想法被省略或为空时提供空的参数的我如何能解决这个问题,这样的模式是有效的?我用我的网络API中的模型验证,如果有一个可空参数每个方法生成模型误差它弄坏。

Any idea how I can fix this so that the model is valid when nullable parameters are omitted or provided as null? I am using model validation within my web api and it breaks it if every method with a nullable parameter generates model errors.

推荐答案

看来,默认绑定模式并不完全了解可空类型。如在问题看出,它给出了三个参数错误,而不是预期的两项。

It appears that the default binding model doesn't fully understand nullable types. As seen in the question, it gives three parameter errors rather than the expected two.

您可以避开这个带有自定义为空的模型绑定:

You can get around this with a custom nullable model binder:

模型绑定

public class NullableIntModelBinder : IModelBinder
{
    public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType != typeof(int?))
        {
            return false;
        }

        ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (val == null)
        {
            return false;
        }

        string rawvalue = val.RawValue as string;

        // Not supplied : /test/5
        if (rawvalue == null)
        {
            bindingContext.Model = null;
            return true;
        }

        // Provided but with no value : /test/5?something=
        if (rawvalue == string.Empty)
        {
            bindingContext.Model = null;
            return true;
        }

        // Provided with a value : /test/5?something=1
        int result;
        if (int.TryParse(rawvalue, out result))
        {
            bindingContext.Model = result;
            return true;
        }

        bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value to int");
        return false;
    }
}

用法

public ModelStateDictionary Get(
    int? id, 
    [ModelBinder(typeof(NullableIntModelBinder))]int? something = null)
{
    var isValid = ModelState.IsValid;

    return ModelState;
}

从asp.net页面改编:<一href=\"http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api\" rel=\"nofollow\">http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api进一步阅读和另一种方法来设置它在类(控制器),而不是每个参数。

Adapted from the asp.net page: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api for further reading and an alternative method to set it at the class(controller) level rather than per parameter.

此处理3有效的方案:

/test/5
/test/5?something=
/test/5?something=2

此先给东西为空。别的(如?东西= X )给出了一个错误。

this first give "something" as null. Anything else (eg ?something=x) gives an error.

如果您更改签名

int? somthing

(即删除 = NULL ),那么你必须明确提供的参数,即 /测试/ 5 不会是一个有效的途径,除非你调整你的路线以及

(ie remove = null) then you must explicitly provide the parameter, ie /test/5 will not be a valid route unless you tweak your routes as well.

这篇关于ModelState.IsValid是假的时,我有一个可空参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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