WCF proxy class creating null values - c#

I have some problem on a WCF proxy class (not sure if it's the proxy or the service class), here is the context:
I have a WCF service that I consume on a web application, this service calls another service and then process the response to take it back to the web app. Here is the construction of that method
public CreateProjectResponse CreateNewProject(List<CreateProjectRequestProject> projects)
{
ServiceHelper helper = new ServiceHelper();
CreateProjectResponse response = helper.CreateNewProject(projects);
return response;
}
Everything is just fine up to the response object assignation. I have my correct list of "CreateProjectResponseProject" objects. The problem is that after the return statement I see that the service class is creating a NEW set of "CreateProjectResponseProject" objects as if it's calling the constructor again and assigning the default values (null in this case).
Does anyone have an idea what can be happening? I have been researching and don't seem to find any related solution. BTW... this process was working before, nothing have changed on the solution. Hope someone can help. Thanks!
EDIT: Here is the code for the helper class:
public class ServiceHelper
{
public CreateProjectResponse CreateNewProject(List<CreateProjectRequestProject> projects)
{
CreateProjectRequest request = new CreateProjectRequest();
CreateProjectResponse response = new CreateProjectResponse();
ProjectCreator create = new ProjectCreator();
WebServiceConfig configs = new WebServiceConfig();
request.Projects = projects;
configs.Password = "XXXXXXX";
configs.Username = "USER";
configs.RemoteAddress = "https://server/listener/connector";
configs.EndpoingConfig = "CreateProjectEndpoint";
try
{
response = create.CreateProject(configs, request);
}
catch (Exception ex)
{
string messageError = "unable to create project:" + ex.Message.ToString();
}
return response;
}
}

I was using the WCF service as an intermediate to communicate to another service, I removed the intermediate and called my helper class directly from the web application (with the proper endpoint config) and everything works fine now.

Related

Adding an Authorization header to a Service Reference SOAP request

I've consumed a WSDL as and have succesfully called web-service methods.The request has an Authorization header that can only be added at the point the request is made:
public static NumberCaptureClient Connect()
{
var remoteAddress = new EndpointAddress("https://website.com:8443/webservice/WebServiceNumberCapture");
using (var NumberCaptureClient = new NumberCaptureClient(new BasicHttpBinding(BasicHttpSecurityMode.Transport), remoteAddress))
{
NumberCapture.ClientCredentials.UserName.UserName = "test";
NumberCapture.ClientCredentials.UserName.Password = "test";
try
{
using (OperationContextScope scope = new OperationContextScope(NumberCaptureClient.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " +
Convert.ToBase64String(Encoding.ASCII.GetBytes(NumberCaptureClient.ClientCredentials.UserName.UserName + ":" + NumberCaptureClient.ClientCredentials.UserName.Password));
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
}
}
catch (Exception error)
{
MessageBox.Show("Error");
return null;
}
return NumberCaptureClient;
}
}
As you can see I'm in need of returning an instance of the proxy client (the client has hundereds of methods that all need the header) but need it so the headers are always sent, with the 'using' clause this isn't possible as the scope is lost outside of it.
Is there a way to permanantly add the headers so they are sent with every request to the webservice?
This is a WCF proxy, right? Generally speaking, you should remove the using from your Connect method. If the method is used to get a prepared service proxy, then it makes no sense to dispose it as part of the method that creates it.
Instead, the method/code that uses the Connect method should be responsible of using it:
using(var proxy = theClass.Connect())
{
// call service using proxy here
// process response here, if you may need to call the service again
// as part of processing
}
// process response here if you don't need to call the service again
There is a catch however, since for WCF proxies, the Dispose method internally calls the Close method, which in turn can throw exceptions. For this reason, Microsoft has a recommendation for how to handle cleaning up of WCF proxies. See here.

ServiceStack - As passthru to another ServiceStack service

I currently have an ServiceStack Service that does nothing but relay requests to an internal ServiceStack service.
The relay service is setup something like this (code made brief as an example):
public class RelayService : Service
{
public SomeDTO Get(FetchSomething request)
{
try
{
return new JsonServiceClient(settings.OtherServiceURL).Get(request);
}
catch (Exception)
{
throw;
}
}
public void Put(PersistSomething request)
{
try
{
new JsonServiceClient(settings.OtherServiceURL).Put(request);
}
catch (Exception)
{
throw;
}
}
}
My questions are:
Is it best practice to new up a JsonServiceClient for each request? Or should I inject an instance?
Since the relay service can contain variations on Put/Get that return DTO's or void, is there a cleaner way to relay all calls to the backing ServiceStack service instead of having to duplicate each method in the relay service? Is it possible to do this all in one or a few methods using Any()?
Thanks for any input.
This previous answer for an example of a generic reverse proxy in ServiceStack.
The simplest and most generic approach in ServiceStack would be to register a RawHttpHandler that just forwards the Request to the downstream server and writes the Response to the Output Stream, e.g:
RawHttpHandlers.Add(_ => new CustomActionHandler((req, res) =>
{
var bytes = req.InputStream.ReadFully();
var proxyUrl = settings.OtherServiceURL.CombineWith(req.RawUrl);
var responseBytes = proxyUrl.SendBytesToUrl(method: req.Verb,
requestBody: bytes,
accept:MimeTypes.Json,
contentType: req.ContentType,
responseFilter: webRes =>
{
res.StatusCode = (int)webRes.StatusCode;
res.StatusDescription = webRes.StatusDescription;
res.ContentType = webRes.ContentType;
});
res.OutputStream.Write(responseBytes, 0, responseBytes.Length);
}));
In order to access the RequestStream you'll also want to tell ServiceStack to not inspect the FormData when creating the Request (as this forces reading the request body), which you can skip with:
SetConfig(new HostConfig {
SkipFormDataInCreatingRequest = true
});
Another approach would be to configure something like IIS Application Request Routing and URL Rewriting to use as a reverse proxy.

Consume asmx webservice in pcl

I am developing an app which uses third party .asmx web service. And I am using PCL(Portable class Libraries) in my app.
So I wanted to consume those .asmx web services in my app. Problem is PCL doesn't support traditional web service viz .asmx. It supports WCF web services.
I have read many articles, they suggests me that from wsdl write WCF web service. But since all web services are third party, I need to write proxy in client app (Where web service is being called) such that it will convert WCF call to .asmx.
Also I have tried this example using PCL.
I am using this asmx web service
public class PerformLogIn : ILogInService
{
public string LogIn(string code)
{
ServiceReference1.WeatherSoapClient obj = new ServiceReference1.WeatherSoapClient();
obj.GetCityForecastByZIPAsync(code);
ServiceReference1.WeatherReturn get = new ServiceReference1.WeatherReturn();
return (get.Temperature);
}
But I am not getting any result.
So do anybody have idea how to do that??
Eureka I found it..
Use following code snippet
public class PerformLogIn : ILogInService
{
public void LogIn(string code)
{
ServiceReference1.WeatherSoapClient obj = new ServiceReference1.WeatherSoapClient(
new BasicHttpBinding(),
new EndpointAddress("http://wsf.cdyne.com/WeatherWS/Weather.asmx"));
obj.GetCityForecastByZIPAsync(code);
obj.GetCityForecastByZIPCompleted+=getResult;
}
void getResult(Object sender,GetCityForecastByZIPCompletedEventArgs e)
{
string error = null;
if (e.Error != null)
error = e.Error.Message;
else if (e.Cancelled)
error = "cancelled";
var result = e.Result;
}
}
So your response from web service is being stored in result variable. Just fetch the data whatever needed and return it to calling client.

How to add security to a EF 5.0 Code First WCF DataService

I created several POCO then created a DbContext (FooDbContext) - I then created a DataService class device from DataService< FooDbContext > calll FooDatService. I can access all my data in my silverlight app and if I start a Web Browser I can access it through the URL as expected. Now I want to allow to the DataService only after a successful login.
I've blogged on that like 3 years ago
http://netpl.blogspot.com/2010/04/aspnet-forms-authentication-sharing-for.html
The idea is to reuse the forms cookie to guard your invocations so that only logged in users are allowed to call the service.
You can add a service authorization manager to your WCF service to put all methods and endpoints of that service under access control, without modifying any of the implementation of the service.
Creating and starting your WCF service:
Uri[] restUris = new Uri[] { new Uri(baseUri, "Api/v1/") };
// substitute your service host type here. I'm using WCF OData DataServiceHost
restAPIServiceHost = new DataServiceHost(typeof(API.RestAPIService), restUris);
var saz = restAPIServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
if (saz == null)
{
saz = new ServiceAuthorizationBehavior();
restAPIServiceHost.Description.Behaviors.Add(saz);
}
saz.ServiceAuthorizationManager = new MyServiceAuthorizationManager();
restAPIServiceHost.Open();
The above can also be done via web.config magic.
In your MyServiceAuthorizationManager implementation:
public class MyServiceAuthorizationManager: System.ServiceModel.ServiceAuthorizationManager
{
public override bool CheckAccess(OperationContext operationContext, ref Message message)
{
var reqProp = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
var authHeader = new AuthorizationHeader(reqProp.Headers[HttpRequestHeader.Authorization]);
bool authorized = // your code to decide if caller is authorized;
if (!authorized)
{
var webContext = new WebOperationContext(operationContext);
webContext.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized;
// optional: give caller hints where to go to login
webContext.OutgoingResponse.Headers.Add( HttpResponseHeader.WwwAuthenticate, String.Format("Bearer realm=\"{0}\"", baseUri.AbsoluteUri));
}
return authorized;
}
}
This CheckAccess method will be called for every request received by your WCF service, before the request is dispatched to the WCF implementation methods.

Adding SOAP Headers for SQL 2005 HTTP Endpoint web service in Visual Studio 2008

I'm trying to use SOAP headers to allow for SQL Authentication while accessing a webservice published on my SQL 2005 box via HTTP Endpoint. On the endpoint, I've set Authentication = (Basic), Ports = (SSL), and LOGIN_TYPE = MIXED. I'm able to generate the WSDL and consume it just fine in VS utilizing domain credentials. However, when I try to implement SOAP headers to allow for SQL Authentication, i'm running into problems. I've followed MS BOL to the letter (http://msdn.microsoft.com/en-us/library/ms189619(SQL.90).aspx), but for some reason, i'm not sending the SOAP header. I've verified this by using fiddler (http://www.fiddler2.com/fiddler2/) to trap my https messages and look at them. Any help would be greatly appreciated. Included is the code I've been using (the names have been changed to protect the innocent)
namespace ConsoleApplication.WebService
{
class Program
{
static void Main(string[] args)
{
//Prevents error due to self signed cert
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Stuff stuff = new Stuff();
stuff.DoSomthing();
}
}
public class Stuff
{
[System.Web.Services.Protocols.SoapHeaderAttribute("sqlSecurity")]
public int DoSomthing()
{
Webservice ws = new Webservice();
CredentialCache myCreds = new CredentialCache();
myCreds.Add(new Uri(ws.Url), "Basic", new NetworkCredential("netaccount", "netpass", "domain"));
ws.Credentials = myCreds;
ws.sqlSecurity = new SqlSoapHeader.Security();
ws.sqlSecurity.Username = "sqluser";
ws.sqlSecurity.Password = "sqlpass";
try
{
ws.SelectUserAccountByUserName("someuser");
}
catch (SoapException ex)
{
string txterror = ex.Detail.InnerText;
return 0;
}
return 1;
}
}
public partial class Webservice
{
public SqlSoapHeader.Security sqlSecurity;
}
}
This code utilizes the SqlSoapHeader class as documented in the BOL reference from above.
I error at calling ws.SelectUserAccountByUserName() with an "Execute permission denied" due to the fact that the "netaccount" user doesn't have rights to execute the stored proc. But again, this is because according to the soap message, no header with the sqluser info is being passed.
The SoapHeaderAttribute needs to be added to the web method. It won't do you any good to add it to some arbitrary calling method.

Categories

Resources