Returning IList as a REST API using Linq - linq

I am working with REST (using WCF) from past 2 years but new to Entity Model & Linq, however have used nHibernate.
I made a simple service with folloiwng :-
NorthwindModel [A data model having Product, Order and Order_Detail tables]
ProductService exposed as REST with specific config (not using WebServiceHostFactory)
Service Contract :-
[ServiceContract]
public interface IProductService
{
[OperationContract]
[WebGet(
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)
]
IList<Product> GetProducts();
}
Service Implementation :-
public class ProductService : IProductService
{
#region IProductService Members
public IList<Product> GetProducts()
{
IList<Product> prodList = new List<Product>();
NorthwindEntities ne = new NorthwindEntities();
var query = from category in ne.Products select category;
prodList = query.ToList<Product>();
return prodList;
}
#endregion
}
Service Tag :-
<services>
<service name="HellooData.ProductService" behaviorConfiguration="wcfJSONBehavior">
<endpoint address="" behaviorConfiguration="REST" binding="webHttpBinding"
contract="HellooData.IProductService" bindingConfiguration="RESTBINDING">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="webHttpBinding" contract="IMetadataExchange" bindingConfiguration="RESTBINDING" />
</service>
</services>
Binding : -
<webHttpBinding>
<binding name="RESTBINDING" maxReceivedMessageSize="2147483647" >
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</webHttpBinding>
After trying to call the service from the browser i get "Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data" error in Chrome and an empty page in Mozilla.
Have tried to debug but data is fetched properly (77 records) and returned without any exception. I somehow have a doubt in config or size of the data but not sure. Did try
to tamper the result set (only 2 instead of 77) result was still the same.
Can someone indicate what's going wrong?

I had this exact issue; in my case, I was disposing the database context before my SQL controller finished using it.

Related

Chrome (v71) ERR_CONNECTION_RESET on Self Signed localhost on Windows 8 Embedded

