The client has a very old .net 1.1 app they need to hit a service. I built a middle piece in 4.0 that hits the service and I am attempting to return the data. The classes I built use ArrayLists since the .net 1.1 won't have access to generic lists. When the client consumes my code, the ArtayLists come over as ArrayOfAnyType and each must be initialized on the CLIENT side, despite the fact that I initialized them in Sub New(). I don't wan tthe client to have to initialize every arraylist. Here is the unremarkable code...
<Serializable()> _
Public Class XApplication
Public Sub New()
_People = New ArrayList
_PhysicalHouseholds = New ArrayList
_TaxReturns = New ArrayList
End Sub
Public Property People() As ArrayList
Public Property PhysicalHouseholds() As ArrayList
Public Property TaxReturns() As ArrayList
End Class
Tried using the XmlInclude Attribute to define the class type but it had no effect. To be clear, I CAN NOT use WCF. I have to use web services.
When a client proxy is generated from a web reference, the proxy will only model the data. Implementation code (including the constructor) cannot be obtained from WSDL. As a result, when a new instance of the proxy class is created, properties will have the default value.
You always have to create the object on the client side.
You can't send an object though a web service. The message that is sent is plain text, so any object has to be sent as the text representation that it contains, and be recreated on the client side by parsing the text and putting the data into a new object.
Related
I am looking for a solution related to passing cookies values from JAX-RX REST API endpoint to ejb layer.
I tried searching the solution and found some of them are using thread local. but and thread local supposed to be not working with executor services.
Is there any another solution that I can use to pass cookies values from web/rest later to ejb layer.
Note: I do not want to pass it as method parameter from rest layer to down the ejb layer. I would like to access the cookies values directly in ejb layer
Thanks
Lets say you have a class MyEJB, you can inject HttpServletRequest object to you ejb as follows:
public class MyEJB{
#Context
private HttpServletRequest httpRequest;
}
Now from this request object you can access your required cookies. As follows:
String rawCookie = request.getHeader("Cookie");
String[] rawCookieParams = rawCookie.split(";");
for(String rawCookieNameAndValue :rawCookieParams)
{
String[] rawCookieNameAndValuePair = rawCookieNameAndValue.split("=");
}
In my one of the .net core project I have to call REST apis to send some data to clients. There are always more than 9-10 clients with different apis having their own domain and custom headers. If I will create HttpClient object each time it will hamper performance since each time new TCP connection will be create and closed. If I will create single HttpClient object using singleton designing pattern then same base url and default header will be used for each client. Can any one suggest a way to solve this problem. I do not wants to go and create new HttpClient every time new client api comes for integration.
If you're calling 9-10 different APIs, where client-level things like default headers could come in handy, then 9-10 static HttpClient instances is optimal. If coding 9-10 instances feels a little messy/repetitive, you could wrap them in a dictionary object, specifically a ConcurrentDictionary will help keep instantiation both lazy and thread-safe. Something like this should work:
public static class HttpClientManager
{
private static ConcurrentDictionary<string, HttpClient> _clients =
new ConcurrentDictionary<string, HttpClient>();
public static HttpClient Get(string baseUrl)
{
return _clients.GetOrAdd(baseUrl, _ =>
new HttpClient { BaseAddress = new Uri(baseUrl) });
}
}
Then it's just HttpClientManager.Get(baseUrl) whenever you need to use one.
I'm trying to design a web application that would user WCF services to access data and provide business logic. So in general the whole system would look like that:
UI (ASP.NET MVC)
BusinessLayer (WCF Services)
DataLayer (Entity Framework)
Date (SQL Server Database)
All parts of the system will resist on the same, closed environment, so I'm going to use Certificates to secure ASP.NET <-> WCF connection. Database connection would use standard EF securities, Connection String and Windows Authentication.
The application has to provide authentication and authorization functionality. I'm going to move most of that into ASP.NET, so there will be ValidateUserAuth() service method, which will be used to validate credentials, but the result (with UserRole that user belongs to) will be then used by ASP to create user session.
After that, every Service Method call needs to know the UserRole of current user, to return proper results (or say 'Access denied' if it's necessary). Problem is I don't want to pass that UserRole as a parameter for every Service Method! I'd like to make it happen automatically. Is it even possible with WCF?
All I need is:
Every service call made from ASP.NET app will be extended with User data taken from current ASP Session.
Service Method invoked by that call will be able to recieve that User data and use it to provide results according to user permissions.
All this would happen somekind on background, so there will be no additional UserDetails method parameter added to every Service Method exposed from Service.
I read a lot about WCF itself, but found anything that could met my requirements. I hope I just missed it and it's still possible.
Passing user roles from the client to the server in a plain form would be a design mistake. Clients could easily misuse your services by calling them freely, outisde of the application scope.
Why don't you rely on a role provider? This way all you pass from the client is the identity (could even be a forms cookie) and then at the server side you read all roles. You could probably even use a built in mechanism to cache roles in a role cookie.
Some time ago I wrote two tutorials on wcf securing with forms authentication so that integration between web pages and active clients is easy
http://netpl.blogspot.com/2008/02/clickonce-webservice-and-shared-forms.html
http://netpl.blogspot.com/2010/04/aspnet-forms-authentication-sharing-for.html
I decided to use MessageInspector for that:
On Client-side:
Public Function BeforeSendRequest(ByRef request As System.ServiceModel.Channels.Message, channel As System.ServiceModel.IClientChannel) As Object Implements System.ServiceModel.Dispatcher.IClientMessageInspector.BeforeSendRequest
Dim requestMessageProperty = New HttpRequestMessageProperty()
Dim currentUser = Authentication.AuthenticatedStaffcareUser
If currentUser Is Nothing Then Throw New ApplicationException()
requestMessageProperty.Headers("UserName") = currentUser.UserName
requestMessageProperty.Headers("UserId") = currentUser.UserID
requestMessageProperty.Headers("UserRole") = currentUser.UserRole
requestMessageProperty.Headers("EffectiveDate") = currentUser.EffectiveDate
request.Properties(HttpRequestMessageProperty.Name) = requestMessageProperty
Return Nothing
End Function
And Server-side:
Public Function AfterReceiveRequest(ByRef request As Message, channel As IClientChannel, instanceContext As InstanceContext) As Object Implements IDispatchMessageInspector.AfterReceiveRequest
Dim messageProperty = CType(OperationContext.Current.IncomingMessageProperties(HttpRequestMessageProperty.Name), HttpRequestMessageProperty)
Dim userName = messageProperty.Headers("UserName")
Dim userId = Integer.Parse(messageProperty.Headers("UserId"))
Dim userRole = messageProperty.Headers("UserRole")
Dim effectiveDate = DateTime.Parse(messageProperty.Headers("EffectiveDate"))
Dim identity = New AppServerUserIdentity(userName, userId, userRole, effectiveDate)
Dim principal = New AppServerUserPrincipal(identity)
Threading.Thread.CurrentPrincipal = principal
Return Nothing
End Function
I also had to set custom AuthorizationPolicy to prevent standard one from overwriting Thread.CurrentPrincipal:
Public Function Evaluate(evaluationContext As EvaluationContext, ByRef state As Object) As Boolean Implements IAuthorizationPolicy.Evaluate
Dim principal = TryCast(Threading.Thread.CurrentPrincipal, AppServerUserPrincipal)
If principal Is Nothing Then
Return False
Else
evaluationContext.Properties("Principal") = principal
Return True
End If
End Function
I understand that webservices are stateless. I want to know if there is any way we can expose the public properties (getters and setters) of a webservice on the client side (client side being a vb consumer not javascript)?
Web services are method-based, so they're not designed to access properties.
But there's no reason you couldn't make GetX/SetX methods which are exposed like regular service methods - just make sure you include the [WebMethod] attribute.
As others have suggested, you will need to use get/set methods instead of properties.
As for accessing the web service from JavaScript, just specify the method name in the URL and do an XmlHttpRequest.
The only thing you can "expose" from a web service are the [WebMethod].
You might access your web service with code like the following:
Dim svc as New WebReference.MyWebService()
Dim result As Integer = svc.GetSomeInteger()
svc.SetSomeInteger(result)
Dim result2 As Integer = svc.GetSomeInteger()
You may think that you have created an instance of the web service class. You have not. You have only created an instance of the proxy class in your VB.NET code. In the above code, each call to the web service goes through the same client proxy instance, but will go to a different instance of the server-side web service class.
Even if the web service had properties, or just fields, since you would have a different instance of the web service for each call, you would have a different version of "SomeInteger" each time.
I have little Silverlight app that needs to make queries to server, is it possible to return objects to silverlight app or how can I communicate with server?
Use a WCF Service. As long as your objects are Serializable, the runtime will encode and decode them for you transparently.
A simple Silverlight-enabled WCF service looks something like this:
using System.ServiceModel;
using System.ServiceModel.Activation;
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class YourService
{
[OperationContract]
public string DoStuff(string arg)
{
return arg + "stuff";
}
}
You can replace "string" with your datatype by creating a [DataContract].
In my opinion it might be best to use web services to ship whatever is needed to your Silverlight application. I suggest that you use the WebClient class in combination with the URI class to obtain the data. Example:
Uri uri = new Uri(//the url of you webservice, UriKind.RelativeOrAbsolute);
Now create an instance of the WebClient class and add a callback to be called when the read from the web service is completed:
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(CallbackMethod);
wc.OpenReadAsync(uri);
When the data is retrieved from the server, the CallbackMethod is called. The method has an EventArgs object that contains a property called result. You can obtain your data using that property.
Silverlight doesnt need ASP at all to function, if you have a database on a seperate server check out WCF, and then get Silverlight to communicate with the WCF service and then the service with the database, if you want something more transparent, then try out WCF RIA services, this allows you to have a middle-tier approach to data access in silverlight