I'm calling a stored procedure via WCf-DataService and EF4. Other method works fine but one which return List failed with the exception Error processing response stream. The XML element contains mixed content.
Here is the XML return by the method (call in http)
<GetShowName>
<element>MONT</element>
<element>INTERPEECH 08/2011</element>
<element>POI MOBILIER 09/2011</element>
<element>ASSEMBLE GALE CLUB 41 06/2011</element>
<element>AFTES 10/2011</element>
<element>DIVERS DEVIS 12/2011</element>
<element>DIVERS DEVIS 12/2011</element>
<element>SFTS 2011</element>
<element>COUPE DU MONDE BIATHLON 12/11</element>
<element>CADRE NOIR GENEVE 04/2011</element>
</GetShowName>
And the code is:
private List<T> ListWithFilter<T>(string methodName, string methodParameters)
{
StringBuilder methodParams = new StringBuilder("/" + methodName + "?");
methodParams.Append(methodParameters);
Uri methodUri = new Uri(entities.BaseUri + methodParams.ToString());
List<T> result = entities.Execute<T>(methodUri).ToList(); //Exception here
return result;
}
Any idea?
According to this post the client does not support primitive type materialization as of .NET 4.0. May need to parse the result manually:
Invoking a WebGet throws an exception
Related
I have a servlet that receives an uploaded file. We've been having issues with a certain client's request not having a file attached or so the servlet thinks. The upload servlet is a replacement for an old one and we're using the Apache Commons FileUpload library to parse the file from the request. The old code uses the JavaZoom library. The requests client we're having issues with work perfectly fine in the old code.
In order to troubleshoot the problem, I added a bunch of logging to look at the request headers and parts to compare requests from a client that works with the one that doesn't. This is a snippet of how I'm looking at the parts:
Collection<Part> parts = request.getParts();
for(Part part : parts)
{
String partName = part.getName();
log.debug("Part=" + partName);
Collection<String> headerNames = part.getHeaderNames();
for(String headerName : headerNames)
{
String headerValue = part.getHeader(headerName);
log.debug(headerName + "=" + headerValue);
InputStream inputStream = part.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
StringBuilder builder = new StringBuilder();
try
{
for(String line=bufferedReader.readLine(); line!=null; line=bufferedReader.readLine())
{
builder.append(line);
builder.append('\n');
}
}
catch (IOException ignore)
{
// empty
}
finally
{
inputStream.reset();
}
log.debug("InputStream=" + builder.toString());
}
}
All this code works fine and I get the logging I'm expecting. However, this next bit of code doesn't act as expected:
if (isMultipart)
{
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
#SuppressWarnings("rawtypes")
List items = null;
// Parse the request
try
{
items = upload.parseRequest(request);
log.debug("items=" + items);
}
catch (FileUploadException ex)
{
log.warn("Error parsing request", ex);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
}
the items variable is empty when it's logged. If I comment out the code for logging the request parts, this bit of code works and the items variable contains the uploaded file.
I can only assume that the act of getting/reading the parts from the request somehow removes them from it and are no longer available for further processing. Is there some way to read them for logging purposes and still retain them in the request for further processing?
The Collection<Part> parts = request.getParts(); is an Sevlet 3.0 API which is replacement for Commons Apache File Upload API.
You should be using only one of the two methods. Both have the support for processing uploaded files and parameters along with it.
Here is the Example for File Upload Using Servlet 3.0
The problem you are facing is because you are invoking this Collection<Part> parts = request.getParts(); request will consume the request input stream. And then you are using Apache Commons API to read the parts again. Because the stream is already read you are seeing no parts are available.
References for Servlet 3.0 File Upload:
Posting Data along with File
Servlet 3.0 Multipart Example
Servlet 3.0 MultipartConfig
I am invoking the Tridion 2011 SP1 core service via the shipped client assembly. When I attempt to list the contents of a publication, I get an exception.
The code (simplified) looks like this:
ItemsFilterData filter = new Tridion.ContentManager.CoreService
.Client.RepositoryItemsFilterData.RepositoryItemsFilterData();
filter.ItemTypes = new ItemType[] {
ItemType.Folder,
ItemType.StructureGroup
};
filter.Recursive = false;
IEnumerable<IdentifiableObjectData> childItems = core.GetList("tcm:0-15-1", filter);
Note: the variable "core" refers to an ISessionAwareCoreService which I can successfully use to call, for example core.GetSystemWideList()
When .GetList is invoked, I get the following exception:
System.ServiceModel.FaultException`1 was unhandled
Message=Unexpected list type:
Tridion.ContentManager.Data.ContentManagement.RepositoryItemsFilterData.
What are the possible causes of this problem? Can you suggest a good general approach for interpreting this kind of message?
You can't get the direct children of a Publication using GetList. Instead you should just load the PublicationData with a client.Read and then access the RootFolder and RootStructureGroup on that.
PublicationData pub = (PublicationData)core.Read("tcm:0-1-1", new ReadOptions());
string rootFolder = pub.RootFolder.IdRef;
string rootSG = pub.RootStructureGroup.IdRef;
Alternatively you can call GetListXml with your RepositoryItemsFilterData and extract the items from the XML yourself.
XElement listResult = core.GetListXml(parent.ID, filter);
I hope you can help me with this problem I'm facing:
I created a simple web application using NetBeans.
As of now, it is very basic.
A servlet receives requests on the /verificon/* url pattern.
It extracts whatever string is set after /verificon/, i.e. if the url was http://domain/context/verificon/blahblah, it extracts blahblah.
It checks if such string is a known string, and simply displays a jsp with the result (true / false).
However, as simple as it is, I get the following error when running the application with a test string:
javax.servlet.ServletException:
The server side component of the HTTP Monitor has detected a java.lang.StackOverflowError.
This happens when there is an infinite loop in the web module.
Correct the cause of the infinite loop before running the web module again.
org.netbeans.modules.web.monitor.server.MonitorFilter.rethrow(MonitorFilter.java:1648)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:473)
mx.tegu.kdor.web.iu.ServletVerificon.processRequest(ServletVerificon.java:51)
mx.tegu.kdor.web.iu.ServletVerificon.doGet(ServletVerificon.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
mx.tegu.kdor.web.iu.ServletVerificon.processRequest(ServletVerificon.java:51)
mx.tegu.kdor.web.iu.ServletVerificon.doGet(ServletVerificon.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
mx.tegu.kdor.web.iu.ServletVerificon.processRequest(ServletVerificon.java:51)
mx.tegu.kdor.web.iu.ServletVerificon.doGet(ServletVerificon.java:70)
...
Then it just keeps repeating itself.
My servlet's processRequest method is as follows. TestData is nothing but a helper class that returns a Mapeo object if the string is known or null if it isn't.
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String h = request.getRequestURI().replaceFirst(request.getContextPath() + "/verificon/", "");
TestData td = TestData.getInstance();
Mapeo m = td.getMapeo(h);
boolean valido = false;
if(m != null) {
valido = true;
}
request.setAttribute("valido", valido);
/*
PrintWriter out = response.getWriter();
out.write("Válido?: " + valido);
out.close();
*/
String respuesta = "WEB-INF/jsp/resultado.jsp";
// Como regla general, forward se utiliza para los GET y sendRedirect para los POST
RequestDispatcher rd = request.getRequestDispatcher(respuesta);
rd.forward(request, response);
}
Any help is really appreciated.
If there is any additional information you need to know, please tell me.
Thank you!
Note 1: Line 51 of the servlet is the call to rd.forward() at the end of the processRequest method, and line 70 is simply the call to processRequest() from the doGet method.
Note 2: Everything works as expected if I comment the forward section and uncomment the PrintWriter section.
Note 3: resultado.jsp is a plain HTML page with proper doctype def, html, head and body tags and this:
<%boolean valido = (boolean)request.getAttribute("valido");%>
...
<% if(valido) {%>
<p>Válido</p>
<% } else {%>
<p>Inválido</p>
<% }%>
Look here,
String respuesta = "WEB-INF/jsp/resultado.jsp";
RequestDispatcher rd = request.getRequestDispatcher(respuesta);
// ...
You're forwarding using a relative path. It is forwarding to http://domain/context/verificon/blahblah/WEB-INF/jsp/resultado.jsp which matches the servlet again. It is in turn forwarding using a relative path to http://domain/context/verificon/blahblah/WEB-INF/jsp/resultado.jsp/WEB-INF/jsp/resultado.jsp which matches the servlet again. Etcetera. It would have made everything much more clear if you have debugged/logged the incoming request URI.
You need to forward using an absolute path instead. Prefix it with /.
String respuesta = "/WEB-INF/jsp/resultado.jsp";
// ...
Unrelated to the concrete problem, the way how you're checking the value in JSP is very clumsy and old school. Just use EL (which exist already over a decade, ensure that you're reading the proper JSP/Servlet books/tutorials):
<p>${valido ? 'Válido' : 'Inválido'}</p>
How do I pass a variable array from one servlet to another servlet?
If you're passing the current request to another servlet, then just set it as request attribute.
request.setAttribute("array", array);
request.getRequestDispatcher("/servleturl").include(request, response);
It'll be available in another servlet as follows:
Object[] array = (Object[]) request.getAttribute("array");
Or, if you're firing a brand new request to another servlet, then just set it as request parameters.
StringBuilder queryString = new StringBuilder();
for (Object item : array) {
queryString.append("array=").append(URLEncoder.encode(item, "UTF-8")).append("&");
}
response.sendRedirect("/servleturl?" + queryString);
It'll be available in another servlet as follows:
String[] array = request.getParameterValues("array");
Or, if the data is too large to be passed as request parameters (safe max length is 255 ASCII characters), then just store it in session and pass some unique key as parameter isntead.
String arrayID = UUID.randomUUID().toString();
request.getSession().setAttribute(arrayID, array);
response.sendRedirect("/servleturl?arrayID=" + arrayID);
It'll be available in another servlet as follows:
String arrayID = request.getParameter("arrayID");
Object[] array = (Object[]) request.getSession().getAttribute(arrayID);
request.getSession().removeAttribute(arrayID);
I have a controller action declared as follows:
[Authorize(Order = 0, Roles = "Requester,Controller,Installer")]
public FileStreamResult ExportJobCards()
The body of this method builds a collection of CSV lines, and attempts to return them as a file as follows:
using (var sw = new StreamWriter(new MemoryStream()))
{
foreach (var line in lines)
{
sw.WriteLine(line);
}
return new FileStreamResult(sw.BaseStream, "text/csv");
}
When I request this action using the following action link...
Html.ActionLink("Export to Excel", "ExportJobCards")
...the export method executes properly, i.e. all the required CSV data is present in the lines collection in the above code, but I get a File Not Found error rendered as the end result.
EDIT:
In agreement with Tommy's observation, I moved the return out of the using, and I now get a file, but the file is empty. The new code that actually produces a file, ableit empty, is:
var sw = new StreamWriter(new MemoryStream());
foreach (var line in lines)
{
sw.WriteLine(line);
}
sw.Flush();
return new FileStreamResult(sw.BaseStream, "text/csv");
With your current setup, the Using statement is disposing of the StringWriter before the return can complete, which is resulting in the null reference/file not found error. Remove the using statement or set the StringWriter to another variable before you exit out and you should be good to go on getting rid of the File Not Found error.
A thought on your second issue now, looking into memorystreams as filestream results, you may need to change your return to this
sw.BaseStream.seek(0, SeekOrigin.Begin)
return new FileStreamResult(sw.BaseStream, "text/csv");
as the pointer is still at the end of the stream when you return.
It throws that error because you're not giving it a file stream. What you want is the FileContentResult into which you can pass arbitrary content. This content needs to be a byte array of your content, probably easiest to:
use a stringbuilder rather than a streamwriter
get your string from the builder
use the static method System.Text.UnicodeEncoding.Unicode.GetBytes(string) to get the byte array
Give the byte array to FileContentResult
As you have to write this code anyway the easiest thing to do would be to create a new FileStringResult that inherits from the base FileResult that can take in a string or stringbuilder. Override WriteFile(HttpResponseBase response) to do the string to byte[] conversion and push that into the response. Take a look at the FileStreamResult class from the MVC sources, it's very small and easy to do.