D'abord cela fonctionne, mais aujourd'hui cela a échoué!
Voici comment je définis la propriété de date:
[Display(Name = "Date")]
[Required(ErrorMessage = "Date of Submission is required.")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime TripDate { get; set; }
Cela a fonctionné dans le passé. Mais aujourd'hui, lorsque j'appelle la même action ApiController:
[HttpPost]
public HttpResponseMessage SaveNewReport(TripLeaderReportInputModel model)
Le Firebug rapporte:
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"
Qu'est-il arrivé? Est-ce que ces [DataContract]
pour WCF
? J'utilise le REST WebAPI
dans MVC4
!
Quelqu'un peut-il aider? S'il vous plaît?
---mettre à jour---
J'ai trouvé des liens similaires.
MvC 4.0 RTM nous a cassé et nous ne savons pas comment le réparer RSS
--- mettre à jour à nouveau ---
Voici l'en-tête de réponse 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
En-tête de demande:
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
--- mettre à jour ---
J'ai trouvé une solution de fortune. Voir la réponse ci-dessous. Si quelqu'un comprend pourquoi cela fonctionne ou a de meilleures solutions, postez vos réponses. Je vous remercie.
J'ai ajouté un ModelValidationFilterAttribute
et l'ai fait fonctionner:
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);
}
}
}
Vous pouvez soit ajouter un filtre [ModelValidation]
aux actions. Ou ajoutez-le dans Global.asax.cs
:
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
De cette manière, je continue à utiliser l'annotation de données d'origine.
UPDATE 24-5-2013: La InvalidModelValidatorProvider
responsable de ce message d'erreur a été supprimé de la pile de technologies ASP.NET. Ce validateur a prouvé qu'il pouvait causer plus de confusion qu'il n'était censé en résoudre. Pour plus d'informations, voir le lien suivant: http://aspnetwebstack.codeplex.com/workitem/270
Lorsque vous décorez votre classe avec l'attribut [DataContract]
, vous devez explicitement décorer les membres que vous souhaitez sérialiser avec l'attribut [DataMember]
.
Le problème est que DataContractSerializer
ne prend pas en charge l'attribut [Required]
. Pour les types de référence, nous pouvons vérifier que la valeur n'est pas nulle après la désérialisation. Mais pour les types de valeur, il n’ya aucun moyen pour nous d’appliquer la sémantique [Required]
pour DataContractSerializer
sans [DataMember(IsRequired=true)]
.
Ainsi, vous pourriez marquer une DateTime
en tant que [Required]
et vous attendre à une erreur de validation du modèle si la DateTime
n'est pas envoyée, mais vous obtiendrez simplement une valeur DateTime.MinValue
et aucune erreur de validation.
Si vous essayez de renvoyer la sortie de votre action au format XML, vous devrez alors utiliser DataContracts car ils sont requis par le sérialiseur par défaut. Je suppose que vous demandiez précédemment la sortie de votre action en tant que Json, le sérialiseur Json ne nécessite pas de contrat de données. Pouvez-vous poster un violon de votre demande?