最初はうまくいきましたが、今日は失敗しました!
これは私が日付プロパティを定義する方法です:
[Display(Name = "Date")]
[Required(ErrorMessage = "Date of Submission is required.")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime TripDate { get; set; }
それは過去に働いていました。しかし、今日、同じApiControllerアクションを呼び出すと、
[HttpPost]
public HttpResponseMessage SaveNewReport(TripLeaderReportInputModel model)
Firebugは次のように報告します。
ExceptionMessage:
"Property 'TripDate' on type 'Whitewater.ViewModels.Report.TripLeaderReportInputModel'
is invalid. Value-typed properties marked as [Required] must also be marked with
[DataMember(IsRequired=true)] to be recognized as required. Consider attributing the
declaring type with [DataContract] and the property with [DataMember(IsRequired=true)]."
ExceptionType
"System.InvalidOperationException"
どうした? WCF
の[DataContract]
ではありませんか? REST WebAPI
でMVC4
を使用しています!
誰か助けてもらえますか?お願いします?
- -更新 - -
私が見つけたいくつかの同様のリンクがあります。
MvC 4.0 RTM壊れており、RSSを修正する方法がわかりません
---もう一度更新---
HTTP応答ヘッダーは次のとおりです。
Cache-Control no-cache
Connection Close
Content-Length 1846
Content-Type application/json; charset=utf-8
Date Thu, 06 Sep 2012 17:48:15 GMT
Expires -1
Pragma no-cache
Server ASP.NET Development Server/10.0.0.0
X-AspNet-Version 4.0.30319
リクエストヘッダー:
Accept */*
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Cache-Control no-cache
Connection keep-alive
Content-Length 380
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Cookie .ASPXAUTH=1FF35BD017B199BE629A2408B2A3DFCD4625F9E75D0C58BBD0D128D18FFDB8DA3CDCB484C80176A74C79BB001A20201C6FB9B566FEE09B1CF1D8EA128A67FCA6ABCE53BB7D80B634A407F9CE2BE436BDE3DCDC2C3E33AAA2B4670A0F04DAD13A57A7ABF600FA80C417B67C53BE3F4D0EACE5EB125BD832037E392D4ED4242CF6
DNT 1
Host localhost:39019
Pragma no-cache
Referer http://localhost:39019/Report/TripLeader
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0
X-Requested-With XMLHttpRequest
---更新---
私はその場しのぎの解決策を見つけました。以下の回答を参照してください。なぜそれが機能するか、より良い解決策があるかを誰かが理解している場合は、回答を投稿してください。ありがとうございました。
はい。私はこのことを完全には理解していませんが。回避策が見つかりました。
Global.asax
:
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
AspnetwebstackのIssue Trackerで見つけました。ここにページへのリンクがあります:
[DataMember(IsRequired = true)]を値タイプの必須プロパティに適用するための非常に積極的な検証
だれかがこのような理由を教えてくれる場合は、洞察を回答として投稿してください。ありがとうございました。
ModelValidationFilterAttribute
を追加して機能させました:
public class ModelValidationFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
// Return the validation errors in the response body.
var errors = new Dictionary<string, IEnumerable<string>>();
//string key;
foreach (KeyValuePair<string, ModelState> keyValue in actionContext.ModelState)
{
//key = keyValue.Key.Substring(keyValue.Key.IndexOf('.') + 1);
errors[keyValue.Key] = keyValue.Value.Errors.Select(e => e.ErrorMessage);
}
//var errors = actionContext.ModelState
// .Where(e => e.Value.Errors.Count > 0)
// .Select(e => new Error
// {
// Name = e.Key,
// Message = e.Value.Errors.First().ErrorMessage
// }).ToArray();
actionContext.Response =
actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
}
}
}
アクションに[ModelValidation]
フィルターを追加できます。または、Global.asax.cs
に追加します。
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
このようにして、元のデータ注釈を引き続き使用します。
UPDATE 24-5-2013:このエラーメッセージの原因であるInvalidModelValidatorProvider
が削除されましたASP.NETテクノロジスタックから。このバリデーターは、解決するつもりよりも混乱を引き起こすことが証明されています。詳細については、次のリンクを参照してください。 http://aspnetwebstack.codeplex.com/workitem/27
_[DataContract]
_属性を使用してクラスを装飾する場合、_[DataMember]
_属性を使用してシリアル化するメンバーを明示的に装飾する必要があります。
問題は、DataContractSerializer
が_[Required]
_属性をサポートしないことです。参照型の場合、逆シリアル化後に値がnullでないことを確認できます。しかし、値型の場合、[DataMember(IsRequired=true)]
なしでDataContractSerializer
に_[Required]
_セマンティクスを適用する方法はありません。
したがって、DateTime
を_[Required]
_としてマークしてしまう可能性があり、DateTime
が送信されない場合はモデル検証エラーが予想されますが、_DateTime.MinValue
_が取得されるだけです。値であり、検証エラーはありません。
アクションの出力をXMLとして返そうとする場合、デフォルトのシリアライザーで必要とされるため、DataContractsを使用する必要があります。以前Jsonとしてアクションの出力をリクエストしていたと思いますが、Jsonシリアライザーはデータコントラクトを必要としません。リクエストのフィドルを投稿できますか?