Silverlight bingMapContril using LocalproxyPage to downLoad MapTiles Extremely Slow - silverlight-4.0

as we know silverlight5 has ability to get pageElement's visual so we can print or save them as pictrue.but if your MapTilesSource uri is in a differentDomain to your silverlight Application host site,you can not get BingMapControl's visual,because of "cross-domain problem",clr would throw a System.Security.SecurityException.
To avoid this problem I add a Proxy aspx page in the silverlight host site,which can send bingMap TileImage request to the remote MapTilesService.
here is my customer Class inherit from TileSource:
public class GoogleTileSource : TileSource
{
public GoogleTileSource()
: base("http://mt{0}.google.cn/vt/lyrs={1}#180000000&hl=zh-CN&gl=cn&z={2}&x={3}&y={4}")
{
this.Type = GoogleTileType.Hybrid;
}
public override Uri GetUri(int x, int y, int zoomLevel)
{
string TargetUrl = string.Format(this.UriFormat, this.Server, (char)this.Type, zoomLevel, x, y);
return new Uri(string.Format(http://localhost:52879/MapTilesServerProxy.aspx + "?sourceUrl={0}", TargetUrl));
//return new Uri(string.Format(this.UriFormat, this.Server, (char)this.Type, zoomLevel, x, y));
}
public int Server
{
get;
set;
}
public GoogleTileType Type
{
get;
set;
}
}
here is my proxy page code:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="MapTilesServerProxy.aspx.cs" Inherits="AeroZH.Web.MapTilesServerProxy" %>
<%# Import Namespace=System.Net %>
<%# Import Namespace=System.IO %>
<%# Import Namespace=System.Diagnostics %>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ProxyRequest();
}
private void ProxyRequest()
{
try
{
string url = "";
url = this.Page.Request.Url.AbsoluteUri.Split(new string[] { "?sourceUrl=" }, StringSplitOptions.RemoveEmptyEntries)[1];
Debug.WriteLine("url:" + url);
Debug.WriteLine(url + "——requestTime:" + System.DateTime.Now);
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(url);
loHttp.Timeout = 10000; // 10 secs
loHttp.UserAgent = "Web Client";
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
Debug.WriteLine(url + "——responseTime:" + System.DateTime.Now);
using (Stream inputStream = loWebResponse.GetResponseStream())
{
byte[] buffer = new byte[4096 * 100];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
} while (bytesRead != 0);
Response.BinaryWrite(buffer);
Response.End();
}
loWebResponse.Close();
if (loHttp != null)
loHttp.Abort();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
after this work,bingMapcontrol successfully make its image request thought the proxy page ,and the ProxyPage's request get response form remote server is also success.but only a few mapTiles show in the map.
I using debug.write to trace response status,almost everyRequest has correct response,i don't know why only few mapTiles show in map.

First off, using Google map tiles in Bing Maps is against the terms of use of both the Bing Maps and Google Maps terms of use.
Secondly, The Bing Maps Silverlight control is nearing end of life. The documentation is already offline and it won't be long before the control is disabled. No new development should be one with it. Also, the end of life for Silverlight in general was announced a few years ago.

Related

How to stream text data with JAX-RS continuously

I read multiple questions that are similar to mine and found this: https://stackoverflow.com/a/34358215/12550134
But I am not able to do this. I use plain JAX-RS API and Open Liberty as my server. Unfortunately the ResourceConfig cannot be found, so I cannot disable the buffer, as described in the answer above.
This is my code:
#GET
#Produces(MediaType.TEXT_PLAIN)
public Response sayHelloStream() {
LOGGER.debug("calling sayHelloStream");
StreamingOutput out = outputStream -> {
Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream));
for (int i = 0; i < 999999999; i++) {
writer.write("Hello\n");
writer.flush();
try {
LOGGER.debug("before sleep");
TimeUnit.SECONDS.sleep(3);
LOGGER.debug("after sleep");
} catch (InterruptedException e) {
LOGGER.error("error with the timer", e);
}
}
};
return Response.ok(out).build();
}
When calling it in the browser nothing happens. To my understanding due to the buffer. How am I able to stream text data like this using plain JAX-RS?
I would use the SSE extension. AFAIK it's part of the JAX-RS API, allthough you might need an extra module to enable it server-side:
https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/sse.html
...
import javax.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseEventSink;
import javax.ws.rs.sse.OutboundSseEvent;
...
#Path("events")
public static class SseResource {
#GET
#Produces(MediaType.SERVER_SENT_EVENTS)
public void getServerSentEvents(#Context SseEventSink eventSink, #Context Sse sse) {
new Thread(() -> {
for (int i = 0; i < 10; i++) {
// ... code that waits 1 second
final OutboundSseEvent event = sse.newEventBuilder()
.name("message-to-client")
.data(String.class, "Hello world " + i + "!")
.build();
eventSink.send(event);
}
}).start();
}
}
It streams text data to the client in chunks in the SSE format, so it can easily be handled in the browser using e.g. the HTML5 <eventsource> element or the EventSource JavaScript API.
var source = new EventSource('.../events');
source.addEventListener('message-to-client', function(e) {
console.log(e.data);
}, false);

