29

オブジェクトを MVC コントローラーに投稿しています。このオブジェクトには StartDt というフィールドが含まれており、クライアントではローカル時間の JavaScript Date オブジェクトです。

オブジェクトで JSON.stringify を呼び出し、jQuery の ajax メソッドを使用してサーバーに POST すると、サーバーに送信されているのは "1900-12-31T13:00:00.000Z" のような ISO 文字列であることが Firebug でわかります。 believe は UTC 形式の現地時間である必要があります。

ただし、コントローラーの DateTime フィールドを見ると、UTC ではなく現地時間に戻っているように見えます。どうすればこれを修正できますか?

クライアントからの Date の UTC バージョンを保存したいと考えています。

4

7 に答える 7

21

ISO 8601準拠のDateTime Model Binderのコードを含む Gist を Google で見つけ、次のように変更しました。

public class DateTimeBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var name = bindingContext.ModelName;
        var value = bindingContext.ValueProvider.GetValue(name);
        if (value == null) 
            return null;

        DateTime date;
        if (DateTime.TryParse(value.AttemptedValue, null, DateTimeStyles.RoundtripKind, out date))
            return date;
        else
            return base.BindModel(controllerContext, bindingContext);
    }
}

Gist コードは制限が厳しすぎると思います。秒の小数点以下 6 桁が必要です。そうしないと、タイムスタンプが受け入れられません。これは TryParseExact の代わりに TryParse を使用するため、技術的に多くのタイムスタンプ タイプを受け入れます。重要な部分は、DateTimeStyles.RoundtripKind を使用して、Z によって暗示されるタイム ゾーンを尊重することです。そのため、これは技術的には ISO 8601 固有の実装ではなくなりました。

次に、モデル バインダー属性または App_Start のこのスニペットを使用して、これを MVC パイプラインにフックできます。

var dateTimeBinder = new DateTimeBinder();

ModelBinders.Binders.Add(typeof(DateTime), dateTimeBinder);
ModelBinders.Binders.Add(typeof(DateTime?), dateTimeBinder);
于 2012-11-12T22:17:13.187 に答える
9

この小さな属性を作成しました。

public class ConvertDateToUTCAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var dateArgs =
            filterContext.ActionParameters.Where(
                x => x.Value != null && x.Value.GetType().IsAssignableFrom(typeof(DateTime))).ToList();

        foreach (var keyValuePair in dateArgs)
        {
            var date = (DateTime) keyValuePair.Value;

            if (date.Kind == DateTimeKind.Local)
                filterContext.ActionParameters[keyValuePair.Key] = date.ToUniversalTime();
        }

        base.OnActionExecuting(filterContext);
    }
}

したがって、これにより、指定されていない日付またはすでに Utc だけの日付が残ります。コントローラー全体に適用できます。

于 2012-04-27T01:34:31.647 に答える
8

または、バインドされたオブジェクトをDateTimeOffsetではなくに指定するDateTimeと、自動変換は行われません。着信文字列に接尾辞が付いている限りZ、元の日付のオフセットを取得する必要があります+00:00

于 2018-08-02T13:53:03.030 に答える
7

UTC時刻を取得するには、DateTime.ToUniversalTime()メソッドを使用する必要がある場合があります。

于 2012-04-24T07:27:09.367 に答える