Loading more than URL in The same browser using jxbrowser - url

I'am using jxbrowser,
This code loads one URL in one browser and saves it's page .
public class JxBrowserDemo {
public JxBrowserDemo(String url) {
Browser browser = new Browser();
browser.addLoadListener(new LoadAdapter() {
#Override
public void onFinishLoadingFrame(FinishLoadingEvent event) {
if (event.isMainFrame()){
String filePath = "G:\\Test\\index"+System.currentTimeMillis()+".html";
String dirPath = "G:\\Test\\resources";
event.getBrowser().saveWebPage(filePath, dirPath, SavePageType.COMPLETE_HTML);
}
}
});
browser.loadURL(url);
if(!browser.isLoading())
{
browser.dispose();
}
}
public static void main(String args[])
{
JxBrowserDemo jxBrowserDemo=new JxBrowserDemo("www.google.com");
}
}
could I load more than URL in the same browser and save it's pages in Local Path ?
Thanks In advance ............

You can load one by one as many URLs as you want and save these web pages by the saveWebPage() method in the same browser.
You should completely load the web page, invoke the saveWebPage() method, wait until the web page is saved, and then repeat these actions with the next URL.
The dispose() method should be invoked when you don't need to perform any actions with this browser instance.

Related

NHibernate session is closed when refreshing page

