Ich habe ein WebAPI-Projekt, das ISO-Datumszeichenfolgen in das Eingabemodell aufnimmt. Ich habe diese unter Verwendung DateTimeOffset?
analysiert. Ich möchte BCL-Datumsangaben aus meinem Projekt verbannen, also möchte ich einen Weg finden, diese Zeichenfolgen direkt an Instant
zu binden.Binden von NodaTime Instant-Feld in einem InputModel-Textkörper mit C# ASP.NET WebAPI 2.0
public class MyInputModel
{
public DateTimeOffset? OldTime { get; set; }
public Instant NewTime { get; set; }
}
Ein Beispiel JSON Eingabemodell sieht wie folgt aus:
{
"oldtime":"2016-01-01T12:00:00Z",
"newtime":"2016-01-01T12:00:00Z"
}
Und mein Controller-Code ist:
[HttpPost]
public async Task<IActionResult> PostTimesAsync([FromBody]MyInputModel input)
{
Instant myOldTime = Instant.FromDateTimeUtc(input.oldTime.Value.UtcDateTime);
Instant myNewTime = input.newTime; // This cannot be used with ISO date strings.
}
ich wie folgt ein benutzerdefiniertes Modell Bindemittel zu bauen versucht. Dies funktioniert für Modelle in der Abfragezeichenfolge, nicht jedoch für solche im Hauptteil einer POST-Anforderung. Wie kann ich Datumseingaben in einem ISO 8601 String-Format an einen NodaTime Instant binden? (In WebApiConfig
Register
Methode)
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.BindParameter(typeof(Instant), new InstantModelBinder())
...
}
}
WebApiConfig.Register heißt in Configuration
Funktion in Startup.cs
Datei:
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (!String.IsNullOrWhiteSpace(bindingContext.ModelName) &&
bindingContext.ModelType == typeof(Instant?) &&
bindingContext.ValueProvider.GetValue(bindingContext.ModelName) != null)
{
Instant? value;
var val = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName).FirstValue as string;
if (String.IsNullOrWhiteSpace(val))
{
bindingContext.Result = ModelBindingResult.Failed();
return Task.FromResult(0);
}
else if (InstantExtensions.TryParse(val, out value))
{
bindingContext.Result = ModelBindingResult.Success(value);
return Task.FromResult(0);
}
else
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName,
"The date is invalid.");
}
}
bindingContext.Result = ModelBindingResult.Failed();
return Task.FromResult(0);
}
public static bool TryParse(string value, out Instant? result)
{
result = null;
// If this is date-only, add Utc Midnight to the value.
if (value.Length.Equals(10))
{
value += "T00:00:00Z";
}
// Trim milliseconds if present
var decimalPointIndex = value.IndexOf('.');
if (decimalPointIndex > 0)
{
value = value.Substring(0, decimalPointIndex) + "Z";
}
// Attempt to parse
var parseResult = InstantPattern.GeneralPattern.Parse(value);
if (parseResult.Success)
{
result = parseResult.Value;
return true;
}
return false;
}
Für welchen Typ haben Sie Ihren Modellbinder registriert? –
Hallo Aram, ich habe es nicht registriert - in den Abfragezeichenfolgen verwende ich es wie folgt: '[ModelBinder (BinderType = typeof (InstantModelBinder))] Instant? time = null) ' – Ivan
Versuchen Sie diese' ModelBinders.Binders.Add (typeof (Instant?), neue InstantModelBinder()); 'in' Global.asax.cs' Oder vielleicht ohne Fragezeichen, wie ich in 'MyInputModel 'Es ist nicht nullbar. –