I have implemented a service which has some get, post, update and delete methods.
I want to make this service restful.
Here is my service code.
public class TestAppService : MyProjectAppServiceBase, ITestAppService
{
public async Task CreateTest(TestDetailsDto input)
{
}
public PagedResultDto<FetchTestDetails> GetSearchTest(FetchTestDetails searchInput)
{
}
public TestDetailsDto GetTestDetailsForEdit(EntityDto input)
{
}
public async Task UpdateTest(TestDetailsDto input)
{
}
public async Task DeleteTest(EntityDto input)
{
}
public ListResultDto<FetchTestDetails> GetAllCurrencies()
{
}
}
so instead of >http://localhost:22742/api/services/app/Test/GetTestDetailsForEdit?Id=1 url should be something like >http://localhost:22742/api/services/app/Currency?Id=1 for get api.
for >http://localhost:22742/api/services/app/Test/CreateTest it should be something like >http://localhost:22742/api/services/app/Test for post api.
for> <a class="postlink" href="http://localhost:22742/api/services/app/Test/DeleteTest?Id=1">http://localhost:22742/api/services/app ... eTest?Id=1</a> it should be >http://localhost:22742/api/services/app/Test?Id=1
20 Answer(s)
-
0
From the ASP.NET Core documentation's Application Services as Controllers section:
You can use any ASP.NET Core attributes to change the HTTP methods or routes of the actions. This requires you to add a reference to the Microsoft.AspNetCore.Mvc.Core package.
[HttpPost("api/services/app/Test")] public async Task CreateTest(TestDetailsDto input)
-
0
I tried with all method, I'm able to run the server-side code. But when I run Refresh.bat file. and then run npm start. It gives the following error. so I think the reason could be that Swagger is not able to differentiate between these methods.
I tried the below code.
[HttpPost("api/services/app/Test")] public async Task CreateTest(TestDetailsDto input) [HttpDelete("api/services/app/Test")] public async Task DeleteTest(EntityDto input) [HttpGet("api/services/app/Test")] public async Task GetTest(EntityDto input) [HttpPut("api/services/app/Test")] public async Task UpdateTest(TestDetailsDto input)
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6197,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6230,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6252,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6267,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6281,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6300,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6315,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6329,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6351,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6370,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6384,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/Tests/Test-list.component.ts (210,45): Property 'deleteTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/Tests/Test-main.component.ts (63,37): Property 'getTestDetailsforEdit' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/Tests/Test-main.component.ts (107,37): Property 'createTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/Tests/Test-main.component.ts (135,37): Property 'createTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/Tests/Test-main.component.ts (147,37): Property 'updateTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6197,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6230,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6252,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6267,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6281,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6300,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6315,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6329,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6351,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6370,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6384,15): Duplicate function implementation.
Do I need to add some extra configuration? Please help
-
0
I think the reason could be that Swagger is not able to differentiate between these methods.
Try running Web.Host project.
-
0
Yes, Of course I have run the Web.Host project, it running and generating methods.
-
0
So, Swagger is able to differentiate between these methods.
NSwag requires some configuration: <a class="postlink" href="https://github.com/RSuter/NSwag/issues/756">https://github.com/RSuter/NSwag/issues/756</a>
-
0
How to open this configuration UI which is mentioned in the github link provided by you, I'm able to see the only service.config.nswag file with a text "operationGenerationMode": "MultipleClientsFromPathSegments", so what should I set value for "operationGenerationMode" instead of "MultipleClientsFromPathSegments", or do I need to delete this line? Is there any side effect of this?
-
0
Try "MultipleClientsFromOperationId".
I do not know if there is any side effect. Try and you will know. As you already know, ASP.NET Zero does not use that setting.
-
0
@Aaron I agree, But AspNetZero should support restful service because nowadays its must in APIs.
-
0
MultipleClientsFromOperationId not working, giving more than 100 error on npm start. Could you please try the same scenario on your local machine and come up with a proper solution with some test entity, because support for restful service has to be there in abp framework.
-
0
@Aaron any updates?
-
0
Hi,
Can you try this ?
[Route("api/services/app/Test")] [HttpPost] public async Task CreateTest(TestDetailsDto input) [Route("api/services/app/Test")] [HttpDelete] public async Task DeleteTest(EntityDto input) [Route("api/services/app/Test")] [HttpGet] public async Task GetTest(EntityDto input) [Route("api/services/app/Test")] [HttpPut] public async Task UpdateTest(TestDetailsDto input)
It seems like Nswag supports it.
-
0
Hi
Tried, but its also not working.
[Route("api/services/app/Test")] [HttpPost] public async Task CreateTest(TestDetailsDto input) [Route("api/services/app/Test")] [HttpDelete] public async Task DeleteTest(EntityDto input) [Route("api/services/app/Test")] [HttpGet] public async Task GetTest(EntityDto input) [Route("api/services/app/Test")] [HttpPut] public async Task UpdateTest(TestDetailsDto input)
Do I need to make any other change also ?
Giving the following error on npm start.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6197,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6230,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6252,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6267,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6281,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6300,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6315,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6329,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6351,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6370,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6384,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-list.component.ts (210,45): Property 'deleteTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (102,41): Property 'getTestDetailsforEdit' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (163,37): Property 'createTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (206,37): Property 'createTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (218,37): Property 'updateTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6197,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6230,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6252,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6267,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6281,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6300,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6315,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6329,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6351,5): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6370,16): The type argument for type parameter 'R' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'void' is not a valid type argument because it is not a supertype of candidate 'TestDetailsDto'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/shared/service-proxies/service-proxies.ts (6384,15): Duplicate function implementation.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-list.component.ts (210,45): Property 'deleteTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (102,41): Property 'getTestDetailsforEdit' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (163,37): Property 'createTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (206,37): Property 'createTest' does not exist on type 'TestServiceProxy'.
ERROR in C:/Users/MyName/source/repos/MyProject/angular/src/app/merchandising/Tests/Test-main.component.ts (218,37): Property 'updateTest' does not exist on type 'TestServiceProxy'.
-
0
Hi @ManojReddy,
Is it possible for you to share your project via email and let us check this ?
-
0
Any updates please?
-
0
Any updates please?
-
0
Hi,
I have just tried it with ABP's Angular 5 template and it seems like it's working.
Here is the app service and it's interface definition:
public class TestAppService : SwagResterAppServiceBase, ITestAppService { [Route("api/services/app/Test")] [HttpPost] public Task CreateTest(TestDetailsDto input) { throw new NotImplementedException(); } [Route("api/services/app/Test")] [HttpDelete] public Task DeleteTest(EntityDto input) { throw new NotImplementedException(); } [Route("api/services/app/Test")] [HttpGet] public Task GetTest(EntityDto input) { throw new NotImplementedException(); } [Route("api/services/app/Test")] [HttpPut] public Task UpdateTest(TestDetailsDto input) { throw new NotImplementedException(); } } public interface ITestAppService: IApplicationService, ITransientDependency { Task CreateTest(TestDetailsDto input); Task DeleteTest(EntityDto input); Task GetTest(EntityDto input); Task UpdateTest(TestDetailsDto input); } public class TestDetailsDto { }
After doing that, I was able to see below methods on swagger (in the screenshot).
Then, running refresh.bat generated service proxies without an error. Only thing is method names are testPut, testPost, testGet and testDelete.
-
0
Hi @ismcagdas,
Thanks for your help.
I tried the exact step mentioned by you, But still, I'm getting the >Duplicate function implementation error. Do I need to make any other changes also?
Below is the generated service-proxies.ts file.
export class AppServiceProxy { { private http: Http; private baseUrl: string; protected jsonParseReviver: (key: string, value: any) => any = undefined; constructor(@Inject(Http) http: Http, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { this.http = http; this.baseUrl = baseUrl ? baseUrl : ""; } /** * @return Success */ test(id: number): Observable<void> { let url_ = this.baseUrl + "/api/services/app/Test?"; if (id === undefined || id === null) throw new Error("The parameter 'id' must be defined and cannot be null."); else url_ += "Id=" + encodeURIComponent("" + id) + "&"; url_ = url_.replace(/[?&]$/, ""); const content_ = ""; let options_ = { body: content_, method: "get", headers: new Headers({ "Content-Type": "application/json; charset=UTF-8", "Accept": "application/json; charset=UTF-8" }) }; return this.http.request(url_, options_).flatMap((response_) => { return this.processTest(response_); }).catch((response_: any) => { if (response_ instanceof Response) { try { return this.processTest(response_); } catch (e) { return <Observable<void>><any>Observable.throw(e); } } else return <Observable<void>><any>Observable.throw(response_); }); } protected processTest(response: Response): Observable<void> { const status = response.status; if (status === 200) { const responseText = response.text(); return Observable.of<void>(<any>null); } else if (status === 401) { const responseText = response.text(); return throwException("A server error occurred.", status, responseText); } else if (status !== 200 && status !== 204) { const responseText = response.text(); return throwException("An unexpected server error occurred.", status, responseText); } return Observable.of<void>(<any>null); } /** * @return Success */ test(input: NoticeDetailsDto): Observable<void> { let url_ = this.baseUrl + "/api/services/app/Test"; url_ = url_.replace(/[?&]$/, ""); const content_ = JSON.stringify(input ? input.toJSON() : null); let options_ = { body: content_, method: "put", headers: new Headers({ "Content-Type": "application/json; charset=UTF-8", "Accept": "application/json; charset=UTF-8" }) }; return this.http.request(url_, options_).flatMap((response_) => { return this.processTest(response_); }).catch((response_: any) => { if (response_ instanceof Response) { try { return this.processTest(response_); } catch (e) { return <Observable<void>><any>Observable.throw(e); } } else return <Observable<void>><any>Observable.throw(response_); }); } protected processTest(response: Response): Observable<void> { const status = response.status; if (status === 200) { const responseText = response.text(); return Observable.of<void>(<any>null); } else if (status === 401) { const responseText = response.text(); return throwException("A server error occurred.", status, responseText); } else if (status !== 200 && status !== 204) { const responseText = response.text(); return throwException("An unexpected server error occurred.", status, responseText); } return Observable.of<void>(<any>null); } /** * @return Success */ test(input: NoticeDetailsDto): Observable<void> { let url_ = this.baseUrl + "/api/services/app/Test"; url_ = url_.replace(/[?&]$/, ""); const content_ = JSON.stringify(input ? input.toJSON() : null); let options_ = { body: content_, method: "post", headers: new Headers({ "Content-Type": "application/json; charset=UTF-8", "Accept": "application/json; charset=UTF-8" }) }; return this.http.request(url_, options_).flatMap((response_) => { return this.processTest(response_); }).catch((response_: any) => { if (response_ instanceof Response) { try { return this.processTest(response_); } catch (e) { return <Observable<void>><any>Observable.throw(e); } } else return <Observable<void>><any>Observable.throw(response_); }); } protected processTest(response: Response): Observable<void> { const status = response.status; if (status === 200) { const responseText = response.text(); return Observable.of<void>(<any>null); } else if (status === 401) { const responseText = response.text(); return throwException("A server error occurred.", status, responseText); } else if (status !== 200 && status !== 204) { const responseText = response.text(); return throwException("An unexpected server error occurred.", status, responseText); } return Observable.of<void>(<any>null); } /** * @return Success */ test(id: number): Observable<void> { let url_ = this.baseUrl + "/api/services/app/Test?"; if (id === undefined || id === null) throw new Error("The parameter 'id' must be defined and cannot be null."); else url_ += "Id=" + encodeURIComponent("" + id) + "&"; url_ = url_.replace(/[?&]$/, ""); const content_ = ""; let options_ = { body: content_, method: "delete", headers: new Headers({ "Content-Type": "application/json; charset=UTF-8", "Accept": "application/json; charset=UTF-8" }) }; return this.http.request(url_, options_).flatMap((response_) => { return this.processTest(response_); }).catch((response_: any) => { if (response_ instanceof Response) { try { return this.processTest(response_); } catch (e) { return <Observable<void>><any>Observable.throw(e); } } else return <Observable<void>><any>Observable.throw(response_); }); } protected processTest(response: Response): Observable<void> { const status = response.status; if (status === 200) { const responseText = response.text(); return Observable.of<void>(<any>null); } else if (status === 401) { const responseText = response.text(); return throwException("A server error occurred.", status, responseText); } else if (status !== 200 && status !== 204) { const responseText = response.text(); return throwException("An unexpected server error occurred.", status, responseText); } return Observable.of<void>(<any>null); } }
-
0
Hi @ManojReddy,
I have sent you the project I have implemented this. You can compare it with your version. If you cannot solve it, we can try to figure this problem on your project.
-
0
Hi,
Thanks for your reply.
I'm getting the build errors with the code you shared, I have sent you mail regarding the same, please check.
-
0
Hi,
We have replied your email. We can continue on email and we can write the result here if we can find a solution.