Skip to content

Commit e2f7e46

Browse files
committed
adding attachment API calls to examples
[otf:9368]
1 parent 76120f4 commit e2f7e46

File tree

2 files changed

+114
-32
lines changed

2 files changed

+114
-32
lines changed

‎WebApp/Controllers/ApiController.cs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ public ActionResult Proxy(string resource)
2525
varOnTime=GetOnTime();
2626

2727
// create the HTTP request
28-
varrequest=WebRequest.Create(OnTime.GetUrl(resource));//using the URL of the specified resource
28+
varurl=OnTime.GetUrl(resource);//using the URL of the specified resource
29+
// forward any query parameters (other than resource)
30+
foreach(stringqueryElementinRequest.QueryString)
31+
if(queryElement!="resource")
32+
url+="&"+HttpUtility.UrlEncode(queryElement)+"="+HttpUtility.UrlEncode(Request.QueryString[queryElement]);
33+
varrequest=WebRequest.Create(url);
2934
request.Method=Request.HttpMethod;// use the same method that was used to make the proxy call
3035
if(string.Compare(Request.HttpMethod,"POST",ignoreCase:true)==0)
3136
{

‎WebApp/Views/Api/Index.cshtml‎

Lines changed: 108 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,37 @@
1111
<optionvalue="POST">POST</option>
1212
</select>
1313
<selectid="api-call-resource">
14-
<optionvalue="v1/projects">api/v1/projects</option>
15-
<optionvalue="v1/projects/{id}">api/v1/projects/{id}</option>
16-
<optionvalue="v1/defects">api/v1/defects</option>
17-
<optionvalue="v1/defects/{id}">api/v1/defects/{id}</option>
18-
<optionvalue="v1/features">api/v1/features</option>
19-
<optionvalue="v1/features/{id}">api/v1/features/{id}</option>
20-
<optionvalue="v1/incidents">api/v1/incidents</option>
21-
<optionvalue="v1/incidents/{id}">api/v1/incidents/{id}</option>
22-
<optionvalue="v1/tasks">api/v1/tasks</option>
23-
<optionvalue="v1/tasks/{id}">api/v1/tasks/{id}</option>
14+
<optgroup>
15+
<optionvalue="v1/projects">api/v1/projects</option>
16+
<optionvalue="v1/projects/{id}">api/v1/projects/{id}</option>
17+
<optionvalue="v1/releases">api/v1/releases</option>
18+
<optionvalue="v1/releases/{id}">api/v1/releases/{id}</option>
19+
<optionvalue="v1/users">api/v1/users</option>
20+
<optionvalue="v1/users/{id}">api/v1/users/{id}</option>
21+
<optionvalue="v1/customers">api/v1/customers</option>
22+
<optionvalue="v1/customers/{id}">api/v1/customers/{id}</option>
23+
<optionvalue="v1/contacts">api/v1/contacts</option>
24+
<optionvalue="v1/contacts/{id}">api/v1/contacts/{id}</option>
25+
</optgroup>
26+
27+
<optgroup>
28+
<optionvalue="v1/defects">api/v1/defects</option>
29+
<optionvalue="v1/defects/{id}">api/v1/defects/{id}</option>
30+
<optionvalue="v1/features">api/v1/features</option>
31+
<optionvalue="v1/features/{id}">api/v1/features/{id}</option>
32+
<optionvalue="v1/incidents">api/v1/incidents</option>
33+
<optionvalue="v1/incidents/{id}">api/v1/incidents/{id}</option>
34+
<optionvalue="v1/tasks">api/v1/tasks</option>
35+
<optionvalue="v1/tasks/{id}">api/v1/tasks/{id}</option>
36+
</optgroup>
37+
38+
<optgroup>
39+
<optionvalue="v1/defects/{id}/attachments">api/v1/defects/{id}/attachments</option>
40+
<optionvalue="v1/features/{id}/attachments">api/v1/features/{id}/attachments</option>
41+
<optionvalue="v1/incidents/{id}/attachments">api/v1/incidents/{id}/attachments</option>
42+
<optionvalue="v1/tasks/{id}/attachments">api/v1/tasks/{id}/attachments</option>
43+
<optionvalue="v1/attachments/{id}">api/v1/attachments/{id}</option>
44+
</optgroup>
2445
</select>
2546

2647
<spanid="api-call-id-label">id:</span><inputtype="text"id="api-call-id"value="1" />
@@ -32,23 +53,21 @@
3253
</div>
3354
</div>
3455

56+
<divid='api-call-file-container'>
57+
<inputtype="file"id="api-call-file" />
58+
</div>
59+
3560
<div>
3661
<ahref="#"class="btn"id="api-call">Make the API Call</a>
3762
</div>
3863

3964
<div>
4065
<textareaid="api-call-results"disabled="disabled"></textarea>
4166
</div>
42-
43-
44-
<h2>Example Attachment Upload</h2>
45-
<formaction="@Model.GetUrl("attachments")"enctype="multipart/form-data"method="post">
46-
<inputtype="file"name="file"class="input-file" />
47-
<inputtype="submit"value="Upload Attachment"class="btn"/>
48-
</form>
4967
</div>
5068

5169
<scripttype="text/javascript">
70+
5271
// hide the id input unless it is needed for the selected API call
5372
var idInputNode =$('#api-call-id'),
5473
resourceInputNode =$('#api-call-resource');
@@ -64,31 +83,53 @@ toggleIdInputNode();
6483
resourceInputNode.change(toggleIdInputNode);
6584
6685
// hide the JSON payload input unless it is needed for the selected API call
86+
87+
functionpostIsAttachmentAdd(){
88+
var resource =resourceInputNode.val();
89+
returnresource.indexOf('{id}/attachments') !==-1;
90+
}
91+
6792
var methodInputNode =$('#api-call-method');
6893
6994
functiontogglePayloadInputNode(){
70-
// we show the payload input node if the method is POST
71-
var showPayloadInputNode =methodInputNode.val() ==='POST';
95+
// we show the payload input node if the method is POST, but not for attachment adds
96+
var showPayloadInputNode =methodInputNode.val() ==='POST'&&!postIsAttachmentAdd();
7297
$('#api-call-payload-container').toggle(showPayloadInputNode);
98+
99+
// show the file input node if the method is POST, and it is an attachment add
100+
var showFileInputNode =methodInputNode.val() ==='POST'&&postIsAttachmentAdd();
101+
$('#api-call-file-container').toggle(showFileInputNode);
73102
}
74103
75104
togglePayloadInputNode();
76105
methodInputNode.change(togglePayloadInputNode);
106+
resourceInputNode.change(togglePayloadInputNode);
77107
78108
// show example JSON payloads
79109
var payloadInputNode =$('#api-call-payload');
80110
81111
var jsonPayloadExamples ={
82-
"v1/projects":'{\n name : "Project Created from API Explorer"\n}',
83-
"v1/projects/{id}":'{\n name : "Project Renamed from API Explorer"\n}',
84-
"v1/defects":'{\n item:{\n name : "Defect Created from API Explorer",\n project:{id: 1 }\n }\n}',
85-
"v1/defects/{id}":'{\n item:{\n name : "Defect Renamed from API Explorer"\n }\n}',
86-
"v1/features":'{\n item:{\n name : "Feature Created from API Explorer",\n project:{id: 1 }\n }\n}',
87-
"v1/features/{id}":'{\n item:{\n name : "Feature Renamed from API Explorer"\n }\n}',
88-
"v1/incidents":'{\n item:{\n name : "Incident Created from API Explorer",\n project:{id: 1 }\n }\n}',
89-
"v1/incidents/{id}":'{\n item:{\n name : "Incident Renamed from API Explorer"\n }\n}',
90-
"v1/tasks":'{\n item:{\n name : "Task Created from API Explorer",\n project:{id: 1 }\n }\n}',
91-
"v1/tasks/{id}":'{\n item:{\n name : "Task Renamed from API Explorer"\n }\n}'
112+
"v1/projects":'{\n name : "Project Created from API Explorer"\n}',
113+
"v1/projects/{id}":'{\n name : "Project Renamed from API Explorer"\n}',
114+
"v1/releases":'{\n name : "Release Created from API Explorer",\n release_type:{id : 1 }\n}',
115+
"v1/releases/{id}":'{\n name : "Release Renamed from API Explorer"\n}',
116+
"v1/users":'{\n login_id : "ApiExplorer",\n first_name : "API",\n last_name : "Explorer",\n security_roles : [ 1 ]\n}',
117+
"v1/users/{id}":'{\n first_name : "Renamed"\n}',
118+
"v1/customers":'{\n company_name : "Customer Created from API Explorer"\n}',
119+
"v1/customers/{id}":'{\n company_name : "Customer Renamed from API Explorer"\n}',
120+
"v1/contacts":'{\n first_name : "API",\n last_name : "Explorer",\n customer_id : 1\n}',
121+
"v1/contacts/{id}":'{\n first_name : "Renamed"\n}',
122+
123+
"v1/defects":'{\n item:{\n name : "Defect Created from API Explorer",\n project :{id : 1 }\n }\n}',
124+
"v1/defects/{id}":'{\n item:{\n name : "Defect Renamed from API Explorer"\n }\n}',
125+
"v1/features":'{\n item:{\n name : "Feature Created from API Explorer",\n project :{id : 1 }\n }\n}',
126+
"v1/features/{id}":'{\n item:{\n name : "Feature Renamed from API Explorer"\n }\n}',
127+
"v1/incidents":'{\n item:{\n name : "Incident Created from API Explorer",\n project :{id : 1 }\n }\n}',
128+
"v1/incidents/{id}":'{\n item:{\n name : "Incident Renamed from API Explorer"\n }\n}',
129+
"v1/tasks":'{\n item:{\n name : "Task Created from API Explorer",\n project :{id : 1 }\n }\n}',
130+
"v1/tasks/{id}":'{\n item:{\n name : "Task Renamed from API Explorer"\n }\n}',
131+
132+
"v1/attachments/{id}":'{\n description : "Description Updated from API Explorer"\n}'
92133
};
93134
94135
$('#api-call-payload-example').click(function(event){
@@ -98,6 +139,28 @@ $('#api-call-payload-example').click(function(event){
98139
payloadInputNode.val(jsonPayloadExamples[resource]);
99140
});
100141
142+
// when a file is selected, load it in using FileReader
143+
var fileInputNode =$('#api-call-file');
144+
var loadedFile;
145+
146+
fileInputNode.change(function(){
147+
loadedFile =null;
148+
var file =fileInputNode.get(0).files[0];
149+
150+
var reader =newFileReader();
151+
reader.onload=function(fileData){
152+
loadedFile ={
153+
data:reader.result,
154+
name:file.name,
155+
};
156+
};
157+
reader.onerror=function(){
158+
alert(reader.error);
159+
};
160+
161+
reader.readAsBinaryString(file);
162+
});
163+
101164
// process API calls
102165
103166
functiondisplayCallResults(jqXHR){
@@ -115,6 +178,9 @@ function displayCallResults(jqXHR){
115178
$('#api-call').click(function(event){
116179
event.preventDefault();
117180
181+
// clear the results
182+
$('#api-call-results').val('');
183+
118184
// compose the url, substituting the id if needed
119185
var url ='@(Url.Action("Proxy"))?resource='+resourceInputNode.val();
120186
url =url.replace('{id}', idInputNode.val());
@@ -134,11 +200,22 @@ $('#api-call').click(function(event){
134200
135201
// send the data if POSTing
136202
if(method ==='POST'){
137-
settings.contentType='application/json';
138-
settings.data=payloadInputNode.val();
203+
if(postIsAttachmentAdd()){
204+
// we can add an attachment by posting a form the contents in the request as an octet-stream,
205+
// and passing the rest of the parameters in the URL
206+
settings.contentType='application/octet-stream';
207+
settings.data=loadedFile.data;
208+
url = url +'&file_name='+encodeURIComponent(loadedFile.name);
209+
}
210+
else{
211+
// for all other request, we post a json object
212+
settings.contentType='application/json';
213+
settings.data=payloadInputNode.val();
214+
}
139215
}
140216
141217
// make the call to the Proxy action, which will forward the call to the OnTime API
142218
$.ajax(url, settings);
219+
143220
});
144221
</script>

0 commit comments

Comments
(0)