Nib*_*Pig 11 asp.net-mvc model-binding asp.net-web-api
我在一个全新的MVC Web API项目中重现了我遇到的问题.
这是默认代码,略有修改.
public string Get(int? id, int? something = null)
{
var isValid = ModelState.IsValid;
return "value";
}
Run Code Online (Sandbox Code Playgroud)
如果你去,http://localhost/api/values/5?something=123那么这很好,isValid是true.
如果你去http://localhost/api/values/5?something=那么isValid是false.
我遇到的问题是,如果为可以为空的项提供null或省略的值,ModelState.IsValid会标记验证错误 "A value is required but was not present in the request."
ModelState字典也如下所示:
有两个条目something,一个可以为空,我不确定它是否重要.
知道如何解决这个问题,以便在省略可空参数或提供为null时模型是有效的吗?我在我的web api中使用模型验证,如果每个带有可为空参数的方法都会产生模型错误,它就会破坏它.
似乎默认绑定模型并不完全理解可为空类型。正如问题中所见,它给出了三个参数错误,而不是预期的两个。
您可以使用自定义的可为空模型绑定器解决此问题:
模型绑定器
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;
}
}
Run Code Online (Sandbox Code Playgroud)
用法
public ModelStateDictionary Get(
int? id,
[ModelBinder(typeof(NullableIntModelBinder))]int? something = null)
{
var isValid = ModelState.IsValid;
return ModelState;
}
Run Code Online (Sandbox Code Playgroud)
改编自 asp.net 页面:http : //www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api以供进一步阅读和替代方法将其设置在类(控制器)级别而不是每个参数。
这处理 3 个有效场景:
/test/5
/test/5?something=
/test/5?something=2
Run Code Online (Sandbox Code Playgroud)
这首先将“某物”作为空值。其他任何东西(例如?something=x)都会出错。
如果您将签名更改为
int? somthing
Run Code Online (Sandbox Code Playgroud)
(即 remove = null)那么您必须明确提供该参数,即/test/5除非您也调整您的路线,否则将不是有效的路线。
| 归档时间: |
|
| 查看次数: |
5701 次 |
| 最近记录: |