I run WCF service exposes API on local machine (https://localhost:8080/MyApi), self signed SHA-256 certificate registered on local machine, executed "netsh http add sslcert ipport=0.0.0.0:8080 certhash=... appid=..." and when browsing to https://localhost:8080/MyApi from Chrome it shows ERR_CONNECTION_RESET.
Now the funny part:
Works fine with Chrome v41. Happened only after upgrading to Chrome v69 (and same on v71).
Browsing from IE works well.
Calling the API from PowerShell web-invoke works either.
Same everything on Windows 10 works fine.
Modifying #allow-insecure-localhost to ENABLED works on Windows 10, but not on Windows 8 Embedded.
After activating chrome logging found this:
{"params":{"net_error":-101,"os_error":10054},"phase":0,"source":{"id":7810,"type":8},"time":"52598608","type":68},
{"params":{"error_lib":33,"error_reason":101,"file":"../../net/socket/socket_bio_adapter.cc","line":154,"net_error":-101,"ssl_error":1},"phase":0,"source":{"id":7810,"type":8},"time":"52598608","type":54},
Additional Chrome logging:
[8652:5036:0107/174231.775:ERROR:ssl_client_socket_impl.cc(1013)]
handshake failed; returned -1, SSL error code 1, net_error -101
[8652:5036:0107/174231.793:ERROR:ssl_client_socket_impl.cc(1013)]
handshake fail ed; returned -1, SSL error code 1, net_error -101
[8652:5036:0107/174231.795:ERROR:ssl_client_socket_impl.cc(1013)]
handshake fail ed; returned -1, SSL error code 1, net_error -101
Do you have any idea how to make Chrome access successfully my WCF localhost server?
How do you publish your wcf service? I would like you could post more details about your service. I followed your steps while could not reproduce your problem.
Here is my demo, wish it is useful to you.
Server (Console application,IP: 10.157.13.69).
class Program
{
static void Main(string[] args)
{
using (ServiceHost sh = new ServiceHost(typeof(MyService)))
{
sh.Opened += delegate
{
Console.WriteLine("service is ready...");
};
sh.Closed += delegate
{
Console.WriteLine("Service is closed");
};
sh.Open();
Console.ReadLine();
sh.Close();
}
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet]
string SayHello();
}
public class MyService : IService
{
public string SayHello()
{
return $"Hello, busy world\n{DateTime.Now.ToShortTimeString()}";
}
}
app.config
<system.serviceModel>
<services>
<service name="Server6.MyService" behaviorConfiguration="mybeh">
<endpoint address="" binding="webHttpBinding" contract="Server6.IService" behaviorConfiguration="rest" bindingConfiguration="mybinding" >
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
<host>
<baseAddresses>
<add baseAddress="https://localhost:13060"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="mybinding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="mybeh">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"></serviceMetadata>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Binding the certificate to the ip port
netsh http add sslcert ipport=0.0.0.0:13060
certhash=6e48c590717cb2c61da97346d5901b260e983850 appid={AA228B95-6613-4D58-9236-2C263AFDF231}
Result. these browser version is all V71.0
Local.
Remote mechine.
Browser.
Feel free to let me know if there is anything I can help with.

How to Configure a Spring Boot CXF Configuration with more that one service wsdl

I have the challenge that I have a WSDL file with more that one service definiton inside
----- Customer WSDL file, can not change it ----
<service name="DocumentOperationService">
<port name="DocumentOperationPort" binding="tns:DocumentOperationBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL" />
</port>
</service>
<service name="PermissionEvaluatorService">
<port name="PermissionEvaluatorPort" binding="tns:PermissionEvaluatorBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL" />
</port>
</service>
<service name="ConfigurationResolverService">
<port name="ConfigurationResolverPort" binding="tns:ConfigurationResolverBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL" />
</port>
</service>
------
How can I configure the Spring Configuration Class
import org.springframework.context.annotation.Configuration;
#Configuration
public class WebServiceConfiguration {
...
#Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), dmsPortService());
// CXF JAX-WS implementation relies on the correct ServiceName as QName-Object with
// the name-Attribute´s text <wsdl:service name="Weather"> and the targetNamespace
// "http://www.codecentric.de/namespace/weatherservice/"
// Also the WSDLLocation must be set
endpoint.setServiceName(dmsOperationService().getServiceName());
endpoint.setWsdlLocation(dmsOperationService().getWSDLDocumentLocation().toString());
// endpoint.setWsdlLocation("classpath:/service-api-definition/journalexportservice.wsdl");
endpoint.publish("/DocumentOperation");
return endpoint;
}
#Bean
public DocumentOperationService dmsOperationService() {
// Needed for correct ServiceName & WSDLLocation to publish contract first incl. original WSDL
return new DocumentOperationService();
}
That all 3 Services are loaded.
In the moment I can only load one Service, I could not find any example how this could be done.
I triad with 3 config files, but then only the last is active, and how to configure 3 services in the same config file I could not figure out.
You might want to take a look at this tutorial describing your exact use case with exactly your stack.
In short:
Your Configuration Bean needs to provide a ServletRegistrationBean with a cxfServlet, a SpringBus and an Endpoint. (Pretty much like your posted code. Juding from the comments it might even be from this very tutorial)
Your Endpoint should point to the overall wdsl location
Then you need to implement a Service that encomapsses all of your intended webservices
In this service you need one method per webservice

Using the setAllowedFields() method in Spring

I'm using Spring 3.2.0. I have registered a few custom property editors for some basic needs as follows.
import editors.DateTimeEditor;
import editors.StrictNumberFormatEditor;
import java.math.RoundingMode;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import org.joda.time.DateTime;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;
#ControllerAdvice
public final class GlobalDataBinder
{
#InitBinder
public void initBinder(WebDataBinder binder, WebRequest request)
{
binder.setIgnoreInvalidFields(true);
binder.setIgnoreUnknownFields(true);
//binder.setAllowedFields(someArray);
NumberFormat numberFormat=DecimalFormat.getInstance();
numberFormat.setGroupingUsed(false);
numberFormat.setMaximumFractionDigits(2);
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
binder.registerCustomEditor(DateTime.class, new DateTimeEditor("MM/dd/yyyy HH:mm:ss", true));
binder.registerCustomEditor(Double.class, new StrictNumberFormatEditor(Double.class, numberFormat, true));
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
binder.registerCustomEditor(URL.class, new URLEditor());
}
}
I have this many editors registered so far. Two of them DateTimeEditor and StrictNumberFormatEditor have been customized by overriding respective methods to fulfill custom needs of number format and Joda-Time.
Since I'm using Spring 3.2.0, I can take advantage of #ControllerAdvice.
Spring recommends to list a set of allowed fields with the setAllowedFields() method so that malicious users can not inject values into bound objects.
From the docs about DataBinder
Binder that allows for setting property values onto a target object,
including support for validation and binding result analysis. The
binding process can be customized through specifying allowed fields,
required fields, custom editors, etc.
Note that there are potential security implications in failing to set
an array of allowed fields. In the case of HTTP form POST data for
example, malicious clients can attempt to subvert an application by
supplying values for fields or properties that do not exist on the
form. In some cases this could lead to illegal data being set on
command objects or their nested objects. For this reason, it is highly
recommended to specify the allowedFields property on the DataBinder.
I have a big application and obviously there are thousands of fields. Specifying and listing all of them with the setAllowedFields() is a tedious job. Additionally, somehow I need to remember them.
Changing a web page to remove some fields or add additional fields as the need arises again requires to modify the parameter value of the setAllowedFields() method to reflect those changes.
Is there any alternative to this?
Instead of using setAllowedFields() to white-list, you can use setDisallowedFields() to black-list. For example, from the petclinic sample application:
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
From a pure security standpoint white-listing is preferred to black-listing, but it maybe help ease the burden some.
setAllowedFields() is very handy when using entity objects directly in web layer. Alternatively, one could use dedicated data transfer objects (DTO), from which entity objects are constructed in the service layer. Not only can the factories be re-used, but also used outside the web context, e.g. for asynchronous messages. Besides, DTO inheritance doesn't have to follow entity inheritance, so you are free to design the DTO hierarchy according to the needs of the use-cases.
from http://static.springsource.org/spring-webflow/docs/2.0.x/reference/htmlsingle/spring-webflow-reference.html#view-model
4.9. Specifying bindings explicitly
Use the binder element to configure the exact set of model bindings usable by the view. This is particularly useful in a Spring MVC environment for restricting the set of "allowed fields" per view.
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
If the binder element is not specified, all public properties of the model are eligible for binding by the view. With the binder element specified, only the explicitly configured bindings are allowed.
Each binding may also apply a converter to format the model property value for display in a custom manner. If no converter is specified, the default converter for the model property's type will be used.
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" />
<binding property="checkoutDate" converter="shortDate" />
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
In the example above, the shortDate converter is bound to the checkinDate and checkoutDate properties. Custom converters may be registered with the application's ConversionService.
Each binding may also apply a required check that will generate a validation error if the user provided value is null on form postback:
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" required="true" />
<binding property="checkoutDate" converter="shortDate" required="true" />
<binding property="creditCard" required="true" />
<binding property="creditCardName" required="true" />
<binding property="creditCardExpiryMonth" required="true" />
<binding property="creditCardExpiryYear" required="true" />
</binder>
<transition on="proceed" to="reviewBooking">
<transition on="cancel" to="bookingCancelled" bind="false" />
</view-state>
In the example above, all of the bindings are required. If one or more blank input values are bound, validation errors will be generated and the view will re-render with those errors.
A solution to use binder with DTO (companydata in example) in case most of the form input values should be converted to null if empty, but there is a need to add few exceptions (setDisallowedFields didn't work for me).
#InitBinder()
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
#InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
binder.registerCustomEditor(String.class, "companydata.companyName", new StringTrimmerEditor(false));
binder.registerCustomEditor(String.class, "companydata.companyNumber", new StringTrimmerEditor(false));
}

Sponsorship of remotely instanced objects

I have a singleton service on remote server, this has a method who returns new objects to clients:
public class MySingleton : MarshalByRefObject
{
public override object InitializeLifetimeService()
{
return null;
}
public MarshalByRefObject GetService()
{
return new Model();
}
}
public class Model : MarshalByRefObject
{
}
I don't want that Model instances live forever on server, so I just wanted to use the normal sponsorship procedure, on client side I create a sponsor for my Model, and I attach the remote lease to this sponsor:
var sponsor = new ClientSponsor();
_service = _mySingleton.GetService();
var success = sponsor.Register(_service);
Well, this does not work. The remote object Model, dies after a while.
Do you confirm this behavior ?
I guess it's because the lifetime manager on server doesn't have the opportunity to initialize the lease, because the object Model is instanced and returned directly.
I know this is an old post but during my search for an similar issue I stumbled on this post.
Maybe it will depend on the SinkProvider configuration. Because the Renewal call on Client side from server require an deserialization. In the app.exe.config on server side you have to setup the serverProvider and also the clientProvider like this:
<channel ref="tcp" port="50220" useIpAddress="false">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
<channel ref="http" port="50221" useIpAddress="false">
<serverProviders>
<formatter ref="soap" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="soap" />
</clientProviders>
</channel>
On the client side use the following app.config.exe:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" port="0">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full"/>
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>

SessionAware does not inject session Object

Once more here I come with a question of s2, I'm a beginner at it and got some trouble finding examples.
I'm building a menu service which depends upon a login, which is give when the user enters at start page. Once the login has been made, I store the user object into the session by doing the follow:
#Override
public String intercept(ActionInvocation invocation) throws Exception {
....
// verifica se o parametro do CPF veio no get e tenta logar o usuario
if (!StringUtils.isBlank(request.getParameter(USER_CPF_REQUEST))) {
if ( doLogin(request, session) ) {
return Action.SUCCESS;
}
and then the doLogin method
Usuario usuario = getServico().buscar( Long.valueOf(cpf) );
//Caso o usuário exista, guarda na session
if (usuario != null){
session.setAttribute(USER_HANDLE, usuario);
return true;
}
Now comes the problem, I have a MenuBean injected on the MenuAction by the following xml piece on ApplicationContext.xml
<bean id="menuService" class="br.com.autenticis.renacon.ejb.MenuBean" />
<bean id="menuAction" scope="prototype" class="br.com.autenticis.renacon.actions.MenuAction">
<constructor-arg ref="menuService" />
</bean>
And the menuAction is declared as follow:
public class MenuAction extends ActionSupport implements Preparable, SessionAware
By doing so I need to implement the session set with a private member
private Map<String, Object> session;
....
#Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
The failing part of all its the method bellow, the session object is null at debugging:
public String execute() {
if ( session.containsKey( LoginInterceptor.USER_HANDLE) ){
Usuario u = (Usuario) session.get( LoginInterceptor.USER_HANDLE);
setMenu( servico.getMenuPerfil( u.getPerfil() ) );
return Action.SUCCESS;
}
return input();
}
Does anyone know why? or how to implement it? Looking at the code above, I need 'Perfil' from the user which is logged on, if the session contains the key to the user object I get it and then use the perfil to populate the Menu through the setter and return SUCESS, otherwise it'll return INPUT which will lead to the login screen.
After some ours I managed to discover the error. wich lies not in the program but in the struts.xml, I've written a custom stack for the application:
<!-- stack seguro -->
<!--
<interceptor-stack name="defaultLoginStack">
<interceptor-ref name="logger" />
<interceptor-ref name="params" />
<interceptor-ref name="login" />
<interceptor-ref name="prepare" />
<interceptor-ref name="chain" />
<interceptor-ref name="modelDriven" />
<interceptor-ref name="modelDriven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="staticParams" />
<interceptor-ref name="params" />
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" />
<interceptor-ref name="workflow" />
</interceptor-stack>
-->
And somewhat forgot to include session-related items, with the defaultLoginStack changed to
<interceptor-stack name="defaultLoginStack">
<interceptor-ref name="login" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
I'm now able to use session injected correctly.

Resources