I'm fairly new to programming an C# and i need to create a web application project. I have been told that a website will navigate to my web application and send an ID. My web application then needs to use this ID within a SOAP request. The responce then needs to be evaluated and if it fits a criteria, the web application can load or else just throws an exception.
I can code all the application except grabbing the initial ID and setting up a SOAP request and recieve. I have all the relevant information, i just don't know how to set up the SOAP request/responce.
Best Regards
Assuming you are using a WCF, it uses SOAP by default, so if you have everything setup correctly, it will automatically serialize and deserialize for you.
[OperationContract]
MyResponse ParseId(MyRequest req);
MyResponse can hold response information
MyRequest can hold request information
Implementation could be like this:
public MyResponse ParseId(MyRequest req)
{
if(req.Id == null)
{
//Error
}
else
{
}
}
If it is really simple, you can do something like this:
[OperationContract]
void ParseId(int id);
Implementation:
public void ParseId(int id)
{
if(id == null)
{
//throw exception;
}
else
{
}
}
Don't forget to decorate your MyResponse class and MyRequest class with DataContract attributes.
Related
Let me start by saying I love the design of ServiceStack as a client. (I've never used it for server side)
I'm writing a C# wrapper for API calls and I keep getting timeout and authentication errors. I've contacted the developers at the other end and they assure me that there are no issues on their end and that I must be doing something wrong. Normally I wouldn't believe them and I'd build a sample project to demonstrate the issue but in this case they pointed me to a web page that will test the same API I'm running in C# and they can re-authenticate as fast as they can click the submit button. I forget the exact site they use for testing but enough of my story... I'm sure I'm doing something wrong I just don't know what.
Here's my Unit Test. If I run it by itself or with one copy it works fine (150-1100ms) but if I make 3 or more copies of it they I will get only 2-3 that pass and the rest will timeout.
[TestMethod]
[Timeout(5000)]
public void Login_Success1()
{
var client = new JsonServiceClient("apiurl");
var response = client.Login("XXXAccessKeyXXX", "XXXSecretKeyXXX");
//Assertions
}
This is my extension method:
public static class Extensions
{
public static (bool Success, string Message, string Token) Login(this JsonServiceClient client, string accessKey, string secretKey)
{
try
{
var response = client.Post(new LoginRequest(accessKey, secretKey));
var authorization = response.Headers.GetValues("Authorization")[0];
return (true, string.Empty, authorization);
}
catch (Exception ex)
{
return (false, $"Authentication failed: {ex.Message}", string.Empty);
}
}
}
And here's the login request:
[Route("/sessions")]
[DataContract]
internal class LoginRequest
{
internal LoginRequest(string accessKey, string secretKey)
{
AccessKey = accessKey ?? throw new ArgumentNullException(nameof(accessKey));
SecretKey = secretKey ?? throw new ArgumentNullException(nameof(secretKey));
}
[DataMember(Name = "accessKey")]
internal string AccessKey { get; set; }
[DataMember(Name = "secretKey")]
internal string SecretKey { get; set; }
}
I think this is all the relevant code but if you feel I missed something please lmk.
Your Request DTO's should implement either IReturn<T> or IReturnVoid otherwise if you're sending just an object you will call the deprecated Post() method:
/// <summary>
/// APIs returning HttpWebResponse must be explicitly Disposed, e.g using (var res = client.Post(url)) { ... }
/// </summary>
[Obsolete("Use: using (client.Post<HttpWebResponse>(requestDto) { }")]
public virtual HttpWebResponse Post(object requestDto)
{
return Send<HttpWebResponse>(HttpMethods.Post, ResolveTypedUrl(HttpMethods.Post, requestDto), requestDto);
}
Which because ServiceStack doesn't know how you want the Response deserialized it will return the open HttpWebResponse so you can inspect the Response yourself (as you're doing in your example). But this needs to be explicitly disposed as .NET's HttpWebRequest only allows a couple of concurrent requests open per domain which will cause your App to hang/timeout as it's waiting for Requests to be disposed to stay within the concurrent limit.
The preferred solution is to always annotate Request DTO's that you send with ServiceStack clients with a IReturn or a IReturn<T> interface marker, if it has none or you want to ignore the Response implement IReturnVoid otherwise implement IReturn<ResponseDtoType>:
class LoginRequest : IReturnVoid {}
Which instead calls the non-deprecated Post() method which disposes of the HttpWebResponse.
Otherwise if you want to send plain object DTO's you need to dispose of the HttpWebResponse after usage, e.g:
using (var response = client.Post<HttpWebResponse>(new LoginRequest(accessKey, secretKey)))
{
var authorization = response.Headers.GetValues("Authorization")[0];
}
API's which implicitly return HttpWebResponse were deprecated to avoid hard to identify issues like this, instead we recommend using the explicit API above which declares the HttpWebResponse return type at the call-site so it's easier to identify it needs to be disposed.
Also note the ServiceStack Service Clients are opinionated for calling ServiceStack Services, for calling other Services we recommend using HTTP Utils instead.
I have got a WCF service from one of my users. I want to check whether the service is working or not without adding any proxy. Is there any way that I can achieve this in my C# code?
You may achieve this by implementing an endpoint at WCF and querying it from the client.
Following is the WCF code I would use.
// Used for communication between WCF and client. Must be implemented both WCF and client sides
public class Response {
public int Id { get; set; }
public string Data { get; set; }
}
// Web Service - Interface
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
UriTemplate = "Up")]
string CheckLogin();
}
// Web service - Implementation
public class ServiceImplementation : IService
{
public Response isUp()
{
Response response = new Response();
response.ID = 200;
response.Data = "web service is up";
return response;
}
}
Following is the client method to test if the service is up.
public bool CheckIfUp(string encodedUrl)
{
WebRequest request;
WebResponse ws;
Response response = new Response();
string url = "http://servicePath/isUp"; // your wcf url
try
{
request = WebRequest.Create(url);
ws = request.GetResponse();
return (response.ID == 200);
}
catch (Exception e)
{
Console.Write(e.StackTrace);
}
return false;
}
Hope this helps.
Try appending ?wsdl at the of the URL pointing to the WCF-service.
If your Web service address is
http://services.aonaware.com/DictService/DictService.asmx
you can reach your wsdl file like this:
http://services.aonaware.com/DictService/DictService.asmx?WSDL
The returned WSDL allows you to see all the method the WCF-service provides.
I never did unittesting for an asp.net web api. The service is about posting a JSON in the request and returning a JSON result after JSON schemavalidation and querying. Just wondering how to unittest a web api in general. An example of a test would be posting an invalid JSON string and testing whether this returns the correct HTTPcode ie 400 or something. This is roughly what my service looks like:
public class MyApiController : ApiController
{
public HttpResponseMessage Post([FromBody]dynamic value)
{
return response;
}
}
Also how can I use constructor injection with web apis? If I use a constructor here my value that is posted is null?
You can directly create the instance of controller. If you are used any complicated code, you can create mock for the class for unit testing. Refer this link to understand unit testing of ASP.NET web API.
[Test]
public async void GetSettingsRequest()
{
var getSettingsResponse = await api.GetSettings();
Assert.IsNotNull (getSettingsResponse);
Assert.IsTrue (getSettingsResponse.Success);
Assert.IsNotNullOrEmpty (getSettingsResponse.Email);
}
I made test project which is making request on api server. After request is made, wait for response and test response.
My first thought is that you should figure out what you want to test first. That means just jotting down all of the expected behaviors, then writing tests to ensure that your controller behaves as... expected.
Let's start with two fictional test cases:
The response is not null
The response always carries a success status code
--
class MyApiControllerTest
{
private MyApiController myApiControllerFixture;
[TestInitialize]
void Initialize()
{
this.myApiControllerFixture = new MyApiController();
}
[TestMethod]
void MyApiController_Post_ResponseNotNullTest()
{
var response = this.myApiControllerFixture.Post(new { });
Assert.IsNotNull(response);
}
[TestMethod]
void MyApiController_Post_SuccessStatusCodeTest()
{
var response = this.myApiControllerFixture.Post(new { });
Assert.IsTrue(response.IsSuccessStatusCode);
}
}
Just add tests as you discover new required behaviors, and delete obsolete tests when behaviors change.
I need to extract a soap Header attribute from a incoming message to my service. I am using service stack and have been looking around and can't find a good answer anywhere. Can anyone tell me how to retrieve a SOAP Header Attribute from a request object?
Here is my service
public class NotificationServices : Service
{
public GetAccountNotificationResponse Any (GetAccountNotification request)
{
//Do Some stuff Here!!!
//Need to retrieve some header here
}
}
Any help will be appreciated. And if you know for a fact it can't be done please let me know as well.
Thank you
In the latest version of ServiceStack v3.9.49 you can access the Request SOAP Message (for SOAP Requests) using the IHttpRequest.GetSoapMessage() extension method, e.g:
public class NotificationServices : Service
{
public GetAccountNotificationResponse Any (GetAccountNotification request)
{
//Do Some stuff Here!!!
var requestSoapMessage = base.Request.GetSoapMessage();
}
}
From the Serialization / Deserialization wiki:
You can access raw WCF Message when accessed with the SOAP endpoints in your Service with IHttpRequest.GetSoapMessage() extension method, e.g:
Message requestMsg = base.Request.GetSoapMessage();
To tell ServiceStack to skip Deserializing the SOAP request entirely, add the IRequiresSoapMessage interface to your Request DTO, e.g:
public class RawWcfMessage : IRequiresSoapMessage {
public Message Message { get; set; }
}
public object Post(RawWcfMessage request) {
request.Message... //Raw WCF SOAP Message
}
I have an application written in Windows Service and this app need to make a call to a WebAPI written in Asp.Net MVC 4 WebAPi. this method in WebAPI return a DTO with primitive type, something like:
class ImportResultDTO {
public bool Success { get; set; }
public string[] Messages { get; set; }
}
and in my webapi
public ImportResultDTO Get(int clientId) {
// process.. and create the dto result.
return dto;
}
My question is, how can I call the webApi from the Windows Service? I have my URL and value of parameter, but I don't know how to call and how to deserialize the xml result to the DTO.
Thank you
You could use System.Net.Http.HttpClient. You will obviously need to edit the fake base address and request URI in the example below but this also shows a basic way to check the response status as well.
// Create an HttpClient instance
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8888/");
// Usage
HttpResponseMessage response = client.GetAsync("api/importresults/1").Result;
if (response.IsSuccessStatusCode)
{
var dto = response.Content.ReadAsAsync<ImportResultDTO>().Result;
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
You can install this NuGet package Microsoft ASP.NET Web API Client Libraries to your Windows Service project.
Here is a simple code snippet demonstrating how to use HttpClient:
var client = new HttpClient();
var response = client.GetAsync(uriOfYourService).Result;
var content = response.Content.ReadAsAsync<ImportResultDTO>().Result;
(I'm calling .Result() here for the sake of simplicity...)
For more sample of HttpClient, please check this out: List of ASP.NET Web API and HttpClient Samples.