This is another strange problem I've encountered this days!!! I've created and MVC 4 app using nhibernate. and added a filter attribute named [LoggingNHibernateSessionAttribute] on my HomeController which manages session for each action. I've followed 'ASP.NET MVC4 and the Web API published by Apress'.
public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
{
private readonly IActionLogHelper _actionLogHelper;
private readonly IActionExceptionHandler _actionExceptionHandler;
private readonly IActionTransactionHelper _actionTransactionHelper;
public LoggingNHibernateSessionAttribute()
: this(WebContainerManager.Get<IActionLogHelper>(),
WebContainerManager.Get<IActionExceptionHandler>(),
WebContainerManager.Get<IActionTransactionHelper>())
{
}
public LoggingNHibernateSessionAttribute(
IActionLogHelper actionLogHelper,
IActionExceptionHandler actionExceptionHandler,
IActionTransactionHelper actionTransactionHelper)
{
_actionLogHelper = actionLogHelper;
_actionExceptionHandler = actionExceptionHandler;
_actionTransactionHelper = actionTransactionHelper;
}
public override void OnActionExecuting(ActionExecutingContext actionExectingContext)
{
_actionLogHelper.LogEntry(actionExectingContext.ActionDescriptor);
_actionTransactionHelper.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
{
_actionTransactionHelper.EndTransaction(actionExecutedContext);
_actionTransactionHelper.CloseSession();
_actionExceptionHandler.HandleException(actionExecutedContext);
_actionLogHelper.LogExit(actionExecutedContext.ActionDescriptor);
}
}
ActionTransactionHelper
public class ActionTransactionHelper : IActionTransactionHelper
{
private readonly ISessionFactory _sessionFactory;
private readonly ICurrentSessionContextAdapter _currentSessionContextAdapter;
public ActionTransactionHelper(
ISessionFactory sessionFactory,
ICurrentSessionContextAdapter currentSessionContextAdapter)
{
_sessionFactory = sessionFactory;
_currentSessionContextAdapter = currentSessionContextAdapter;
}
public void BeginTransaction()
{
var session = _sessionFactory.GetCurrentSession();
if (session != null)
{
session.BeginTransaction();
}
}
public bool TransactionHandled { get; private set; }
public void EndTransaction(ActionExecutedContext filterContext)
{
var session = _sessionFactory.GetCurrentSession();
if (session == null) return;
if (!session.Transaction.IsActive) return;
if (filterContext.Exception == null)
{
session.Flush();
session.Transaction.Commit();
}
else
{
session.Transaction.Rollback();
}
TransactionHandled = true;
}
public bool SessionClosed { get; private set; }
public void CloseSession()
{
if (_currentSessionContextAdapter.HasBind(_sessionFactory))
{
var session = _sessionFactory.GetCurrentSession();
session.Close();
session.Dispose();
_currentSessionContextAdapter.Unbind(_sessionFactory);
SessionClosed = true;
}
}
}
when run the app, I can save an entity in the dataBase. but when I hit refresh button and exception thrown indication session is closed.
I don't know why this happens. (I searched and find this NHibernate throwing Session is closed but couldn't solve my problem).
in my NinjectConfigurator I added inRequestScope() to all of injections but no answer. I checked when I refresh the page session will be opened. but I donnow why it say session is closed?!
UPDATE:
when I first run the app. I can create a new member. but when I hit the refresh button, the session will be closed unexpectedly!!
first run:
everything works well
after hitting refresh button:
a new session bind to the current context.
the new session will be injected the repository (session is open)
the ActionTransactionHelper calls beginTransaction()
4- customMembership createUser (....) called
5- but when the _userRepositoy.save(user)called in the repository session is closed!!!!
note:but when still endTransaction and closeSession isn't called. but how session is closed?
if I comment closeSession() in onActionExecute(). session alway is open and everything woks well if refresh the page.
I checked a lot and tried different way I knew. it only happens when for the second time I want to do CRUD operations with my customMembership.
for other entities it works like a charm!
I have upoaded my sample code. for testing just create and empty database and change connection string. then go to localHost:*****/api/categories (user and pass doesn't required)
Download sample project:
Size: 47 MB
https://www.dropbox.com/s/o63wjng5f799fii/Hashem-MVC4ServicesBook.rar
size: 54 MB
Zip Format: https://www.dropbox.com/s/smrsbz4cbtznx1y/Hashem-MVC4ServicesBook2.zip
A very important thing here, could be the nature of the NHibernate. The NHibernate and its Session are in the ASP.NET MVC living longer, then could be expected. I mean not only inside of the
ActionExecuting (Controller Action starts)
ActionExecuted (the View or Redirect is called)
Session in fact must live also through the phase of rendering. Because, we could load some proxy in the "Action()" but its collection, could be lazily loaded only during the View rendering. So even in these phases Session must be opened (the same Session from the request begining)
ResultExecuting (the proxy could start to be loaded only here)
ResultExecuted (almost all is done, let's close the session)
Other words... keep the session opened throught the complete Request. From authorization untill the content is rendered.
NOTE: Anohter hint, just to be sure that all is ok, I am using this scenario (maybe you do as well):
Client FORM is about to send the data to server. The method is POST, the Action is Update()
Sent FORM is coming to server, Action Update() is triggerred - all the transactions stuff is in place (as described above)
Once NHibernate persists the data into DB, the Update() action ends, and is redirected to action
Detail() if all is ok or
Edit() if something goes wrong
The users Browser was redirected to action Detail or Edit. So if user does REFRESH, the Detail or Edit is refreshed. The Update() is not called at all (it is a POST method)
In fact, the step 1. was one of the Actions Detail or Edit. In this case, we would face this issue already...
You have this error since Asp.Net MVC does not create a new instance of LoggingNHibernateSessionAttribute every request. It creates a new instance when you request an action first time and then uses this instance in the future.
The behaviour is the following:
First invocation of Post -> new instance of 'LoggingNHibernateSession' is created
First invocation of Put -> another one instance of 'LoggingNHibernateSession' is created
Second invocation of Put -> instance of 'LoggingNHibernateSession' from previous step is used
First invocation of Delete -> another one instance of 'LoggingNHibernateSession' is created
[LoggingNHibernateSession]
public JsonResult Post(Dto data)
{
/* ... */
}
[LoggingNHibernateSession]
public JsonResult Put(int id, Dto data)
{
/* ... */
}
[LoggingNHibernateSession]
public JsonResult Delete(int id)
{
/* ... */
}
It can be solved using Func<IActionLogHelper> instead of IActionLogHelper in the constructor. An instance of IActionLogHelper can be initialised within OnActionExecuting method.
public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
{
/* your code */
private readonly Func<IActionTransactionHelper> _getActionTransactionHelper;
private IActionTransactionHelper _actionTransactionHelper;
public LoggingNHibernateSessionAttribute()
: this(WebContainerManager.Get<IActionLogHelper>(),
WebContainerManager.Get<IActionExceptionHandler>(),
() => WebContainerManager.Get<IActionTransactionHelper>())
{
}
public LoggingNHibernateSessionAttribute(
IActionLogHelper actionLogHelper,
IActionExceptionHandler actionExceptionHandler,
Func<IActionTransactionHelper> getActionTransactionHelper)
{
_actionLogHelper = actionLogHelper;
_actionExceptionHandler = actionExceptionHandler;
_getActionTransactionHelper = getActionTransactionHelper;
_actionTransactionHelper = null;
}
public override void OnActionExecuting(ActionExecutingContext actionExectingContext)
{
_actionTransactionHelper = _getActionTransactionHelper();
_actionLogHelper.LogEntry(actionExectingContext.ActionDescriptor);
_actionTransactionHelper.BeginTransaction();
}
/* your code */
}

Dynamic internal redirect in ASP.NET MVC

I've searched a lot but didn't find any solution. So here is my case:
I have database model UrlRedirect
public class UrlRedirect : AuditInfo
{
[Key]
public int Id { get; set; }
public string OldUrl { get; set; }
public string NewUrl { get; set; }
}
As you may assume I am trying to save URL mapping between OldUrl and NewUrl.
I want to internally change the OldUrl path of the request to the NewUrl and then run all defined routes as they will run if the user is opening NewUrl directly.
The redirect should be server side URL rewrite and user should see the old URL in their browser
In Global.asax you have some events that are executed in the web application context. (for sample: Start_Application, End_Application, etc).
In your case, you could use the BeginRequest event, where every request made to your web application is executed. In this event you could check the URL and try to redirect it using the default of htpp protocols, such as 301 Moved Permanently status code. For sample, in the Global.asax file, add the code bellow:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
// get the current url
string currentUrl = HttpContext.Current.Request.Url.ToString().ToLower();
// here, you could create a method to get the UrlRedirect object by the OldUrl.
var urlRedirect = GetUrlRedirect(currentUrl);
// check if the urlRedirect object was found in dataBase or any where you save it
if (urlRedirect != null)
{
// redirect to new URL.
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", urlRedirect.NewUrl);
Response.End();
}
}
In the sample, GetUrlRedirect(string) method should check it in a database, xml file, cache, or anywhere you save the UrlRedirect objects.
To understand more about how asp.net core applications life cycles works, read this article.
If you really want to redirect within the server you may use one of the following:
HttpServerUtility.TransferRequest
HttpServerUtility.Transfer
HttpServerUtility.Execute
HttpContext.RewritePath
You can read more about these options, where a similar problem is posed here.
Consider the impact of your choice on the request serving performance. IMHO you should try your best to utilize MVC infrastructure of Routing, or just fall back to simple redirections (even permanent for speed) as [user:316799] wrote when you compute new urls in business layer or map from db.
This is my final solution that works like a charm. Thanks to #WeTTTT for the idea.
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
// ...
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
this.ApplyCustomUrlRedirects(new UowData(), HttpContext.Current);
}
private void ApplyCustomUrlRedirects(IUowData data, HttpContext context)
{
var currentUrl = context.Request.Path;
var url = data.UrlRedirects.All().FirstOrDefault(x => x.OldUrl == currentUrl);
if (url != null)
{
context.RewritePath(url.NewUrl);
}
}
}

