datetime 매개 변수를 전달하는 방법은 무엇입니까?
UTC 날짜를 웹 API로 전달하는 방법은 무엇입니까?
싱패2010-01-01
작동하지만, 제가 , 같은과때하를짜 UTC통할과와 같은 때.2014-12-31T22:00:00.000Z
(시간 구성 요소 포함), HTTP 404 응답을 수신합니다.그렇게
http://domain/api/controller/action/2012-12-31T22:00:00.000Z
404 오류 응답을 생성하는 동안
http://domain/api/controller/action/2012-12-31
잘 작동합니다.
UTC 날짜를 웹 API로 전달하는 방법 - 아니면 최소한 날짜와 시간을 지정하는 방법?
문제는 두 가지입니다.
더.
기본적으로 IIS는 점이 있는 모든 URI를 정적 리소스로 처리하고 이를 반환하고 추가 처리를 모두 건너뜁니다.은 Web.config 됩니다.system.webServer.handlers
는 기본핸핸을 처리합니다.path="*."
이 문서에서 이상한 구문과 관련된 문서를 많이 찾을 수 없습니다.path
속성(regex)이 더 의미가 있었지만, 이것이 의미하는 것은 "점을 포함하지 않는 기호"(및 아래 2 지점의 문자)입니다. ' 없음이라는 이름의 '확장 없음'은다음과 같습니다.ExtensionlessUrlHandler-Integrated-4.0
.
여러 가지 해결책이 가능하며, '정확성'의 순서로 생각합니다.
- 점을 허용해야 하는 경로에 대한 새 처리기를 추가합니다.기본값 앞에 추가해야 합니다.이렇게 하려면 먼저 기본 처리기를 제거한 후 해당 처리기를 다시 추가해야 합니다.
- 변할내용을 합니다.
path="*."
다리탓으에 대한 .path="*"
그러면 그것은 모든 것을 잡을 것입니다.이때부터 웹 API는 더 이상 점이 있는 수신 통화를 정적 리소스로 해석하지 않습니다!API에서 하지 않습니다! API를 참조하십시오. - 에 추가하여 요청을 합니다: "Web.config" 아래에서.
<system.webserver>
:<modules runAllManagedModulesForAllRequests="true">
더:
위의 내용을 변경한 후에는 기본적으로 다음 오류가 표시됩니다.
잠재적으로 위험한 요청입니다.클라이언트(:)에서 경로 값이 탐지되었습니다.
Web.config에서 미리 정의된 허용되지 않는/잘못된 문자를 변경할 수 있습니다.<system.web>
합니다.<httpRuntime requestPathInvalidCharacters="<,>,%,&,*,\,?" />
제가 제거했습니다.:
유효하지 않은 문자의 표준 목록에서.
더 쉽고 안전한 솔루션
질문에 대한 답변은 아니지만, 이 모든 것이 필요하지 않도록 요청을 변경하는 것이 더 안전하고 쉬운 해결책이 될 것입니다.이 작업은 두 가지 방법으로 수행할 수 있습니다.
- 날짜를 쿼리 문자열 매개 변수로 전달(예:
?date=2012-12-31T22:00:00.000Z
. - 를 .
.000
모든 요청에서 URL을 인코딩하므로 모두 바꾸기:
함께 있음%3A
예를 들어 사용하여HttpUtility.UrlEncode()
.
제품 웹 API 컨트롤러에서 다음을 수행합니다.
[RoutePrefix("api/product")]
public class ProductController : ApiController
{
private readonly IProductRepository _repository;
public ProductController(IProductRepository repository)
{
this._repository = repository;
}
[HttpGet, Route("orders")]
public async Task<IHttpActionResult> GetProductPeriodOrders(string productCode, DateTime dateStart, DateTime dateEnd)
{
try
{
IList<Order> orders = await _repository.GetPeriodOrdersAsync(productCode, dateStart.ToUniversalTime(), dateEnd.ToUniversalTime());
return Ok(orders);
}
catch(Exception ex)
{
return NotFound();
}
}
}
Fiddler에서 GetProductPeriodOrders 방법 테스트 - 구성자:
http://localhost:46017/api/product/orders?productCode=100&dateStart=2016-12-01T00:00:00&dateEnd=2016-12-31T23:59:59
DateTime 형식:
yyyy-MM-ddTHH:mm:ss
javascript pass 매개 변수 use moment.js
const dateStart = moment(startDate).format('YYYY-MM-DDTHH:mm:ss');
const dateEnd = moment(endDate).format('YYYY-MM-DDTHH:mm:ss');
당신의 고통을 느껴요...또 다른 날짜 시간 형식...바로 당신이 필요로 했던 것!
Web API 2를 사용하여 경로 특성을 사용하여 매개 변수를 지정할 수 있습니다.
따라서 클래스와 메서드의 속성을 사용하여 문제가 있는 이 utc 형식을 사용하여 REST URL을 코드화할 수 있습니다(분명히 ISO8601이며, startDate.toISOString()을 사용하여 도착한 것으로 추정됨).
[Route(@"daterange/{startDate:regex(^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$)}/{endDate:regex(^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$)}")]
[HttpGet]
public IEnumerable<MyRecordType> GetByDateRange(DateTime startDate, DateTime endDate)
그러나 이것은 하나의 날짜(startDate)로 작동하지만, 어떤 이유로 endDate가 이 형식일 때는 작동하지 않습니다... 몇 시간 동안 디버깅됩니다. (web.config가 다음과 함께 설정되어 있더라도) colon ":"을 좋아하지 않는다는 단서만 있습니다.
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" requestPathInvalidCharacters="" />
</system.web>
따라서 다른 날짜 형식(ISO 날짜 형식의 폴리필에서 가져온 것)을 만들어 Javascript 날짜에 추가합니다(간단하게는 최대 분까지만 변환).
if (!Date.prototype.toUTCDateTimeDigits) {
(function () {
function pad(number) {
if (number < 10) {
return '0' + number;
}
return number;
}
Date.prototype.toUTCDateTimeDigits = function () {
return this.getUTCFullYear() +
pad(this.getUTCMonth() + 1) +
pad(this.getUTCDate()) +
'T' +
pad(this.getUTCHours()) +
pad(this.getUTCMinutes()) +
'Z';
};
}());
}
그런 다음 Web API 2 메서드로 날짜를 보낼 때 문자열에서 날짜로 변환할 수 있습니다.
[RoutePrefix("api/myrecordtype")]
public class MyRecordTypeController : ApiController
{
[Route(@"daterange/{startDateString}/{endDateString}")]
[HttpGet]
public IEnumerable<MyRecordType> GetByDateRange([FromUri]string startDateString, [FromUri]string endDateString)
{
var startDate = BuildDateTimeFromYAFormat(startDateString);
var endDate = BuildDateTimeFromYAFormat(endDateString);
...
}
/// <summary>
/// Convert a UTC Date String of format yyyyMMddThhmmZ into a Local Date
/// </summary>
/// <param name="dateString"></param>
/// <returns></returns>
private DateTime BuildDateTimeFromYAFormat(string dateString)
{
Regex r = new Regex(@"^\d{4}\d{2}\d{2}T\d{2}\d{2}Z$");
if (!r.IsMatch(dateString))
{
throw new FormatException(
string.Format("{0} is not the correct format. Should be yyyyMMddThhmmZ", dateString));
}
DateTime dt = DateTime.ParseExact(dateString, "yyyyMMddThhmmZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
return dt;
}
그래서 URL은.
http://domain/api/myrecordtype/daterange/20140302T0003Z/20140302T1603Z
Hanselman은 여기에서 관련 정보를 제공합니다.
http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx
sk의 답변과 유사한 대안으로 쿼리 문자열에 로 포맷된 날짜를 전달할 수 있습니다.이 형식은 표준 ISO 8601 형식이며 에 의해 승인됩니다.경로 또는 작업에 대한 추가 구성 없이 Net Web API 컨트롤러.
예.
var dateString = dateObject.toISOString(); // "2019-07-01T04:00:00.000Z"
이것은 가능한 해결책과 모델입니다.클라이언트에서 Moment.js를 사용하여 날짜 형식을 지정하고 unix 시간으로 변환합니다.
$scope.startDate.unix()
경로 매개 변수가 길도록 설정합니다.
[Route("{startDate:long?}")]
public async Task<object[]> Get(long? startDate)
{
DateTime? sDate = new DateTime();
if (startDate != null)
{
sDate = new DateTime().FromUnixTime(startDate.Value);
}
else
{
sDate = null;
}
... your code here!
}
Unix 시간에 대한 확장 메서드를 만듭니다.유닉스 날짜 시간 방법
이전에는 힘든 작업이었지만 이제는 toUTCString()을 사용할 수 있습니다.
예:
[HttpPost]
public ActionResult Query(DateTime Start, DateTime End)
Ajax 포스트 요청에 아래 내용 삽입
data: {
Start: new Date().toUTCString(),
End: new Date().toUTCString()
},
사실 매개 변수를 ?date='full datetime'으로 명시적으로 지정하는 것이 매력적으로 작용했습니다.따라서 지금은 쉼표를 사용하지 말고 기존 GET 방식을 사용하는 것이 해결책이 될 것입니다.
한 가지 가능한 해결책은 눈금을 사용하는 것입니다.
public long Ticks { get; }
그러면 컨트롤러의 방법은 다음과 같습니다.
public DateTime(long ticks);
ISO-8859-1 운영 체제 인코딩을 가지고 있기 때문에 날짜 형식은 "dd.MM.yyyy HH:mm:ss"가 불변 문화 문자열을 사용하는 작업을 인식하지 못했습니다.
string url = "GetData?DagsPr=" + DagsProfs.ToString(CultureInfo.InvariantCulture)
코드를 보면 DateTime 객체의 'Time'에 대해 걱정하지 않으실 것 같습니다.이 경우 날짜, 월 및 연도를 정수 매개 변수로 전달할 수 있습니다.다음 코드를 참조하십시오.이것은 제가 현재 진행하고 있는 프로젝트의 실제 사례입니다.
장점은 이 방법을 사용하면 DateTime 형식 문제와 문화 비호환성을 방지할 수 있다는 것입니다.
/// <summary>
/// Get Arrivals Report Seven Day Forecast
/// </summary>
/// <param name="day"></param>
/// <param name="month"></param>
/// <param name="year"></param>
/// <returns></returns>
[HttpGet("arrivalreportsevendayforecast/{day:int}/{month:int}/{year:int}")]
public async Task<ActionResult<List<ArrivalsReportSevenDayForecastModel>>> GetArrivalsReportSevenDayForecast(int day, int month, int year)
{
DateTime selectedDate = new DateTime(year, month, day);
IList<ArrivalsReportSevenDayForecastModel> arrivingStudents = await _applicationService.Value.GetArrivalsReportSevenDayForecast(selectedDate);
return Ok(arrivingStudents);
}
프론트엔드도 보고 싶다면 아래 코드를 읽어보십시오.불행하게도, 그것은 Angular로 쓰여 있습니다.이것이 일반적으로 Angular GET 요청에서 DateTime을 쿼리 매개 변수로 전달하는 방법입니다.
public getArrivalsReportSevenDayForecast(selectedDate1 : Date): Observable<ArrivalsReportSevenDayForecastModel[]> {
const params = new HttpParams();
const day = selectedDate1.getDate();
const month = selectedDate1.getMonth() + 1
const year = selectedDate1.getFullYear();
const data = this.svcHttp.get<ArrivalsReportSevenDayForecastModel[]>(this.routePrefix +
`/arrivalreportsevendayforecast/${day}/${month}/${year}`, { params: params }).pipe(
map<ArrivalsReportSevenDayForecastModel[], ArrivalsReportSevenDayForecastModel[]>(arrivingList => {
// do mapping here if needed
return arrivingList;
}),
catchError((err) => this.svcError.handleError(err)));
return data;
}
날짜를 문자열로 전달하고 구문 분석하는 것이 저에게 효과가 있었습니다.아마도 구문 분석에 시도 캐치를 추가하고 싶지만, 이것이 기본 코드입니다.
[HttpGet("name={name}/date={date}", Name = "GetByNameAndDate")]
public IActionResult GetByNameAndDate(string name, string date) {
DateTimeOffset dto = DateTimeOffset.Parse(date);
}
그러면 요청은 다음과 같이 보일 수 있습니다.
https://localhost/api/Contoller/name=test/date=2022-02-18T13:45:37.000Z
외부 API(서비스를 호출할 클라이언트 유형을 알 수 없는 경우)의 경우 입력 매개 변수 및 출력 날짜 필드에서 모두 Unix 시간을 사용해야 합니다.https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tounixtimeseconds?view=net-6.0
.Net은 DateTime 또는 DateTimeOff로 쉽게 변환할 수 있는 ToUniximeSeconds 및 FromUnixSeconds를 제공합니다.
유닉스 시간은 정수일 뿐이고 인코딩 없이 URL 문자열로 전달될 수 있기 때문에 ISO 형식보다 선호되어야 합니다.
'Ticks' 속성은 유닉스 시간과 비슷하지만 (나는) .net 클라이언트와 서버 사이에서만 사용해야 한다고 생각합니다.
가장 잘 알려진 API는 Unix Time을 사용합니다. 예를 들어 Stripe의 API: https://stripe.com/docs/api 를 참조하십시오.
유닉스 시간을 사용하는 것의 명백한 단점은 다음과 같습니다.
- 그것들은 사람이 읽을 수 없습니다.
- 그것들은 사람에 의해 만들어질 수 없습니다 - 코드 없이 API를 호출하는 것을 어렵게 만듭니다.
이진 형식을 사용합니다.
URL로 정보를 보내려면 dateTimeVar를 사용합니다.이진()에게 다음과 같은 것이 될 것입니다.
http://domain/api/controller/action/637774955400000000
수신하면 데이터가 Long 변수처럼 되고 DateTime 클래스의 정적 함수를 사용하여 DateTime 유형으로 다시 변환됩니다.
DateTime MyDateTime = DateTime입니다.이진에서(이진 날짜 시간);
건배.
언급URL : https://stackoverflow.com/questions/14359566/how-to-pass-a-datetime-parameter
'programing' 카테고리의 다른 글
일반 이전 CLR 개체 대 데이터 전송 개체 (0) | 2023.05.01 |
---|---|
GIT 리포지토리를 한 서버에서 새 서버로 마이그레이션하는 방법 (0) | 2023.05.01 |
재정의에 대한 모범 사례는 동일: 및 해시입니다. (0) | 2023.05.01 |
현재 분기에 커밋되지 않은 변경사항이 있을 때 다른 분기 체크아웃 (0) | 2023.05.01 |
올바른 Bash 및 셸 스크립트 변수 대문자화 (0) | 2023.05.01 |