programing

datetime 매개 변수를 전달하는 방법은 무엇입니까?

abcjava 2023. 5. 1. 19:48
반응형

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="&lt;,&gt;,%,&amp;,*,\,?" />제가 제거했습니다.:유효하지 않은 문자의 표준 목록에서.

더 쉽고 안전한 솔루션

질문에 대한 답변은 아니지만, 이 모든 것이 필요하지 않도록 요청을 변경하는 것이 더 안전하고 쉬운 해결책이 될 것입니다.이 작업은 두 가지 방법으로 수행할 수 있습니다.

  1. 날짜를 쿼리 문자열 매개 변수로 전달(예:?date=2012-12-31T22:00:00.000Z.
  2. 를 ..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

반응형