Bundling CSS files depending on domain of request?

I have a multi-tenant application and I'm trying to determine the simplest means of controlling which CSS files are bundled based on the url of any incoming request.
I'm thinking I can have some conditional logic inside RegisterBundles() that takes the Url as a string, and bundles accordingly:
public static void RegisterBundles(BundleCollection bundles, string tenant = null) {
if (tenant == "contoso"){
bundles.Add(new StyleBundle("~/contoso.css")
}
}
But I don't know how to pass the string into RegisterBundles, nor even if it's possible, or the right solution. Any help here would be awesome.
It is not possible to do it in RegisterBundles right now. Dynamically generating the bundle content per request will prevent ASP.net from caching the minified CSS (it's cached in HttpContext.Cache).
What you can do is create one bundle per tenant in RegisterBundles then select the appropriate bundle in the view.
Example code in the view:
#Styles.Render("~/Content/" + ViewBag.TenantName)
Edit:
As you said, setting the TenantName in a ViewBag is problematic since you have to do it per view. One way to solve this is to create a static function like Styles.Render() that selects the correct bundle name based from the current tenant.
public static class TenantStyles
{
public static IHtmlString Render(params string[] paths)
{
var tenantName = "test"; //get tenant name from where its currently stored
var tenantExtension = "-" + tenantName;
return Styles.Render(paths.Select(i => i + tenantExtension).ToArray());
}
}
Usage
#TenantStyles.Render("~/Content/css")
The bundle names will need to be in the this format {bundle}-{tenant} like ~/Content/css-test. But you can change the format ofcourse.
I think you are after a solution that allows you to dynamically control the BundleCollection. As far as I know this is currently not possible.
The bundles are configured during app start/configured per the application domain.
A future version of ASP.NET may support this feature i,e using VirtualPathProvider.
Here is some discussion.
See also this SO question.
i'm not good in english, but if you mean you need to handle which CSS file load when you run any URL in your page, i can handle css file in a controler.
First, create a controller name : ResourceController
// CREATE PATH TO CSS FOLDER, I store in webconfig <add key="PathToStyles" value="/Content/MyTheme/" />
private static string _pathToStyles = ConfigurationManager.AppSettings["PathToStyles"];
public void Script(string resourceName)
{
if (!String.IsNullOrEmpty(resourceName))
{
var pathToResource = Server.MapPath(Path.Combine(_pathToScripts, resourceName));
TransmitFileWithHttpCachePolicy(pathToResource, ContentType.JavaScript.GetEnumDescription());
}
}
public void Style(string resourceName)
{
if (!String.IsNullOrEmpty(resourceName))
{
var pathToResource = Server.MapPath(Path.Combine(_pathToStyles, resourceName));
TransmitFileWithHttpCachePolicy(pathToResource, ContentType.Css.GetEnumDescription());
}
}
private void TransmitFileWithHttpCachePolicy(string pathToResource, string contentType)
{
//DO WHAT YOU WANT HERE;
Response.ContentType = contentType;
Response.TransmitFile(pathToResource);
}
//You can handle css or js file...
private enum ContentType
{
[EnumDescription("text/css")]
Css,
[EnumDescription("text/javascript")]
JavaScript
}
In file Global.asax.cs, make sure in application start medthod, in contain the route config
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Go to routeConfig, add below map to this file (must be add in top of this file) :
routes.MapRoute(
name: "Resource",
url: "resource/{action}/{resourceName}",
defaults: new { controller = "Resource" }
);
Now, create a UrlHelperExtensions class, same path with webconfig file
public static class UrlHelperExtensions
{
public static string Style(this UrlHelper urlHelper, string resourceName)
{
return urlHelper.Content(String.Format("~/resource/style/{0}", resourceName));
}
}
And from now, you can define css file in your view like :
..."<"link href="#Url.Style("yourcss.css")" rel="stylesheet" type="text/css"
/>
Hope this help

UrlActionResult in asp.net MVC

I want to know is there any open source action result code available for asp.net mvc in which i can pass a URL and it will response out the content.
Just like there are some inbuilt Action results
FileResult
FileStreamResult
I want to build a custom Action Result in which i can pass a URL (basically an mp3 url) which will get downloaded in memory and the content will be streamed to the current executing response.
It should also support resume download if supported by server and client. Thats a must for me.
public UrlActionResult DownloadUrl(string url)
{
return new UrlActionResult("http://www.example.com/audiofile.mp3");
}
For a basic scenario you could use something like this:
public class DownloadResult : ActionResult
{
private readonly FileStreamResult _fileStreamResult;
public DownloadResult(string url, string contentType)
{
using (var myWebClient = new WebClient())
{
var myStream = myWebClient.OpenRead(url);
_fileStreamResult = new FileStreamResult(myStream, contentType);
}
}
public override void ExecuteResult(ControllerContext context)
{
_fileStreamResult.ExecuteResult(context);
}
}
However if you want to do the resume download it becomes a lot more complicated. Here is a great article with example code.
If you don't need to hide the url just use a redirect. Using a redirect with spare you server bandwidth:
public ActionResult DownloadUrl(string url)
{
return new Redirect("http://www.example.com/audiofile.mp3");
}

Mini profiler not displaying ajax request information?

I'm using the mini-profiler on my asp.net MVC 3 application. I've implemented the profiler using the mvc nuget package. Everything works ok for standard page requests i get profile information sql everything.
However ajax requests don't seem to display initially. Just to let me confirm the request are completed without error. I've debugged this and they complete they also return http 200 responses in fiddler.
There is no request by the mini profiler that accompanies the ajax request. When i then navigate to another page i.e. a standard page request all the ajax request that were made on the last page are now displayed.
This is my mini profiler configuration page in App_Start
public static class MiniProfilerPackage
{
public static void PreStart()
{
//Setup sql formatter
MiniProfiler.Settings.SqlFormatter = new OracleFormatter();
//Make sure the MiniProfiler handles BeginRequest and EndRequest
DynamicModuleUtility.RegisterModule(typeof(MiniProfilerStartupModule));
//Setup profiler for Controllers via a Global ActionFilter
GlobalFilters.Filters.Add(new ProfilingActionFilter());
//Settings
MiniProfiler.Settings.PopupShowTimeWithChildren = true;
MiniProfiler.Settings.PopupShowTrivial = false;
//Ignore glimpse details in miniprofiler
var ignored = MiniProfiler.Settings.IgnoredPaths.ToList();
ignored.Add("Glimpse.axd");
MiniProfiler.Settings.IgnoredPaths = ignored.ToArray();
}
public static void PostStart()
{
// Intercept ViewEngines to profile all partial views and regular views.
// If you prefer to insert your profiling blocks manually you can comment this out
var copy = ViewEngines.Engines.ToList();
ViewEngines.Engines.Clear();
foreach (var item in copy)
{
ViewEngines.Engines.Add(new ProfilingViewEngine(item));
}
}
}
public class MiniProfilerStartupModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, e) =>
{
var request = ((HttpApplication)sender).Request;
MiniProfiler.Start();
};
//Profiling abadened if user is not in the admin role
context.PostAuthorizeRequest += (sender, e) =>
{
if (!context.User.IsInRole("Admin"))
MiniProfiler.Stop(discardResults: true);
};
context.EndRequest += (sender, e) =>
{
MiniProfiler.Stop();
};
}
public void Dispose() { }
}
Is there some configuration that is required or potential issues I should be aware of?
In the end i figured out that the Miniprofiler JavaScript block that is added to the page must be below the pages jquery reference.
My JavaScript reference are all added at the end of the page for best practice performance reasons.
But I'd left the #MvcMiniProfiler.MiniProfiler.RenderIncludes() in the page header. Moving it below the jquery script ref at the bottom of the page fixed my problem.
Just found out that the same situation repeat if
$.ajaxSetup({
global: false
});

Resources