UTC日付をクエリ文字列パラメーターとしてWeb APIメソッドに渡そうとしています。 URLは次のようになります
_/api/order?endDate=2014-04-01T00:00:00Z&zoneId=4
_
メソッドの署名は次のようになります
_[HttpGet]
public object Index(int zoneId, DateTime? endDate = null)
_
日付は_31/03/2014 8:00:00 PM
_として入っていますが、_01/04/2014 12:00:00 AM
_として入ってほしい
私の_JsonFormatter.SerializerSettings
_は次のようになります
_new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
DateFormatHandling = DateFormatHandling.IsoDateFormat
};
_
編集#1:私はPOST _2014-04-01T00:00:00Z
_がC#でUTC DateTime種類にシリアル化されることに気づきました。しかしendDate.Value.ToUniversalTime()
変換するために、POST GETではなく、それがどのように動作するか奇妙に感じますが。
_2014-04-01T00:00:00Z
_を送信しているクエリ文字列パラメーター値はUTC時間です。そのため、同じことがローカルクロックに基づいて時間に変換され、ToUniversalTime()
を呼び出すと、UTCに変換されます。
それで、質問は正確に何ですか?質問がクエリ本文として送信された場合にこれが発生する理由であるが、リクエストボディに投稿されたときではない場合、その質問に対する答えは、ASP.NET Web APIがURIパス、クエリ文字列などをmodel bindingおよびparameter bindingを使用する本文。後者の場合、メディアフォーマッタを使用します。 JSONを送信する場合、JSONメディアフォーマッタが使用され、JSON.NETに基づいています。
_DateTimeZoneHandling.Utc
_を指定しているため、その設定が使用され、希望する日時の種類が取得されます。ところで、この設定を_DateTimeZoneHandling.Local
_に変更すると、モデルバインディングと同じ動作が見られます。
変換を透過的にする場合は、カスタムTypeConverter
を使用できます。
public sealed class UtcDateTimeConverter : DateTimeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return ((DateTime)base.ConvertFrom(context, culture, value)).ToUniversalTime();
}
}
以下を使用して接続します。
TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(UtcDateTimeConverter)));
その後、クエリ文字列パラメーターはDateTimeKind.Utc
としてインスタンス化されます。
最終的には、パラメーターが入力されるときにToUniversalTime()
メソッドを使用することになりました。
したがって、アプリケーション全体で文字列から日付への変換をオーバーライドしたくない、また日付パラメータを受け取るすべてのメソッドを変更することを忘れたくない場合は、次のようにしますWeb APIプロジェクト。
最終的に、一般的な指示はここから来ます:
この場合の特別な手順は次のとおりです。
「WebApiConfig」クラスで、次を追加します。
var provider = new SimpleModelBinderProvider(typeof(DateTime),new UtcDateTimeModelBinder());
config.Services.Insert(typeof(ModelBinderProvider), 0, provider);
UtcDateTimeModelBinderという新しいクラスを作成します。
public class UtcDateTimeModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext,
ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(DateTime)) return false;
var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null)
{
return false;
}
var key = val.RawValue as string;
if (key == null)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName,
"Wrong value type");
return false;
}
DateTime result;
if (DateTime.TryParse(key, out result))
{
bindingContext.Model = result.ToUniversalTime();
return true;
}
bindingContext.ModelState.AddModelError(bindingContext.ModelName,
"Cannot convert value to Utc DateTime");
return false;
}
}