2014-04-14 5 views
1

웹 API에서 복잡한 유형을 시작하기 시작했습니다. 나는 기본 포맷이 작업 아무 문제가 없어야합니다 간단한 클래스 생성 :복잡한 유형의 배열을 웹 API 메서드에 전달

public class GridColumnArgs 
{ 
    public GridColumnArgs() { } 

    public int FieldID { get; set; } 
    public bool Visible { get; set; } 
} 

을 그리고 GridColumnArgs 소요 웹 API 방법 설정 :

public void PutGridLevel(int gridLevelID, GridColumnArgs columnArgs) 
{ 
    // my breakpoint is set here 
} 

그리고 자바 스크립트를 간단한 테스트를했다 방법 :

var columnArgs = { FieldID: 1, Visible: true }; 
myHelperLibrary.put({ 
    url: 'api/grid?gridLevelID=123', 
    obj: columnArgs, 
    done: function() { alert('ok!') }, 
    fail: function() { alert('no good!') } 
}); 

완벽하게 작동합니다. 중단 점에 도달하면 JavaScript 객체 리터럴에 설정된 내 속성이 훌륭합니다.

그러나 이러한 GridColumnArgs 개체의 컬렉션을 전달해야합니다. 내가 thusly 히 내 웹 API 방식 변경한다면 :

public void PutGridLevel(int gridLevelID, GridColumnArgs[] columnArgs) 
{ 
    // my breakpoint is set here 
} 

을 그리고 같은 내 테스트 자바 스크립트를 조정합니다

var columnArgs = [ 
    { FieldID: 1, Visible: true }, 
    { FieldID: 2, Visible: false } 
]; 

myHelperLibrary.put({ 
    url: 'api/grid?gridLevelID=123', 
    obj: columnArgs, 
    done: function() { alert('ok!') }, 
    fail: function() { alert('no good!') } 
}); 

호출이 작동하지 않습니다. 라우팅 작업 - 중단 점에 도달했습니다. 그러나 매개 변수는 빈 배열입니다.

분명히 기본 서식 지정자는 단일 복합 유형과 마찬가지로 복잡한 유형의 배열을 사용하여 쉽게 작업 할 수 없습니다.

이 문제를 해결하기 위해 사용자 지정 미디어 포맷터 작성과 관련된 몇 가지 답변과 기사를 읽었지만 기본 미디어 포맷터가 이미 알고있는 일련의 개체를 수락하는 데 많은 어려움이있는 것 같습니다. 함께 일해 ...이 일을하는 가장 빠른 방법은 무엇입니까?

도움 주셔서 대단히 감사합니다.

답변

0

매개 변수에서 JObject를 사용하고 Json.NET을 사용하여 배열을 구문 분석하는 작업 솔루션이 있습니다. 나는 여전히 개체를 실제로 인스턴스화하는 기본 기능을 사용할 수 있지만 여전히 너무 많은 작업과 약해 보입니다 (다른 PUT 경로 등을 지원하려는 경우 자체 오버로딩을 구현해야 함은 물론입니다). 대답은 크게 감사하겠습니다.

클라이언트 측 코드 : 서버에서

var columnArgs = [ 
    { FieldID: 1, Visible: true }, 
    { FieldID: 2, Visible: false } 
]; 

myHelperLibrary.put({ 
    url: 'api/grid?gridLevelID=123', 
    obj: { columns: columnArgs }, 
    done: function() { alert('ok!') }, 
    fail: function() { alert('no good!') } 
}); 

:

public void PutGridLevel(int gridLevelID, JObject json) 
{ 
    var jprop = json.Properties().FirstOrDefault(p => p.Name.Equals("columns", StringComparison.OrdinalIgnoreCase)); 
    if (jprop == null) 
     throw new ArgumentException("The parameter object must contain an array property called \"columns\"."); 
    var columns = jprop.Value.ToArray().Select(obj => obj.ToObject<GridColumnArgs>()); 

// etc... 
} 
1

이것이 도움이되는지 확실하지 않지만 속성을 추가해볼 수 있습니다.

[JsonProperty("FieldID")] 
public int FieldID { get; set; } 

또는

public void PutGridLevel(int gridLevelID, dynamic columnArgs) 

가능한 유형의 문제를 제거하기 위해 변경합니다. 그것은 동적 유형 대신 'var'또는 try 'object'가 정확하게 다시 호출 할 수 없으며 VS atm에서 확인할 수 없습니다.

+0

은'JsonPropertyAttribute' 대부분 유용 때 JSON 속성 다릅니다 이름에서 C# 속성보다. 기본적으로 C# 속성 이름을 사용하여 매핑합니다. –

+0

아이디어 LIUFA 주셔서 감사하지만,이 문제를 해결하지 못했습니다. –

+0

동적으로 매개 변수를 변경하는 두 번째 제안을 시도했습니다. 도착한 매개 변수는 "개체"이지만 아무 것도 할 수없는 것처럼 보입니다. ExpandoObject, Array 또는 IEnumerable로 캐스팅하지 않으며 Length 또는 Count 속성을 갖지 않습니다. –

1

나는 웹 API 복잡한 객체 유형을 결합하는 또 다른 대안을 발견했다. 요청 본문을 문자열로 읽은 다음 JSON.NET을 사용하여 필요한 객체 유형으로 역 직렬화하는 모델 바인더를 정의했습니다. 복잡한 객체 유형의 배열을 매핑하는 데에도 사용할 수 있습니다.다음과 같이 내가 웹 API 컨트롤러에 사용하고 다음

public class PollRequestModelBinder : IModelBinder 
{ 
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     var body = actionContext.Request.Content.ReadAsStringAsync().Result; 
     var pollRequest = JsonConvert.DeserializeObject<PollRequest>(body); 
     bindingContext.Model = pollRequest; 
     return true; 
    } 
} 

을 그리고 : 다음과 같이

나는 모델 바인더를 추가

public async Task<PollResponse> Post(Guid instanceId, [ModelBinder(typeof(PollRequestModelBinder))]PollRequest request) 
    { 
     // api implementation 
    } 
관련 문제