Okay so I'm trying to get data from Web API that I made in angular. Web API is working I tested it using Postman and Postman gets the data from Web API just fine here is the screenshot of Postman getting the data from Web API " http://prntscr.com/nr18ct ". That makes me certain that it is a problem with angular. And I'm sorry if I don't make sense or if the rest of the question / post is f**ed up first time asking a question here.
I did follow angular tutorial on Angular.io I really don't know what it could cause it, just to say it worked perfectly fine before I did the last part of the tutorial, that is trying to get data from Web API. My first thought was maybe I f**ed up something in PagedVehicleMake class in angular (typescript class) or VehicleMake class also in angular also typescript class
Web API part:
As you saw in the screen shot I sent before Web API sends that type of data.
public class PagedResult<T> : IPagedResult<T> where T : class
{
public int PageNumber { get; set; }
public int PageSize { get; set; }
public int TotalNumberOfPages { get; set; }
public IEnumerable<T> Results { get; set; }
}
and IEnumrable Results in this case is IEnumrable Results
and VehicleMakeVM is:
public class VehicleMakeVM
{
public int Id { get; set; }
public string Name { get; set; }
public string Abrv { get; set; }
}
Now for Angular part:
export class PagedVehicleMake{
Results : VehicleMake[];
TotalNumberOfPages : number;
PageSize : number;
PageNumber : number;
}
I tried to arrange PagedVehicleMake class the same way data is sent to Postman showed in a screenshot I sent. I thought maybe it had something to do with that.
export class VehicleMake {
Id : number;
Name : string;
Abrv : string;
}
and here is the VehicleMakeService class in angular:
export class VehicleMakeService {
constructor(private http: HttpClient, private messageService : MessageService) { }
private vehiclemakesUrl = "http://localhost:53282/api/VehicleMake"
/**GET vehiclemakes from the server */
getVehicleMakes() : Observable<PagedVehicleMake>{
this.messageService.add("VehicleMakeService : fetched VehicleMakes")
return this.http.get<PagedVehicleMake>(this.vehiclemakesUrl).pipe(
catchError(this.handleError<PagedVehicleMake>("getVehicleMakes", []))
);
}
/**
* Handle Http operation that failed.
* Let the app continue.
* #param operation - name of the operation that failed
* #param result - optional value to return as the observable result
*/
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// TODO: better job of transforming error for user consumption
this.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
/** Log a VehicleMakeService message with the MessageService */
private log(message: string) {
this.messageService.add(`VehicleMakeService: ${message}`);
}
I expected it to just get the data from WebAPI but it somehow isn't capable of getting the data.
I figured out what was the problem. It was WebAPI actually I forgot to enable CORS, that's all.
Related
I search in google and here but I got weird case.
I need to make an API, what get data from another service where I paste links to my API.
Links should be that:
1: https://myAPI/xxx/xxxx/optincallbackurl.php?email=$email$&key=sha1($email$security_parameter)
2: https://myAPI/xxx/xxxx/optincallbackurl.php?email=$email$&key=sha1($email$security_parameter)
Service in 2 options send me an email. How receive this data? Normal POST method API in c# should work for that callback?
I ask for advice how to make receiver from URI, I resolve my problem code below.
public class Kontakt
{
public string kEmail { get; set; }
}
public class optoutcallbackurlController : ApiController
{
public void Post([FromUri]string email)
{
Kontakt kontakt = new Kontakt();
kontakt.kEmail = email;
}
}
Now I got link like myAPI/conroler?email="email.test#gmail.com" and I receive email from URI to my API.
Thanks, I am developing one rest API in Dot.Net core. I need to secure my API calls while accessing.
I have 10 rest API calls, here few of them,
ValidateUser,
UploadDocument
VerifyDocument
ApproveDocument
EligibleForPersonalLoan.
The order of these calls should be sequential order, what bulleted above
Example: 1 -> 2 -> 3 -> 4 -> 5 -> 6.
if byepasser make a call request "2.UploadDocument" after the "5. EligibleForPersonalLoan" call, and this request is wrong and in this scenario the user has byepassed two calls(3 and 4), so here i want to return 'invalid request' error message. So how to handle this scenario.
You could easily managed it by introducing a new enum called "LoanStatus"
public class Loan
{
public long Id { get; set; }
public virtual User User{ get; set; }
public virtual List<Document> Documents{ get; set; }
public LoanStatus LoanStatus{ get; set; }
}
public enum LoanStatus
{
UserValidated,
DocumentUploaded,
DocumentVerified,
DocumentApproved,
LoanEligibility...
}
Each time a WebApi is called you check the LoanStatus property and see if it's in the expected status otherwise you throw a forbidden request.
If the status is the one expected you do all your logic and then you change the status of the entity.
[HttpGet]
[Route("verifydocument/{loadId:long}")]
public IHttpActionResult VerifyDocument(long loadId)
{
try
{
var loan= _loanService.FindLoanById(loadId);
if (loan.LoanStatus!=null && loan.LoanStatus.Equals(LoanStatus.DocumentUploaded)
//Do logic for the verifyDocument and update the LoanStatus to DocumentVerified
{
return Ok(loanUpdated);
}
return Forbid();
}
catch (Exception exception)
{
return InternalServerError(exception);
}
}
I am trying to create Payment Gateway abstraction, for one of my projects using Asp.Net Core, so that clients can integrate their payment gateways, by creating derived libraries. My application will load the derived libraries and call the methods.
Below is an interface that all payment gateways must implement. This lies in the Core library, let's call it PaymentGateway.Core.dll. This library is part of the main application.
namespace PaymentGateway.Core
{
public interface IPaymentGateway
{
string Name { get; }
// The purpose of this function is to transform the order details into an object,
// as expected by the underlying gateway's apis
object CreatePaymentRequest(Order request);
// The purpose of this function is to transform the payment response object,
// received from the payment gateway api,
// into an application entity that represents this payment.
Payment ProcessPaymentResponse(object response);
}
// Order for which the payment to be collected. This entity is stored in DB
public class Order
{
string UserId { get; set; }
string ProductId { get; set; }
double OrderTotal { get; set; }
}
// A payment attempted for an Order. This entity is stored in DB
public class Payment
{
Order Order { get; set; }
string PaymentGateway { get; set; }
double Amount { get; set; }
PaymentStatus Status { get; set; } // Failed, User Aborted, Success
}
}
Below is an example of PayPal integration library, let's call it PaymentGateway.PayPal.dll. This library references the core library and implements the PaymentGateway interface.
namespace PaymentGateway.PayPal
{
class PayPal : IPaymentGateway
{
public string Name { get => "PayPal"; }
public object CreatePaymentRequest(Order request)
{
:
:
}
public Payment ProcessPaymentResponse(object response)
{
:
:
}
}
}
The process flow in the core library to execute a payment would be like :
The buyer clicks on the PayPal button on the webpage.
The core application then initializes the PayPal object.
The core application then calls the CreatePaymentrequest() function with the order details. The function will transform the order details into PayPal Payment Request format.
The returned data is passed to PayPal apis to initiate a transaction.
After PayPal api finishes, it returns the response in a its defined format.
The response from PayPal api is passed to the server, which calls ProcessPaymentResponse() on the PayPal object. This function transform the response into Payment object.
The problem i have is that the application ( Core ) doesn't understand the return type of CreatePaymentRequest(), as it is depends on the called gateway. Similarly, for ProcessPaymentResponse() the argument type is gateway specific and the type will be defined in the gateway library.
For now i am forced to use System.Object. Is there any better solution to the problem ?
public interface IPaymentGateway<T> where T : class
{
string Name { get; }
T CreatePaymentRequest(PaymentRequest request);
PaymentResponse ProcessPaymentResponse(T response);
}
public class PayPal<T> : IPaymentGateway<T> where T : class
{
public string Name { get; }
public T CreatePaymentRequest(PaymentRequest request)
{
throw new NotImplementedException();
}
public PaymentResponse ProcessPaymentResponse(T response)
{
throw new NotImplementedException();
}
}
public class Example
{
public void ExampleMethod()
{
IPaymentGateway<Foo> paypal = new PayPal<Foo>();
var name = paypal.Name;
Foo paymentRequest = paypal.CreatePaymentRequest(new PaymentRequest());
var paymentResponse = paypal.ProcessPaymentResponse(new Foo());
}
}
public class Foo
{
}
public class PaymentResponse
{
}
public class PaymentRequest
{
}
Instead of returning an object why not make it generic and have them pass in the type?
I am building a REST API using .net WEB API.
Here is a sample code
public class ValuesController : ApiController
{
// GET api/values
public Values Get(int ID, int userID)
{
return new Values(){};
}
}
Now what I want to do is return a different class if userID is not in allowed userID list. I was thinking of throwing an exception, but after I considered it I don't think that would be a good idea. Reason for this is that process was handled with OK status.
Basically I would like to return a custom ErrorMessage object instead of Values object. Is it possible to do it?
IMO throwing an exception is valid when the flow of your code encounters an abnormal situation.
If you still dont want to throw, you can create a wrapper class that describes your result:
public class ValueResponse
{
public HttpStatusCode HttpStatus { get; set; }
public string ErrorMessage { get; set; }
public Values Values { get; set; }
}
and return that object
public class ValuesController : ApiController
{
// GET api/values
public ValueResponse Get(int ID, int userID)
{
// Send a valid response or an invalid with the proper status code
}
}
I am attempting to get ServiceStack to return a list of objects to a C# client, but I keep getting this exception:
"... System.Runtime.Serialization.SerializationException: Type definitions should start with a '{' ...."
The model I am trying to return:
public class ServiceCallModel
{
public ServiceCallModel()
{
call_uid = 0;
}
public ServiceCallModel(int callUid)
{
this.call_uid = callUid;
}
public int call_uid { get; set; }
public int store_uid { get; set; }
...... <many more properties> ......
public bool cap_expense { get; set; }
public bool is_new { get; set; }
// An array of properties to exclude from property building
public string[] excludedProperties = { "" };
}
The response:
public class ServiceCallResponse
{
public List<ServiceCallModel> Result { get; set; }
public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized
}
And the service:
public class ServiceCallsService : Service
{
// An instance of model factory
ModelFactory MyModelFactory = new ModelFactory();
public object Any(ServiceCallModel request)
{
if (request.call_uid != 0)
{
return MyModelFactory.GetServiceCalls(request.call_uid);
} else {
return MyModelFactory.GetServiceCalls() ;
}
}
}
The client accesses the service with:
JsonServiceClient client = new ServiceStack.ServiceClient.Web.JsonServiceClient("http://172.16.0.15/");
client.SetCredentials("user", "1234");
client.AlwaysSendBasicAuthHeader = true;
ServiceCallResponse response = client.Get<ServiceCallResponse>("/sc");
The "model factory" class is a DB access class which returns a list. Everything seems to work just fine when I access the service through a web browser. The JSON returned from the service starts:
"[{"call_uid":70...."
And ends with:
"....false,"is_new":true}]"
My question is, what here might be causing serialization/deserialization to fail?
Solution
Thanks to the answer from mythz, I was able to figure out what I was doing wrong. My misunderstanding was in exactly how many DTO types there are and exactly what they do. In my mind I had them sort of merged together in some incorrect way. So now as I understand it:
Object to return (In my case, called "ServiceCallModel": The actual class you wish the client to have once ServiceStack has done its job. In my case, a ServiceCallModel is a key class in my program which many other classes consume and create.
Request DTO: This is what the client sends to the server and contains anything related to making a request. Variables, etc.
Response DTO: The response that the server sends back to the requesting client. This contains a single data object (ServiceCallModel), or in my case... a list of ServiceCallModel.
Further, exactly as Mythz said, I now understand the reason for adding "IReturn" to the request DTO is so the client will know precisely what the server will send back to it. In my case I am using the list of ServiceCallModel as the data source for a ListView in Android. So its nice to be able to tell a ListViewAdapter that "response.Result" is in fact already a useful list.
Thanks Mythz for your help.
This error:
Type definitions should start with a '{'
Happens when the shape of the JSON doesn't match what it's expecting, which for this example:
ServiceCallResponse response = client.Get<ServiceCallResponse>("/sc");
The client is expecting the Service to return a ServiceCallResponse, but it's not clear from the info provided that this is happening - though the error is suggesting it's not.
Add Type Safety
Although it doesn't change the behavior, if you specify types in your services you can assert that it returns the expected type, e.g Change object to ServiceCallResponse, e.g:
public ServiceCallResponse Any(ServiceCallModel request)
{
...
}
To save clients guessing what a service returns, you can just specify it on the Request DTO with:
public class ServiceCallModel : IReturn<ServiceCallResponse>
{
...
}
This lets your clients have a more succinct and typed API, e.g:
ServiceCallResponse response = client.Get(new ServiceCallModel());
instead of:
ServiceCallResponse response = client.Get<ServiceCallResponse>("/sc");
See the New API and C# Clients docs for more info.