passing username and password to soap webservice - c#

I am working on a soap webservice in c#. It look like this:
public class MyService : System.Web.Services.WebService
{
public MyService()
{
}
[WebMethod]
public string Hello()
{
return "hello";
}
}
and I added a service reference to this web service from another website, so I can access the Hello() method from there using the code:
MyServiceSoapClient client = new MyServiceSoapClient();
client.Hello();
Now I need to pass the credentials to that web service. I have tried:
MyServiceSoapClient client = new MyServiceSoapClient();
client.ClientCredentials.UserName.UserName = "test";
client.ClientCredentials.UserName.Password = "pwd";
client.Hello();
But I could not manage to get these credentials in the webservice ( in the Hello() method).
How can I get these values in the webservice?

You get the user via the WebService.User property. This will give you the username but there is no way to retrieve the passed password, this is by design as the authentication happens at the IIS level before your WebService is run.
public class MyService : System.Web.Services.WebService
{
public MyService()
{
}
[WebMethod]
public string Hello()
{
return "hello, my name is " + User.Identity.Name;
}
}

Related

how to maintain wcf service per session calling url from android studio

I created WCF service and calling it from the android studio and its working fine, but after implementing WCF perSession functionality it is working for a single user at a time.
Problem:
My problem is when i am hitting WCF url with multiple user my sessionID get overwrite by the latest logged in user, So how to maintain session for multiple user like we do in web application.
I used this to creste session in WCF:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
and this is my method to create sessionid within services class
public class MyService : IMyService
{
static string currentSessionID = string.Empty;
public string createSession()
{
currentSessionID = DateTime.Now.Ticks.ToString();
return currentSessionID;
}
public string Login()
{
var mysessionId = createSession();
return mysessionId;
}
public string Mymethods(string data)
{
string response = "";
if(data.StartsWith("01"))
response = Login();
return response;
}
}
and am hitting this createSession() method only in login function.
Please help me out of this.....
Thanks in advnance.

WCF service without using proxy in C#

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.

How to upload my custom WCF SOAP service to remote server?

Everyone! I have have custom WCF SOAP service (chatbot with getAnswer method that takes a string) and my client (website). My IService:
namespace WcfServiceLab1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetChatbotAnswerUsingDataContract(string question);
}
}
Service.svc:
namespace WcfServiceLab1
{
public class Service1 : IService1
{
public string GetChatbotAnswerUsingDataContract(string question)
{
Chatbot chatbot = new Chatbot();
return chatbot.GetAnswer(question);
}
}
}
And my ChatbotController:
[HttpPost]
public ActionResult Create(string question)
{
try
{
ViewBag.ChatbotAnswer = obj.GetChatbotAnswerUsingDataContract(question.ToLower());
ViewBag.YourQuestion = question;
return View("Index");
}
catch
{
return View("Index");
}
}
It's works on localhost, but when I upload my WCF service on free hosting using FTP and try to add Service References Visual Studio didn't find my service. It's here: http://chatbotservice.esy.es/WcfServiceLab1/
How to "install" wcf service on the remote server? What should I do?

Call ASP.NET from c# (win32 based) client