Keep connection alive for streaming in ASP.NET Core

I'm making a small web application which is built on ASP.NET Core. My application is for streaming video from clients to clients through service.
I've followed this post :
http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/
I've implemented the application of tutorial successfully, but, that was for streaming Video from server to clients.
What I wanna do now is :
Clients register to service for streaming. (using video or audio tag)
Service receives client submitted data (submit through POSTMAN)
Service broadcast the data to its every registered clients.
Here is what I've implemented:
(Index.cshtml)
<div>
<video width="480"
height="320"
controls="controls"
autoplay="autoplay">
<source src="/api/video/initiate"
type="video/mp4">
</source>
</video>
</div>
StreamingService
public class StreamingService: IStreamingService
{
public IList<Stream> Connections {get;set;}
public StreamingService()
{
Connections = new List<Stream>();
}
public byte[] AnalyzeStream(Stream stream)
{
long originalPosititon = 0;
if (stream.CanSeek)
{
originalPosititon = stream.Position;
stream.Position = 0;
}
try
{
var readBuffer = new byte[4096];
int bytesReader;
while ((byteRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
{
totalBytesRead += byteRead;
if (totalBytesRead == readBuffer.Length)
{
var nextByte = stream.ReadByte();
if (nextByte != -1)
{
var temp = new byte[readBuffer * 2];
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
readBuffer = temp;
totalBytesRead++;
}
}
}
var buffer = readBuffer;
if (readBuffer.Length != totalBytesRead)
{
buffer = new byte[totalBytesRead];
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
return buffer;
}
finally
{
if (stream.CanSeek)
stream.Position = originalPosititon;
}
}
}
VideoController
public class VideoController: Controller
{
private readonly IStreamingService _streamingService;
private readonly IHostingEnvironment _hostingEnvironment;
public VideoController(IStreamingService streamingService, IHostingEnvironment hostingEnvironment)
{
_streamingService = streamingService;
_hostingEnvironment = hostingEnvironment;
}
[HttpGet("initiate")]
public IActionResult Initiate()
{
_streamingService.Connections.Add(Response.Body);
}
[HttpPost("broadcast")]
public async Task<IActionResult> Broadcast()
{
// Retrieve data submitted from POSTMAN.
var data = _streamingService.AnalyzeStream(Request.Body);
foreach (var stream in _streamingService.Connections)
{
try
{
await stream.WriteAsync(data, 0, data.Length);
}
catch (Exception exception)
{
stream.Dispose();
_streamingService.Connections.Remove(stream);
}
}
}
}
When I send data from POSTMAN through api/video/broadcast . For loop ran and I got an exception said the stream has been disposed.
My question is:
How can I keep the stream alive for streaming ?
(Stream created in api/video/initiate is kept alive and when a client calls api/video/broadcast , all initiated stream will update its date without having disposed)
Thank you,
Is it an option to keep the stream in cache?
You can read more about it here. The simplest way it to add the cache services to the dependency injection container and the request the concrete implementation of IMemoryCache through constructor injection in your VideoController (as you've done with IStreamingService and IHostingEnvironment).
Just add the stream to the cache and use the cached stream the next time api/video/broadcast is hit.
Be aware though that if you are on a webfarm or hosted in the cloud it is recommended to use Distributed Cache like Redis Cache, or else your cache could disapear unexpected. I use Azure Redis Cache for instance which works great!

How can I use iText to convert HTML with images and hyperlinks to PDF?

I'm trying to convert HTML to PDF using iTextSharp in an ASP.NET web application that uses both MVC, and web forms. The <img> and <a> elements have absolute and relative URLs, and some of the <img> elements are base64. Typical answers here at SO and Google search results use generic HTML to PDF code with XMLWorkerHelper that looks something like this:
using (var stringReader = new StringReader(xHtml))
{
using (Document document = new Document())
{
PdfWriter writer = PdfWriter.GetInstance(document, stream);
document.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(
writer, document, stringReader
);
}
}
So with sample HTML like this:
<div>
<h3>HTML Works, but Broken in Converted PDF</h3>
<div>Relative local <img>: <img src='./../content/images/kuujinbo_320-30.gif' /></div>
<div>
Base64 <img>:
<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' />
</div>
<div><a href='/somePage.html'>Relative local hyperlink, broken in PDF</a></div>
<div>
The resulting PDF: (1) is missing all images, and (2) all hyperlink(s) with relative URLs are broken and use a file URI scheme (file///XXX...) instead of pointing to the correct web site.
Some answers here at SO and others from Google search recommend replacing relative URLs with absolute URLs, which is perfectly acceptable for one-off cases. However, globally replacing all <img src> and <a href> attributes with a hard-coded string is unacceptable for this question, so please do not post an answer like that, because it will accordingly be downvoted.
Am looking for a solution that works for many different web applications residing in test, development, and production environments.
Out of the box XMLWorker only understands absolute URIs, so the described issues are expected behavior. The parser can't automagically deduce URI schemes or paths without some additional information.
Implementing an ILinkProvider fixes the broken hyperlink problem, and implementing an IImageProvider fixes the broken image problem. Since both implementations must perform URI resolution, that's the first step. The following helper class does that, and also tries to make web (ASP.NET) context calls (examples follow) as simple as possible:
// resolve URIs for LinkProvider & ImageProvider
public class UriHelper
{
/* IsLocal; when running in web context:
* [1] give LinkProvider http[s] scheme; see CreateBase(string baseUri)
* [2] give ImageProvider relative path starting with '/' - see:
* Join(string relativeUri)
*/
public bool IsLocal { get; set; }
public HttpContext HttpContext { get; private set; }
public Uri BaseUri { get; private set; }
public UriHelper(string baseUri) : this(baseUri, true) {}
public UriHelper(string baseUri, bool isLocal)
{
IsLocal = isLocal;
HttpContext = HttpContext.Current;
BaseUri = CreateBase(baseUri);
}
/* get URI for IImageProvider to instantiate iTextSharp.text.Image for
* each <img> element in the HTML.
*/
public string Combine(string relativeUri)
{
/* when running in a web context, the HTML is coming from a MVC view
* or web form, so convert the incoming URI to a **local** path
*/
if (HttpContext != null && !BaseUri.IsAbsoluteUri && IsLocal)
{
return HttpContext.Server.MapPath(
// Combine() checks directory traversal exploits
VirtualPathUtility.Combine(BaseUri.ToString(), relativeUri)
);
}
return BaseUri.Scheme == Uri.UriSchemeFile
? Path.Combine(BaseUri.LocalPath, relativeUri)
// for this example we're assuming URI.Scheme is http[s]
: new Uri(BaseUri, relativeUri).AbsoluteUri;
}
private Uri CreateBase(string baseUri)
{
if (HttpContext != null)
{ // running on a web server; need to update original value
var req = HttpContext.Request;
baseUri = IsLocal
// IImageProvider; absolute virtual path (starts with '/')
// used to convert to local file system path. see:
// Combine(string relativeUri)
? req.ApplicationPath
// ILinkProvider; absolute http[s] URI scheme
: req.Url.GetLeftPart(UriPartial.Authority)
+ HttpContext.Request.ApplicationPath;
}
Uri uri;
if (Uri.TryCreate(baseUri, UriKind.RelativeOrAbsolute, out uri)) return uri;
throw new InvalidOperationException("cannot create a valid BaseUri");
}
}
Implementing ILinkProvider is pretty simple now that UriHelper gives the base URI. We just need the correct URI scheme (file or http[s]):
// make hyperlinks with relative URLs absolute
public class LinkProvider : ILinkProvider
{
// rfc1738 - file URI scheme section 3.10
public const char SEPARATOR = '/';
public string BaseUrl { get; private set; }
public LinkProvider(UriHelper uriHelper)
{
var uri = uriHelper.BaseUri;
/* simplified implementation that only takes into account:
* Uri.UriSchemeFile || Uri.UriSchemeHttp || Uri.UriSchemeHttps
*/
BaseUrl = uri.Scheme == Uri.UriSchemeFile
// need trailing separator or file paths break
? uri.AbsoluteUri.TrimEnd(SEPARATOR) + SEPARATOR
// assumes Uri.UriSchemeHttp || Uri.UriSchemeHttps
: BaseUrl = uri.AbsoluteUri;
}
public string GetLinkRoot()
{
return BaseUrl;
}
}
IImageProvider only requires implementing a single method, Retrieve(string src), but Store(string src, Image img) is easy - note inline comments there and for GetImageRootPath():
// handle <img> elements in HTML
public class ImageProvider : IImageProvider
{
private UriHelper _uriHelper;
// see Store(string src, Image img)
private Dictionary<string, Image> _imageCache =
new Dictionary<string, Image>();
public virtual float ScalePercent { get; set; }
public virtual Regex Base64 { get; set; }
public ImageProvider(UriHelper uriHelper) : this(uriHelper, 67f) { }
// hard-coded based on general past experience ^^^
// but call the overload to supply your own
public ImageProvider(UriHelper uriHelper, float scalePercent)
{
_uriHelper = uriHelper;
ScalePercent = scalePercent;
Base64 = new Regex( // rfc2045, section 6.8 (alphabet/padding)
#"^data:image/[^;]+;base64,(?<data>[a-z0-9+/]+={0,2})$",
RegexOptions.Compiled | RegexOptions.IgnoreCase
);
}
public virtual Image ScaleImage(Image img)
{
img.ScalePercent(ScalePercent);
return img;
}
public virtual Image Retrieve(string src)
{
if (_imageCache.ContainsKey(src)) return _imageCache[src];
try
{
if (Regex.IsMatch(src, "^https?://", RegexOptions.IgnoreCase))
{
return ScaleImage(Image.GetInstance(src));
}
Match match;
if ((match = Base64.Match(src)).Length > 0)
{
return ScaleImage(Image.GetInstance(
Convert.FromBase64String(match.Groups["data"].Value)
));
}
var imgPath = _uriHelper.Combine(src);
return ScaleImage(Image.GetInstance(imgPath));
}
// not implemented to keep the SO answer (relatively) short
catch (BadElementException ex) { return null; }
catch (IOException ex) { return null; }
catch (Exception ex) { return null; }
}
/*
* always called after Retrieve(string src):
* [1] cache any duplicate <img> in the HTML source so the image bytes
* are only written to the PDF **once**, which reduces the
* resulting file size.
* [2] the cache can also **potentially** save network IO if you're
* running the parser in a loop, since Image.GetInstance() creates
* a WebRequest when an image resides on a remote server. couldn't
* find a CachePolicy in the source code
*/
public virtual void Store(string src, Image img)
{
if (!_imageCache.ContainsKey(src)) _imageCache.Add(src, img);
}
/* XMLWorker documentation for ImageProvider recommends implementing
* GetImageRootPath():
*
* http://demo.itextsupport.com/xmlworker/itextdoc/flatsite.html#itextdoc-menu-10
*
* but a quick run through the debugger never hits the breakpoint, so
* not sure if I'm missing something, or something has changed internally
* with XMLWorker....
*/
public virtual string GetImageRootPath() { return null; }
public virtual void Reset() { }
}
Based on the XML Worker documentation it's pretty straightforward to hook the implementations of ILinkProvider and IImageProvider above into a simple parser class:
/* a simple parser that uses XMLWorker and XMLParser to handle converting
* (most) images and hyperlinks internally
*/
public class SimpleParser
{
public virtual ILinkProvider LinkProvider { get; set; }
public virtual IImageProvider ImageProvider { get; set; }
public virtual HtmlPipelineContext HtmlPipelineContext { get; set; }
public virtual ITagProcessorFactory TagProcessorFactory { get; set; }
public virtual ICSSResolver CssResolver { get; set; }
/* overloads simplfied to keep SO answer (relatively) short. if needed
* set LinkProvider/ImageProvider after instantiating SimpleParser()
* to override the defaults (e.g. ImageProvider.ScalePercent)
*/
public SimpleParser() : this(null) { }
public SimpleParser(string baseUri)
{
LinkProvider = new LinkProvider(new UriHelper(baseUri, false));
ImageProvider = new ImageProvider(new UriHelper(baseUri, true));
HtmlPipelineContext = new HtmlPipelineContext(null);
// another story altogether, and not implemented for simplicity
TagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
CssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
}
/*
* when sending XHR via any of the popular JavaScript frameworks,
* <img> tags are **NOT** always closed, which results in the
* infamous iTextSharp.tool.xml.exceptions.RuntimeWorkerException:
* 'Invalid nested tag a found, expected closing tag img.' a simple
* workaround.
*/
public virtual string SimpleAjaxImgFix(string xHtml)
{
return Regex.Replace(
xHtml,
"(?<image><img[^>]+)(?<=[^/])>",
new MatchEvaluator(match => match.Groups["image"].Value + " />"),
RegexOptions.IgnoreCase | RegexOptions.Multiline
);
}
public virtual void Parse(Stream stream, string xHtml)
{
xHtml = SimpleAjaxImgFix(xHtml);
using (var stringReader = new StringReader(xHtml))
{
using (Document document = new Document())
{
PdfWriter writer = PdfWriter.GetInstance(document, stream);
document.Open();
HtmlPipelineContext
.SetTagFactory(Tags.GetHtmlTagProcessorFactory())
.SetLinkProvider(LinkProvider)
.SetImageProvider(ImageProvider)
;
var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
var htmlPipeline = new HtmlPipeline(HtmlPipelineContext, pdfWriterPipeline);
var cssResolverPipeline = new CssResolverPipeline(CssResolver, htmlPipeline);
XMLWorker worker = new XMLWorker(cssResolverPipeline, true);
XMLParser parser = new XMLParser(worker);
parser.Parse(stringReader);
}
}
}
}
As commented inline, SimpleAjaxImgFix(string xHtml) specifically handles XHR that may send unclosed <img> tags, which is valid HTML, but invalid XML that will break XMLWorker . A simple explanation & implementation of how to receive a PDF or other binary data with XHR and iTextSharp can be found here.
A Regex was used in SimpleAjaxImgFix(string xHtml) so that anyone using (copy/paste?) the code doesn't need to add another nuget package, but a HTML parser like HtmlAgilityPack should be used, since it's turns this:
<div><img src='a.gif'><br><hr></div>
into this:
<div><img src='a.gif' /><br /><hr /></div>
with only a few lines of code:
var hDocument = new HtmlDocument()
{
OptionWriteEmptyNodes = true,
OptionAutoCloseOnEnd = true
};
hDocument.LoadHtml("<div><img src='a.gif'><br><hr></div>");
var closedTags = hDocument.DocumentNode.WriteTo();
Also of note - use SimpleParser.Parse() above as a general blueprint to additionally implement a custom ICSSResolver or ITagProcessorFactory, which is explained in the documentation.
Now the issues described in the question should be taken care of. Called from a MVC Action Method:
[HttpPost] // some browsers have URL length limits
[ValidateInput(false)] // or throws HttpRequestValidationException
public ActionResult Index(string xHtml)
{
Response.ContentType = "application/pdf";
Response.AppendHeader(
"Content-Disposition", "attachment; filename=test.pdf"
);
var simpleParser = new SimpleParser();
simpleParser.Parse(Response.OutputStream, xHtml);
return new EmptyResult();
}
or from a Web Form that gets HTML from a server control:
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=test.pdf");
using (var stringWriter = new StringWriter())
{
using (var htmlWriter = new HtmlTextWriter(stringWriter))
{
ConvertControlToPdf.RenderControl(htmlWriter);
}
var simpleParser = new SimpleParser();
simpleParser.Parse(Response.OutputStream, stringWriter.ToString());
}
Response.End();
or a simple HTML file with hyperlinks and images on the file system:
<h1>HTML Page 00 on Local File System</h1>
<div>
<div>
Relative <img>: <img src='Images/alt-gravatar.png' />
</div>
<div>
Hyperlink to file system HTML page:
<a href='file-system-html-01.html'>Page 01</a>
</div>
</div>
or HTML from a remote web site:
<div>
<div>
<img width="200" alt="Wikipedia Logo"
src="portal/wikipedia.org/assets/img/Wikipedia-logo-v2.png">
</div>
<div lang="en">
English
</div>
<div lang="en">
iText
</div>
</div>
Above two HTML snippets run from a console app:
var filePaths = Path.Combine(basePath, "file-system-html-00.html");
var htmlFile = File.ReadAllText(filePaths);
var remoteUrl = Path.Combine(basePath, "wikipedia.html");
var htmlRemote = File.ReadAllText(remoteUrl);
var outputFile = Path.Combine(basePath, "filePaths.pdf");
var outputRemote = Path.Combine(basePath, "remoteUrl.pdf");
using (var stream = new FileStream(outputFile, FileMode.Create))
{
var simpleParser = new SimpleParser(basePath);
simpleParser.Parse(stream, htmlFile);
}
using (var stream = new FileStream(outputRemote, FileMode.Create))
{
var simpleParser = new SimpleParser("https://wikipedia.org");
simpleParser.Parse(stream, htmlRemote);
}
Quite a long answer, but taking a look at questions here at SO tagged html, pdf, and itextsharp, as of this writing (2016-02-23) there are 776 results against 4,063 total tagged itextsharp - that's 19%.
Very helpful post,
I was problem to render images in my report html to pdf. with your post I could do it.
I'm working with asp.mvc 5.
I only have to change this method of the ImageProviderClass
public virtual string GetImageRootPath() { return null; }
to
public virtual string GetImageRootPath() { HostingEnvironment.MapPath("~/Content/Images/") }
thanks!

Sharepoint 2010 Web Part Communication - How to make consumer wait for the provider

I have a series of web parts I need to implement in SharePoint 2010. The data provider web part uses an UpdatePanel and asynchronously makes a web service call which can potentially be slow. To keep it simple, I've put a single consumer web part on the page (Chart) which will use the consumer as its data provider.
My problem is that I can't get the consumer to wait for the provider - I get a variety of errors but all basically come back to "There is no data available". This may be because it is a Chart web part but the question also applies to the other custom parts I will be developing as they will pull the same data.
The question is: how do I either push data to my consumers when my provider is ready or somehow let them wait for my provider to have data (via polling or whatever).
Note: this is just a prototype, I haven't added error handling, etc yet.
Code is below:
[ToolboxItem(true)]
public partial class ClarityProjectGeneral : System.Web.UI.WebControls.WebParts.WebPart , IWebPartTable
{
public DataTable ProjectVitals = new DataTable(); For web part communication
// bunch of properties
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
InitializeControl();
// For web part communication
// Initialize our datatable so the chart doesn't barf
DataColumn col = new DataColumn();
col.DataType = typeof(string);
col.ColumnName = "Name";
this.ProjectVitals.Columns.Add(col);
col = new DataColumn();
col.DataType = typeof(DateTime);
col.ColumnName = "Start";
this.ProjectVitals.Columns.Add(col);
col = new DataColumn();
col.DataType = typeof(DateTime);
col.ColumnName = "End";
this.ProjectVitals.Columns.Add(col);
}
protected void Page_Load(object sender, EventArgs e)
{
loading.Visible = true;
content.Visible = false;
}
public ClarityObjectClasses.Projects GetProject(string projectID)
{
Clarity.ClarityAbstractorProject ca = new Clarity.ClarityAbstractorProject(this.Username, this.Password);
Dictionary<string, string> queryParams = new Dictionary<string, string>();
queryParams.Add("projectID", projectID);
// Class for making web service call
ClarityObjectClasses.Projects response = new ClarityObjectClasses.Projects();
response = ca.GetProject(queryParams);
return response;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
if (this.ProjectID == null || this.Username == null || this.Password == null)
{
lblConfigError.Visible = true;
lblConfigError.Text = "One or more required configuration values are not set. Please check the web part configuration.";
panelProjectDetails.Visible = false;
}
else
{
loading.Visible = true;
content.Visible = false;
panelProjectDetails.Visible = true;
ClarityObjectClasses.Projects projects = GetProject(this.ProjectID);
//Assign a bunch of values
// For web part communication
LoadTable(projects.Project[0]);
Timer1.Enabled = false;
loading.Visible = false;
content.Visible = true;
}
}
/* Interface functions for Graph Chart communication */
For web part communication
protected void LoadTable(ClarityObjectClasses.Project project)
{
DataRow row = ProjectVitals.NewRow();
row["Name"] = project.name;
row["Start"] = project.start;
row["End"] = project.finish;
this.ProjectVitals.Rows.Add(row);
}
public PropertyDescriptorCollection Schema
{
get
{
return TypeDescriptor.GetProperties(ProjectVitals.DefaultView[0]);
}
}
public void GetTableData(TableCallback callback)
{
callback(ProjectVitals.Rows);
}
public bool ConnectionPointEnabled
{
get
{
object o = ViewState["ConnectionPointEnabled"];
return (o != null) ? (bool)o : true;
}
set
{
ViewState["ConnectionPointEnabled"] = value;
}
}
[ConnectionProvider("Table", typeof(TableProviderConnectionPoint), AllowsMultipleConnections = true)]
public IWebPartTable GetConnectionInterface()
{
return this;
}
public class TableProviderConnectionPoint : ProviderConnectionPoint
{
public TableProviderConnectionPoint(MethodInfo callbackMethod, Type interfaceType, Type controlType, string name, string id, bool allowsMultipleConnections)
: base(callbackMethod, interfaceType, controlType, name, id, allowsMultipleConnections)
{
}
public override bool GetEnabled(Control control)
{
return ((ClarityProjectGeneral)control).ConnectionPointEnabled;
}
}
}
Do not quite understand, but if it helps
You may not use "connectable" web-parts inside UpdatePanel,
because of lack of corresponding events to bind data on asynchronous callback.
I just stumbled across this. I had exactly the same problem trying to implement a custom webpart just as a proof to myself. I applied filters to both my webpart and a list, and then let a chart consume them. What I found was that my webpart sent the wrong data, but the list webpart worked as expected.
So I reflected the XsltListViewWebPart (or whatever it's exact name is) and I discovered that there is an IConnectionData interface. This allows you to specify the dependencies and get the correct delay binding you need. GetRequiresData indicates that there are still more connections to be consumed before the data can be requested.

JavaFX: File upload to REST service / servlet fails because of missing boundary

I'm trying to upload a file using JavaFX using the HttpRequest. For this purpose I have written the following function.
function uploadFile(inputFile : File) : Void {
// check file
if (inputFile == null or not(inputFile.exists()) or inputFile.isDirectory()) {
return;
}
def httpRequest : HttpRequest = HttpRequest {
location: urlConverter.encodeURL("{serverUrl}");
source: new FileInputStream(inputFile)
method: HttpRequest.POST
headers: [
HttpHeader {
name: HttpHeader.CONTENT_TYPE
value: "multipart/form-data"
}
]
}
httpRequest.start();
}
On the server side, I am trying to handle the incoming data using the Apache Commons FileUpload API using a Jersey REST service. The code used to do this is a simple copy of the FileUpload tutorial on the Apache homepage.
#Path("Upload")
public class UploadService {
public static final String RC_OK = "OK";
public static final String RC_ERROR = "ERROR";
#POST
#Produces("text/plain")
public String handleFileUpload(#Context HttpServletRequest request) {
if (!ServletFileUpload.isMultipartContent(request)) {
return RC_ERROR;
}
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = null;
try {
items = upload.parseRequest(request);
}
catch (FileUploadException e) {
e.printStackTrace();
return RC_ERROR;
}
...
}
}
However, I get a exception at items = upload.parseRequest(request);:
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
I guess I have to add a manual boundary info to the InputStream. Is there any easy solution to do this? Or are there even other solutions?
Have you tried just using the InputStream from HttpServletRequest like so
InputStream is = httpRequest.getInputStream();
BufferedInputStream in = new BufferedInputStream(is);
//Write out bytes
out.close();
is.close();