2017-09-06 1 views
2

내 컨트롤러가 dd/MM/yyyy 날짜를 받으면 MM/dd/yyyy로 디코드합니다. 컨트롤러에게 URL 매개 변수를 디코드하는 방법을 알려주는 것이 가능합니까? 컨트롤러웹 API - 컨트롤러 DateTime ('dd/MM/yyyy')을 Url 매개 변수로받는 방법?

내 방법 :

[HttpGet] 
public JsonResult<IList<Callers>> GetListOfCallers(DateTime startDate, DateTime endDate) 
     { 
      // myCode.... 
     } 

내 자바 스크립트 : 나는 그것을 구문 분석, 또는 ISO8601 내 자바 스크립트에서 변경 한 후 문자열로 컨트롤러에 날짜를받을 수 있습니다 알고

var $startDate = $('#startDate').val(); 
var $endDate = $('#endDate').val(); 

$.get(rootUrl + "api/report/GetListOfCallers?startDate=" + $startDate + "&endDate=" + $endDate, function (data) { 
       // myCode.... 
      }); 

url을 넣기 전에, 나는받은 매개 변수를 디코딩하는 방법을 컨트롤러에 알릴 수 있는지 알고 싶다.

EDIT : 저는 MVC 컨트롤러를 사용하고 있었지만 문제가되지 않았습니다. ApiController로 변경 한 후 잘못 디코딩을 시작 했으므로 코드가 작동하고 그대로 유지하려고합니다.

+0

나는 문자열을 날짜로 변환해야한다고 믿고, 문자열을 날짜로 디코딩하는 과정에서 원하는대로 사용자 정의 할 수 있습니다. –

+1

모델 바인딩이 친구입니다. 여기에 귀하의 질문과 관련된 주제에 대한 내 인터넷 검색 결과가 나와 있습니다. http://www.vickram.me/custom-datetime-model-binding-in-asp-net-web-api/ – Jakotheshadows

+0

나는 사용자 정의 모델 바인딩이 여기에 갈 길이라는 데 동의한다. – Amy

답변

2

@ Jakotheshadows 및 @Amy에서 제안한 모델 바인딩을 사용하여 문제를 해결할 수 있습니다.

this answer (웹 사이트는 포르투갈어이지만 코드는 분명합니다.)의 몇 가지 조정 사항을 사용하여 ModelBinders about this answer의 코드를 Web API에 사용했습니다.

그래서 지금 내 코드 : 두 번째 링크에 제시된 바와 같이, 제 1 항상 심지어 시도 및 캐치와 예외를 throwed 때문에

using System; 
using System.Web.Http.Controllers; 
using System.Web.Http.ModelBinding; 

namespace Site.Services 
{ 
    public class DateTimeModelBinder : IModelBinder 
    { 
     public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
     { 
      ValidateBindingContext(bindingContext); 

      if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName) || 
       !CanBindType(bindingContext.ModelType)) 
      { 
       return false; 
      } 

      var modelName = bindingContext.ModelName; 
      var attemptedValue = bindingContext.ValueProvider 
       .GetValue(modelName).AttemptedValue; 

      try 
      { 
       bindingContext.Model = DateTime.Parse(attemptedValue); 
      } 
      catch (FormatException e) 
      { 
       bindingContext.ModelState.AddModelError(modelName, e); 
      } 

      return true; 
     } 

     private static void ValidateBindingContext(ModelBindingContext bindingContext) 
     { 
      if (bindingContext == null) 
      { 
       throw new ArgumentNullException("bindingContext"); 
      } 

      if (bindingContext.ModelMetadata == null) 
      { 
       throw new ArgumentException("ModelMetadata cannot be null", "bindingContext"); 
      } 
     } 

     public static bool CanBindType(Type modelType) 
     { 
      return modelType == typeof(DateTime) || modelType == typeof(DateTime?); 
     } 
    } 
} 

나는, tryDateTime.Parse을 사용했다. 그가 제안

ModelBinderProvider 내가 사용 :

using System; 
using System.Web.Http; 
using System.Web.Http.ModelBinding; 

namespace Site.Services 
{ 
    public class DateTimeModelBinderProvider : ModelBinderProvider 
    { 
     readonly DateTimeModelBinder binder = new DateTimeModelBinder(); 

     public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType) 
     { 
      if (DateTimeModelBinder.CanBindType(modelType)) 
      { 
       return binder; 
      } 

      return null; 
     } 
    } 
} 

을 그리고 here (첫 번째 링크도 대답을) 제안 구성,하지만 내 WebApiConfig.cs (Global.asax에서 작동하지 않았다), 이런 식의 :

using Site.Services; 
using System; 
using System.Web.Http; 

namespace Site 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      config.BindParameter(typeof(DateTime), new DateTimeModelBinder()); 
      config.BindParameter(typeof(DateTime?), new DateTimeModelBinder()); 

      //Rest of my code 
      config.MapHttpAttributeRoutes(); 

      config.Routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "api/{controller}/{action}/{id}", 
       defaults: new { id = RouteParameter.Optional } 
      ); 
     } 
    } 
} 

은 내가 Web.configglobalizationuiCultureculture 당신이 원하는 문화와 enableClientBasedCulture로 설정해야합니다 생각 true으로 설정해야합니다. here을 제안하지만, 테스트를 위해 코드를 변경하고 싶지 않았기 때문에 확실하지 않습니다.

관련 문제