I've got a web application created with ASP.NET and a windows native client program written in c#.
The windows native program needs to send and fetch data from the ASP.NET web application.
I guess in the web application I'll need a controller for the external calls. And in the client Software I somehow Need to call them.
Is there a way to achieve calls with complex data types (lists of classes) as parameters?
How do I secure the calls from the client? Simple http-logon?
for example I'd like to transfer an instance of this class to or from the ASP.NET web application:
public class Address
{
public String Street {get;set;}
public String City {get;set;}
}
public class CustomerInformation
{
public String No {get;set;}
public String Name {get;set;}
public List<Address> Addresses {get;set;}
}
Of course the Windows client is running somewhere local while the ASP.NET Service is running in the web.
I would add API controller and put some methods there. For instance
// Addresses API
public class AddressController : ApiController
{
private readonly IRepository<Address> _repository;
public AddressController(IRepository<Address> repository)
{
_repository = repository;
}
[BasicAuthorize]
public IList<Address> GetList()
{
return _repository.GetAll();
}
}
// Constomer information API
public class CustomerInformationController : ApiController
{
private readonly IRepository<CustomerInformation> _repository;
public CustomerInformationController(IRepository<CustomerInformation> repository)
{
_repository = repository;
}
[BasicAuthorize]
public IList<CustomerInformation> GetList()
{
return _repository.GetAll();
}
}
To secure those methods you can use Basic authentication. This means that you can add authorization header for each request:
For example how it looks for user "myuser" with password "test"
Authorization: basic bXl1c2VyOnRlc3Q=
// Custom attribute for Basic authentication
public class BasicAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
private readonly string[] _permissionNames;
public BasicAuthorizeAttribute()
{
}
public BasicAuthorizeAttribute(params string[] permissionNames)
{
_permissionNames = permissionNames;
}
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// check if user has been already authorized
if (base.IsAuthorized(actionContext))
return true;
var user = AuthenticateUser(actionContext);
// here you can check roles and permissions
return user != null;
}
private IUser AuthenticateUser(HttpActionContext context)
{
var request = context.Request;
AuthenticationHeaderValue authHeader = request.Headers.Authorization;
if (authHeader != null)
{
// RFC 2617 sec 1.2, "scheme" name is case-insensitive
if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) && authHeader.Parameter != null)
return AuthenticateUser(authHeader.Parameter);
}
return null;
}
private IUser AuthenticateUser(string credentials)
{
try
{
// parse values
var encoding = Encoding.GetEncoding("iso-8859-1");
credentials = encoding.GetString(Convert.FromBase64String(credentials));
var credentialsArray = credentials.Split(':');
var username = credentialsArray[0];
var password = credentialsArray[1];
// authentication
var membershipService = new IMembershipService();
return membershipService.ValidateUser(username, password);
}
catch (Exception)
{
// Credentials were not formatted correctly.
return null;
}
}
}
On client side you can use HttpClient to send async request
public async Task<Address[]> GetAddresses() {
var client = new HttpClient {BaseAddress = new Uri(_settingsService.GetHost())};
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var base64 = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "myuser", "test")));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",base64);
HttpResponseMessage response = await client.GetAsync("api/addresses");
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(response.ReasonPhrase);
string content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Address[]>(content);
}
Is there a way to achieve calls with complex data types (lists of classes) as parameters?
Yes, The server application as ASP.NET or ASP.NET MVC or (preferably) ASP.NET WEB API can provide services with complex data types. In fact there is no limitation in declaring methods.
How do I secure the calls from the client? Simple http-logon?
There are wide ranage of authentication and authorization mechanism in ASP.NET (MVC, WEB API) which give you opportunity to choose one them.
The data transfers between your client and server via XML or JSON.
The "WebClient" class provides everything that you need to make a call from client to server.
More information:
http://www.codeproject.com/Articles/33798/HTTP-GET-with-NET-WebClient
How to post data to specific URL using WebClient in C#
How do I log into a site with WebClient?

WCF client fields are losing values

I have a WCF service hosted on a console application the code is:
public interface ITestService
{
[OperationContract]
void SetField(string data);
[OperationContract]
string GetField();
}
public class TestService : ITestService
{
private string myData;
public string GetField()
{
retrun myData;
}
public void SetField(string data)
{
myData = data;
}
}
then I hosted it on a console application:
ServiceHost host = new ServiceHost(typeof(TestService));
host.Open();
Console.WriteLine("Test Service Host");
Console.WriteLine("Service Started!");
foreach (Uri address in host.BaseAddresses)
{
Console.WriteLine("Listening on " + address);
}
Console.WriteLine("Press any key to close the host...");
Console.ReadLine();
host.Close();
I started the console host then In an other console app I referenced the service and used it:
TestService client = new TestService();
client.SetField("test");
Console.WriteLine( client.GetField() );
this print nothing means the field is still null
What is wrong with this service?
What's wrong is that you're expecting that state will be persisted between calls - it is NOT. By default, WCF are absolutely stateless (and they should be! That's a good thing!)
If you need to persist information - store it into a persistent store (a.k.a a database).
Each WCF call will (by default) get a brand new, freshly created instance of TestService.
So your second call's instance knows nothing about the first instance (used by SetField) and therefore cannot return that value that you set in the first call.
Try this:
Use string as static.
public interface ITestService
{
[OperationContract]
void SetField(string data);
[OperationContract]
string GetField();
}
public class TestService : ITestService
{
private static string myData;
public string GetField()
{
retrun myData;
}
public void SetField(string data)
{
myData = data;
}
}
You should mark your service class with the attribute:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class TestService : ITestService
{
//...
}
This means that your service must have only one instance. And you must create the host like this:
var host = new ServiceHost(new TestService()); // or get a singleton..
host.Open();
Pay your attantion that you use an instance to create a service instead type. Then your code should work.

Categories