私はこのような、たとえば、見えDTOクラス、持っている:.NETのWeb API:クラス・レベルの検証属性は、インスタンスがnullの場合は例外ArgumentNullExceptionをスローするには、Web APIを起こし
public class ExampleDto
{
[DataMember(Name = "Date", IsRequired = true, Order = 1), Required]
public DateTime Date { get; set; }
[DataMember(Name = "ParentExample", IsRequired = false, Order = 2, EmitDefaultValue = false)]
public Guid? ParentExampleId { get; set; }
}
を、もし一例として、ユーザーはこのような、誤った日付を提供しています。
<?xml version="1.0" encoding="UTF-8" ?>
<ExampleDto xmlns="http://customurl/">
<Date>2012-05-25T18:23:INCORRECTDATE</Date>
<ParentExample>B62F10A8-4998-4626-B5B0-4B9118E11BEC</ParentExample>
</ExampleDto>
または単にちょうど空のボディ、そして行動に渡さExampleDto引数はnullになります(そして前者の場合には、にModelStateにエラーがあります)。
私はクラスにCustomValidationAttributeを適用し、そのクラス宣言は次のようになります。今ExampleDto引数があるため、空体(nullの場合、または私は、これを追加しましたことを
[CustomValidation(typeof(CustomExampleValidator), "Validate")]
public class ExampleDto
シリアル化の問題)、例外ArgumentNullExceptionがスローされます。
<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns="http://customurl" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Type>Failure</Type>
<Message>An unknown error has occurred</Message>
<Errors>
<Error>
<Message>System.ArgumentNullException</Message>
<MessageDetail>Value cannot be null. Parameter name:
instance</MessageDetail>
<StackTrace> at System.ComponentModel.DataAnnotations.ValidationContext..ctor(Object
instance, IServiceProvider serviceProvider,
IDictionary`2 items) at System.Web.Http.Validation.Validators.DataAnnotationsModelValidator.Validate(ModelMetadata
metadata, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ShallowValidate(ModelMetadata
metadata, ValidationContext validationContext,
Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata
metadata, ValidationContext validationContext,
Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object
model, Type type, ModelMetadataProvider metadataProvider,
HttpActionContext actionContext, String keyPrefix)
at System.Web.Http.ModelBinding.FormatterParameterBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(Object
model) at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass36`1.<>c__DisplayClass38.<Then>b__35()
at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass49.<ToAsyncVoidTask>b__48()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1
func, CancellationToken cancellationToken)</StackTrace>
</Error>
</Errors>
</Response>
リフレクターnull引数のチェックがCustomValidationAttributeが実行される直前に、ValidationContextのコンストラクタでオブジェクトに対して実行されていることを示しています。ヌル引数はコントローラのアクションの引数として受け入れることができるので、少し奇妙なようです。私はここでnull引数のチェックは、フレームワークではなく、ユーザのコードで、または検証属性によって明示的に実行されるべきだと思います。
ユーザーが正しいXML/JSONを送信した場合、この例外はスローされず、期待通りにCustomValidationAttributeが実行されますが、ユーザーは常に正しいXML/JSONを送信するとは信用できません。また、ArgumentNullException彼らの努力のために、私は自分自身を返すことができるものの代わりに。
私はこれを経験した誰かを見つけるのに苦労しています。プロパティレベルで "複合"バリデータを適用する例はたくさんありますが、ここではクラスレベルで検証を適用する方が理にかなっています(特定のプロパティがnullでない場合は複数のプロパティが必要なため、別のプロパティはnullではありません)、クラスレベルで適用された検証属性がサポートされていないとは何も見つかりません。
回避策として:
そしてWebApiConfig.csでグローバルフィルタを登録します。だから、私の迅速かつ汚いソリューションは、フィルタでこれらの例外をキャッチし、適切な応答を返送することでした検証を実行するためにIValidatableObjectを明示的に実装しました。私は検証属性を使用することを好むので、これについての説明を探しています。 –
私はあなたの問題を再現しようとしましたが運がなかった...この画像を見てください:http://tallmaris.com/blog/wp-content/uploads/2013/06/Capture.png。あなたが見ることができるように、値はバリデーターに到着し、それはヌルではありません。それがコントローラに到達すると、 'IsValid'はコースの日付のためにfalseになります。その結果の投稿情報は次のとおりです。var example = new {Chi = "YYY"、PatientStatus = 1、Date = "2012-05-25T18:23:XXXX"、ParentExample = "B62F10A8-4998-4626-B5B0-4B9118E11BEC "};'(その後、Jsonはシリアライズしてアップロードしました)。 – Tallmaris
こんにちはタルマリス、それを与えてくれてありがとう。値がnullでない場合、例外はスローされません。var example = null;で投稿するか、jsonを手動で、構文エラーで送信してください。 –