UTC DateTime을 Web API HttpGet 메서드에 전달하면 로컬 시간이 됩니다.
웹 API 메서드에 UTC 날짜를 쿼리 문자열 매개 변수로 전달하려고 합니다.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 PM01/04/2014 12:00:00 AM
★★★JsonFormatter.SerializerSettings 모양입니다.
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
DateFormatHandling = DateFormatHandling.IsoDateFormat
};
: POST 때 된 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」2014-04-01T00:00:00ZC# UTC Date Time (UTC 날짜 시간)하지만, 저는 이 모든 것을 할 수 있는endDate.Value.ToUniversalTime()POST에서는 동작하지만 GET에서는 동작하지 않는 것이 이상하다고 생각합니다.
하는 값2014-04-01T00:00:00ZUTC ★★★★★★★★★★★★★★★」로컬 으로 한 되며, 콜을 됩니다.ToUniversalTime()UTC ★★★★★★★★★★★★★★★★★」
그럼, 정확히 어떤 질문이죠?쿼리 문자열로 전송되어도 요청 본문에 게시되어 있지 않은 경우 이 문제가 발생하는 이유에 대한 질문인 경우, 그 질문에 대한 답변은 이 ASP입니다.NET Web API는 모델 바인딩을 사용하여 URI 경로, 쿼리 문자열 등을 바인딩하고 본문은 파라미터 바인딩을 사용하여 바인딩합니다.후자의 경우 미디어 포맷터를 사용합니다.JSON을 전송하면 JSON 미디어 포맷터가 사용되며 JSON을 기반으로 합니다.그물.
「 」를 지정했기 에,DateTimeZoneHandling.Utc이 BTW로 하면 BTW가 됩니다.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)));
파라미터가 'Da'로 되어 ' query string 파라미터는 'Da'로 인스턴스화 됩니다.DateTimeKind.Utc.
는 결국 ★★★★★★★★★★★★★★★★★★★★★★★★★★★ToUniversalTime()메서드를 지정합니다.
따라서 어플리케이션 전체에서 문자열에서 날짜로의 변환을 덮어쓰지 않고 날짜 파라미터를 사용하는 모든 메서드를 변경할 필요가 없는 사용자를 위해 웹 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; } }
드디어 이 코드를 찾았습니다.주요 답은 아니지만 경우에 따라서는 사용할 수 있습니다.
var dateUtc = TimeZoneInfo.ConvertTimeToUtc(date);
Date Time Offset(날짜 시간 오프셋)
버전화된 API 클래스는 내부 클래스에 자동으로 매핑됩니다.API의 URL 파라미터 모델에서 DateTimeOffset을 사용하여 DateTimeOffset = > DateTime 매핑을 추가하면 시간대 변환을 방지할 수 있습니다.예.
API 클래스:
public DateTimeOffset? SomeDateTime{ get; set; }
내부 클래스:
public DateTime? SomeDateTime{ get; set; }
매핑 프로파일:
CreateMap<DateTimeOffset, DateTime>();
[이 답변은 @SeanFausett의 답변으로 확대됩니다]
ISO 8601 날짜로 "Z"를 지정하고 Web api 함수가 이를 Utc Kind Date Time으로 수신할 수 있도록 하고 싶습니다.하지만 "Z"가 없으면 변환을 원하지 않습니다.
또한 들어오는 POST JSON 페이로드에서 날짜를 변환해야 했습니다.아래 함수는 문자열을 DateTime, DateTime?, DateTimeOffset 또는 DateTimeOffset으로 변환할 수 있습니다.
JSON 포스트 또는 URL 파라미터에 관계없이 날짜를 동일하게 해석하는 것이 편리합니다.원하는 대로 변환해 주세요.
//Register the two converters
var jSettings = new Newtonsoft.Json.JsonSerializerSettings()
jSettings.Converters.Add(new UtcDateTimeConverterJSON());
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = jSettings;
GlobalConfiguration.Configure(config =>
{
TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(UtcDateTimeConverterURI)));
WebApiConfig.Register(config);
}
//Date converter for URI parameters
public class UtcDateTimeConverterURI : DateTimeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value?.GetType() == typeof(string))
{
return StringToDate(typeof(DateTime), (string)value, Path: "URI parameter");
}
else
{
return base.ConvertFrom(context, culture, value);
}
}
/// <summary>
/// Convert String to DateTime, DateTime?, DateTimeOffset, or DateTimeOffset?<br />
/// Used for incoming JSON objects and URI parameters
/// </summary>
/// <param name="targetType">The type (i.e. typeof(DateTime))</param>
/// <param name="sDate">string representation of date to be converted</param>
/// <param name="Path">JSON Path in case of error, so the caller knows which parameter to fix</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static object StringToDate(Type targetType, string sDate, string Path)
{
//if the object is a DateTime, determine if we need to return a UTC or Local date type
bool returnUTC = false;
//DateTime or DateTimeOffset return type
bool isDateTimeOffset;
if (targetType == typeof(DateTime?) || targetType == typeof(DateTime))
{
isDateTimeOffset = false;
}
else
{
isDateTimeOffset = true;
}
DateTimeOffset d;
if (String.IsNullOrEmpty(sDate))
{
//if we have an empty string and the type is a nullable date, then return null... otherwise throw an error
if (targetType == typeof(DateTime?))
{
return null;
}
else
{
throw new Exception(Path + " cannot be an empty Date");
}
}
if (sDate[0] == '/')
{
// /Date(xxxxx)/ format
sDate = sDate.Substring(6, sDate.Length - 8);
var index = sDate.LastIndexOf('-');
if (index == -1) index = sDate.LastIndexOf('+');
if (index >= 0)
{
//lop off timezone offset
sDate = sDate.Substring(0, index);
}
else
{
//no timezone offset, return as UTC
returnUTC = true;
}
if (!Int64.TryParse(sDate, out var l))
{
//can't parse....
throw new Exception(Path + " cannot be parsed as a Date");
}
else
{
d = DateTimeOffset.FromUnixTimeMilliseconds(l);
}
}
else
{
//try and parse ISO8601 string
if (!DateTimeOffset.TryParse(sDate, out d))
{
throw new Exception(Path + " cannot be parsed as a Date");
}
else
{
if (!isDateTimeOffset)
{
//if UTC is specifically requested and we're not returning a DateTimeOffset, then make sure the return is UTC
if (d.Offset == TimeSpan.Zero && sDate[sDate.Length - 1] == 'Z') returnUTC = true;
}
}
}
if (isDateTimeOffset)
{
return d;
}
else
{
if (returnUTC)
{
return d.UtcDateTime;
}
else
{
//return the raw time passed in, forcing it to the "Local" Kind
//for example:
//"2020-03-27T12:00:00" --> use 2020-03-27 12:00:00PM with Kind=Local
//"2020-03-27T12:00:00-05:00" --> use 2020-03-27 12:00:00PM with Kind=Local
return DateTime.SpecifyKind(d.DateTime, DateTimeKind.Local); //this will pull the raw time and force the Kind to "Local"
}
}
}
}
//Date converter for JSON payloads
public class UtcDateTimeConverterJSON : DateTimeConverterBase
{
public override bool CanRead
{
get
{
return true;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null || reader.TokenType == JsonToken.Date) return reader.Value;
if (reader.TokenType != JsonToken.String) throw new Exception("Cannot parse Date");
return UtcDateTimeConverterURI.StringToDate(objectType, (string)reader.Value, reader.Path);
}
}
언급URL : https://stackoverflow.com/questions/22581138/passing-utc-datetime-to-web-api-httpget-method-results-in-local-time
'source' 카테고리의 다른 글
| document.getElementById를 angular4 / typscript로 대체하시겠습니까? (0) | 2023.03.19 |
|---|---|
| 여러 조건의 AngularJs ng-if (0) | 2023.03.19 |
| symfony2 어플리케이션의 Angularjs (0) | 2023.03.14 |
| pymongo - mongodb+srv:// URI를 사용하려면 "dnspython" 모듈을 설치해야 합니다. (0) | 2023.03.14 |
| React Redux에서 스토어 상태에 액세스하려면 어떻게 해야 합니까? (0) | 2023.03.14 |