I have an ASP.NET 3.5 SP1 web application that uses a custom JavaScriptConverter. The code used to work at some time in the past, but has stopped working. I do not know what changes have happened in the middle server side. The problem we are seeing now is that the converter is not being invoked, so we are getting errors that System.Data.DataRow cannot be serialized.
The following is the relevant portion of web.config:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="DataSetConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter, Microsoft.Web.Preview" />
<add name="DataRowConverter" type="WebUI.DataRowConverter, WebUI.DataRowConverter, Version=1.1.0.323, Culture=neutral" />
<add name="DataTableConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter, Microsoft.Web.Preview" />
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
A trimmed version of the class is as follows (trimmed only to avoid wasting space on unnecesary implementation):
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Web.Script.Serialization;
namespace WebUI {
public class DataRowConverter : JavaScriptConverter {
private ReadOnlyCollection<Type> _supportedTypes = new ReadOnlyCollection<Type>(new Type[] { typeof(DataRow) });
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
// stuff
return dr;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) {
// stuff
return dictionary;
}
public override IEnumerable<Type> SupportedTypes {
get {
return this._supportedTypes;
}
}
}
}
What seems to happen is that the class is indeed being loaded (if we take it out of web.config and the project references, no breakpoints are available; put it back into web.config and copy the DLL/PDB by hand or add it to the project, breakpoints are available), but it's not being used propertly. No breakpoint anywhere in the class is hit, and no exceptions (including one thrown in a constructor added to see what happens) are thrown. It seems like the class is being loaded but never called.
This is on IIS 7.5 and IIS 7.0 in Integrated mode, if it matters.
Anyone have any ideas?
OK, just in case anyone else hits this, when calling web services through the automatically generated test pages, the custom serializers are not invoked - they are bypassed. This is apparently by design.
Related
I am using PrimeFaces 5.3 <p:fileUpload> to upload a PNG image and I would like to show a preview of it in <p:graphicImage> before saving in database.
Here's a MCVE:
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{bean.uploadedFile}" mode="simple" />
<p:graphicImage value="#{bean.image}" />
<p:commandButton action="#{bean.preview}" ajax="false" value="Preview" />
</h:form>
private UploadedFile uploadedFile;
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
public void preview() {
// NOOP for now.
}
public StreamedContent getImage() {
if (uploadedFile == null) {
return new DefaultStreamedContent();
} else {
return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()), "image/png");
}
}
No error occurring on the backing bean, and the image won't be load and display at front-end. The client mentions that the image returned a 404 not found error.
Your problem is two-fold. It failed because the uploaded file contents is request scoped and because the image is requested in a different HTTP request. To better understand the inner working, carefully read the answers on following closely related Q&A:
Display dynamic image from database with p:graphicImage and StreamedContent
How to choose the right bean scope?
To solve the first problem, you need to read the uploaded file contents immediately in the action method associated with the form submit. In your specific case, that would look like:
private UploadedFile uploadedFile;
private byte[] fileContents;
public void preview() {
fileContents = uploadedFile.getContents();
}
// ...
To solve the second problem, your best bet is to use the data URI scheme. This makes it possible to render the image directly in the very same response and therefore you can safely use a #ViewScoped bean without facing "context not active" issues or saving the byte[] in session or disk in order to enable serving the image in a different request. Browser support on data URI scheme is currently pretty good. Replace the entire <p:graphicImage> with below:
<ui:fragment rendered="#{not empty bean.uploadedFile}">
<img src="data:image/png;base64,#{bean.imageContentsAsBase64}" />
</ui:fragment>
public String getImageContentsAsBase64() {
return Base64.getEncoder().encodeToString(imageContents);
}
Note: I assume that Java 8 is available to you as java.util.Base64 was only introduced in that version. In case you're using an older Java version, use DatatypeConverter.printBase64Binary(imageContents) instead.
In case you happen to use JSF utility library OmniFaces, you can also just use its <o:graphicImage> component instead which is on contrary to <p:graphicImage> capable of directly referencing a byte[] and InputStream bean property and rendering a data URI.
<o:graphicImage value="#{bean.imageContents}" dataURI="true" rendered="#{not empty bean.imageContents}">
Recently upgraded to version 3.2.1 of castle windsor and receiving an error when attempting to resolve a service that previously didn't occur in version 3.0 of the windsor framework.
IWindsorContainer container = new WindsorContainer();
The following code no longer works
// Throws component not found exception
InstallerHelper.ProcessAssembliesInBinDirectory(
assembly => container.Register(
Classes
.FromAssembly(assembly)
.BasedOn<IWindsorInstaller>()
.WithService.FromInterface()
.LifestyleSingleton()
));
var installers = container.ResolveAll<IWindsorInstaller>();
container.Install(installers);
// Fails here, is it related to a hashcode mismatch in SimpleTypeEqualityComparer?
var credentialCache = container.Resolve<ICredentialCache>()
// works fine if explicity install installers individually
container.Install(new CredentialsInstaller());
var credentialCache = container.Resolve<ICredentialCache>()
Where ProcessAssembliesInBinDir is:
public static void ProcessAssembliesInBinDirectory(Action<Assembly> action)
{
var directoryName = GetDirectoryName();
foreach (var dll in Directory.GetFiles(directoryName, "*.dll"))
{
var fileInfo = new FileInfo(dll);
if (!IgnoreList.Any(x=>fileInfo.Name.StartsWith(x)))
{
var assembly = Assembly.LoadFile(dll);
action(assembly);
}
}
}
Where credential installer is:
public class CredentialsInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICredentidalCache>()
.ImplementedBy<CredentidalCache>()
.LifestyleSingleton()
);
// This works fine
var credentialCache = container.Resolve<ICredentialCache>()
}
}
Class implementation
public interface ICredentidalCache {}
public class CredentidalCache : ICredentidalCache{}
This is being run from an MVC application
version 4.5 of the .net framework
the credential installer lives inside another assembly, referenced by the website
using the Windsor source, the successful attempt to resolve occurs when the typeof(ICredentialCache).GetHashCode() is the same as what has been registered. For some reason when returning out of the installer the hashcode has changed for the type. Putting a debug line inside SimpleTypeEqualityComparer.GetHashCode(Type obj) shows that hashcodes are different for the same Type.
inspecting the container inside the debugger shows the ICredentialCache successfully installed.
Edit
Manage to move forward by manually registering installers, ie. not relying on the resolve<IwindsorInstaller>() and use container.install(new Installer(), ...). If i find out more I'll update the SO question.
This works fine for me:
public sealed class AppServiceFactory
{
...
public T Create<T>()
{
return (T)container.Resolve(typeof(T));
}
...
}
AppServiceFactory.Instance.Create<IYourService>();
The problem is caused by the InstallerHelper and how it goes about loading an assembly. This SO post pointed me in the right direction,
https://stackoverflow.com/a/6675227/564957
essentially the way the assembly was loaded was failing using Assembly.LoadFile(string fileName) was causing the problem, changing this to be Assembly.Load(string assemblyName) rectified the issue.
#Eric Lippert does a good job explaining
[when] loading an assembly by its path, and one via loading the same
assembly by its assembly name... reflection will
consider types from the two loadings of the same assembly to be
different types. Any assembly loaded from its path is considered to be
distinct from an assembly loaded by its assembly name.
I have written a custom JUnit runner that I want to become part of an eclipse plugin that will launch tests using this runner without having to apply the #RunWith annotation to the class. I have managed to get an additional item under the 'Run As' context menu, using the org.eclipse.debug.ui.launchShortcuts extension point. However, I am not sure how to invoke the test using my custom runner.
So I figured out a way to do what I wanted. However, it does seem a bit hacky. But, I thought that I would post the answer here in case someone else runs into the same problem.
First you have to register a junit kind like this:
<extension point="org.eclipse.jdt.junit.internal_testKinds">
<kind
id="my.junit.kind"
displayName="Your Kind Name"
finderClass="org.eclipse.jdt.internal.junit.launcher.JUnit4TestFinder"
loaderPluginId="org.eclipse.jdt.junit4.runtime"
loaderClass="your.test.loader.MyLoaderClass">
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit4.runtime" />
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit.core" />
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit.runtime"/>
</kind>
</extension>
In the xml you have to specify a custom implementation of org.eclipse.jdt.internal.junit.runner.ITestLoaderwhich in turn returns an implementation of org.eclipse.jdt.internal.junit.runner.ITestReference. The core part is the implementation of ITestReference, because this is where you create an instance of your custom JUnit runner.
public class MyTestReference extends JUnit4TestReference
{
public MyTestReference(final Class<?> p_clazz, String[] p_failureNames)
{
super(new Request()
{
#Override
public Runner getRunner()
{
return new MyCustomRunner(p_clazz);
}
}, p_failureNames);
}
...
}
Then finally you have to link this with a launch shortcut that sets the kind appropriately
public class MyJunitLaunchShortcut extends JUnitLaunchShortcut
{
#Override
protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement p_element) throws CoreException
{
ILaunchConfigurationWorkingCopy config = super.createLaunchConfiguration(p_element);
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, "my.junit.kind");
return config;
}
}
This does use a bunch of internal classes, so there is probably a better way. But this seems to work.
I've read a lot of examples/tutorials (incl. Ayende's Alexandria on MSDN).
But just getting somewhat updated assemblies have proven to be an obstacle in itself. After getting the correct version of Castle.Windsor - it cannot find the correct section in the app.config file. The syntax in both Rhino Service Bus and the CastleBootstrapper has been changed as well - and I'm now totally confused. The 'documentation' on Hibernating Rhinos is really not helping me get started.
Could anyone please help me a working sample with Rhino Service Bus with either Castle Windsor v. 3.0 (beta) or 2.5.3, point me at something already online or just giving me a step-by-step pointers on what I need to get up and running?
after downloading the latest Rhino-ESB bits from github (https://github.com/hibernating-rhinos/rhino-esb) and building it, it's pretty straightforward to get started.
I have a asp.net MVC application which communicates with a backend through Rhino-ESB.
On the asp.net MVC side:
On global.asax.cs:
private IWindsorContainer _container;
protected void Application_Start()
{
_container = new WindsorContainer();
new RhinoServiceBusConfiguration().UseCastleWindsor(_container).Configure();
_container.Install(new YourCustomInstaller());
//Don't forget to start the bus
_container.Resolve<IStartableServiceBus>().Start();
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container));
}
Note that YourCustomInstaller must implement IWindsorInstaller and you register your controllers with the container in the Installmethod:
public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(Component
.For<HomeController>().LifeStyle.PerWebRequest.ImplementedBy<HomeController>());
Also note that the WindsorControllerFactory internally delegates controller creation to the container:
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return null;
return (IController)this.container.Resolve(controllerType);
}
Last but not least, provide the configuration on your web.config
<configSections>
<section name="rhino.esb" type="Rhino.ServiceBus.Config.BusConfigurationSection, Rhino.ServiceBus"/>
</configSections>
<rhino.esb>
<bus threadCount="1"
numberOfRetries="5"
endpoint="rhino.queues://localhost:31316/Client"
queueIsolationLevel="ReadCommitted"
name="Client"/>
<messages>
<add name="YourMessagesNamespace"endpoint="rhino.queues://localhost:31315/Backend"/>
</messages>
</rhino.esb>
This configuration assumes that the backend runs a queue in localhost:31315 and the client runs its queue on localhost:31316.
On the backend side:
assuming we're running it as a console application,
static void Main(string[] args)
{
IWindsorContainer container;
container = new WindsorContainer();
new RhinoServiceBusConfiguration()
.UseCastleWindsor(container)
.Configure();
var host = new RemoteAppDomainHost(typeof(YourBootstrapper));
host.Start();
Console.WriteLine("Starting to process messages");
Console.ReadLine();
Notice that YourBootstrapperclass implements CastleBootstrapper
public class YourBootstrapper: Rhino.ServiceBus.Castle.CastleBootStrapper
{
protected override void ConfigureContainer()
{
Container.Register(Component.For<OneOfYourMessages>());
}
}
in which we're registering a consumer for OneOfYourMessages
I'm really stumped on this incredibly simple mapping. It looks just like one of the examples even. If I comment out the internal structure, it'll run the binding compiler successfully. If I put the internal structure back in, it fails. Note that the internal structure is just defining the XML. This is basically example5 of the JIBX tutorial examples.
<binding>
<mapping name="RequestTransaction" class="TransactionRequest">
<value name="version" set-method="setVersion" get-method="getVersion" style="attribute" />
<structure name="transHeader">
<value name="requestCount" set-method="setRequestCount" get-method="getRequestCount"/>
</structure>
</mapping>
<binding>
Then I get the following error on the jibx compile:
Error: Error during validation: null; on mapping element at (line 2, col 97, in jibx-binding.xml)
I'm absolutely stumped and out of ideas. Google shows nothing useful.
The <structure> is arguably the most important concept in JiBX binding because it allows you to map arbitrary XML to your Java classes without forcing you to create bloated and ugly layers of nested Java objects and classes to match the XML design.
In this case your binding declares that you have an XML element named <transHeader> that will not be present in your Java class.
With some slight fixes to your XML format, your binding works perfectly. I assume the fact that your binding has two <binding> open tags rather than and open and close <binding></binding> is a typo, because you said you got it to work without the structure. Also add <?xml version="1.0"?> at the top of your binding file. Those two XML mods allow the JiBX 1.2 binding compiler to work with the following Java class:
(Note: you didn't provide the Java class this binding is for so I had to reconstruct it from the info you put in the binding file. The obvious side effect of this is that I reconstructed a class that will work with this binding. But the simple fact is that a JiBX binding by design contains all the info you need to know about the class and the XML.)
public class TransactionRequest {
private String version;
private int requestCount;
public void setVersion(String ver) {
version = ver;
}
public String getVersion() {
return version;
}
public void setRequestCount(int count) {
requestCount = count;
}
public int getRequestCount() {
return requestCount;
}
}
compile the class then run the binding compiler with:
>java -jar jibx-bind.jar jibx-binding.xml
To test it I used the following sample.xml:
(Note: you also didn't provide the XML you are trying to map so again I created a sample based on what you did provide)
<?xml version="1.0"?>
<RequestTransaction version="0.1">
<transHeader>
<requestCount>3</requestCount>
</transHeader>
</RequestTransaction>
Running the test uses the following code:
public static void main(String[] argz) {
String fileName = "./sample.xml";
IBindingFactory bfact = null;
IUnmarshallingContext uctx = null;
TransactionRequest sample = null;
try {
bfact = BindingDirectory.getFactory(TransactionRequest.class);
uctx = bfact.createUnmarshallingContext();
InputStream in = new FileInputStream(fileName);
sample = (TransactionRequest)uctx.unmarshalDocument(in, null);
System.out.println(sample.getRequestCount());
System.out.println(sample.getVersion());
}
catch (Exception e) {
e.printStackTrace();
}
}
And it runs successfully.
It's been a while now, but I found it was related to inheritance. I needed to give mappings for everything in the inheritance tree, including interfaces as I recall.
I ended up creating a wrapper object, which I've found seems to be the easiest way to use JIBX in general. Trying to map a true domain class causes tendrils into every class that class touches and I have to unjar everything so JIBX can find the classes, including 3rd party libs.