Griffin.MvcContrib Localization with FluentValidation - asp.net-mvc-3

I've been working on my first localization project for mvc and have been using the excellent Griffin.MvcContrib to get me started.
I've using the Griffin to handle the language change and the page views, and have a custom provider setup to handle the models and validation through database resources.
The validation is done with FluentValidation like the following:
RuleFor(x => x.Bin)
.Length(0, 50)
.WithMessage(localizationService.GetResource("Inspection.Bin.Length"));
Everything seemed to work great until I realized that server side errors were not being translated, only the client side ones. After a lengthy investigation it seems to me the issue is that the thread culture is being set after the server side validation is done - I believe the same thing that was happening in this other post:
MVC3 globalization not set for ModelState.Value.Culture
What I did to get it working so far is just to place the following in the Global.asax file.
protected void Application_BeginRequest(object sender, EventArgs e)
{
string CookieName = "GriffinLanguageSwitcher";
HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current);
if (currentContext.Request.Cookies[CookieName] != null)
{
Thread.CurrentThread.CurrentCulture =
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(currentContext.Request.Cookies[CookieName].Value);
}
}
It seems to work. I'm not worried about validation when a user switches their language, and it now seems to pickup the current language and translate the server side errors.
But is this an acceptable way of fixing this issue, or should I be doing something else. Thanks.

Related

Error trying to scaffold a view in ASP.NET Core 6.0 MVC

I'm trying to scaffold a new razor view using Visual Studio. I select a template, my model and my DbContext, then I get the error message shown below.
Things to note. My models, my DbContext and my website are all in different projects. From the message below I am using AddDbContext and I have a constructor that accepts a DbContextOptions<TContext> parameter.
I read a comment on a blog post that the issue is because my context is in another project. The comment referenced something about the need to inject the Configuration into the DbContext to get the connection string and manually add it in the OnConfiguring override.
I can't find any examples if this is correct or how to set it up. Any help would be appreciated.
EDIT:
Testing out the theory from the blog comment I mentioned above, I added this section into my DbContext. ConnectionString is a hardcoded string constant with my connection information. This does work and allow me to scaffold, so the question still remains. How can I inject this connection string into my DbContext to allow the scaffolding to work?
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(ConnectionString);
}
else
{
base.OnConfiguring(optionsBuilder);
}
}
EDIT: So after making this change, I checked in the code and had another developer pick it up. It appears this section above just needs to be there to allow scaffolding to work. He never changed the connection string to point to his environment. He no longer got the error above it just worked.
I am not sure about what is the actual problem but it seems like we were having problems creating DbContext at design time. I manually added the code below and it's working now. It's just a temporary solution tho.
public AppDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=JwtTemplate;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
return new AppDbContext(optionsBuilder.Options);
}
Reference: https://stackoverflow.com/a/70559350

Kentico Tapping into Page Level Events

We are creating webevents in a DB other than Kentico. These webevents are then used for enterprise reporting. I need to implement the same inside Kentico project.
Is there an event that can fire after the page has loaded so that i can create my web event with page name and user information if logged in.
I have also seen in the past that with events, the Request and Session objects are not available. However, HTTPContext.Current is available. I need the Request and Session objects.
We are using Kentico version 7.0.92 and have a portal template site.
Now, i don't want to use portal template page to create events since this code executes multiple times with each request for a page.
Basically, i am interested in the PageName, Session and Request objects.
I have looked around Kentico 7 documentation. Looks like we have CMSRequestEvents but haven't been able to find sample code.
Update:
Looks like the missing piece is CMSContext class. Now just trying to find the right event for CMSRequestEvents, where i have the Session object available.
I'd suggest modifying Kentico\CMS\Global.asax.cs in the following way:
public override void Init()
{
base.Init();
CMSRequestEvents.AcquireRequestState.After += AcquireRequestState_After;
}
void AcquireRequestState_After(object sender, EventArgs e)
{
// Do your stuff...
}
By that time the HttpContext.Current.Session should already be initialized. Page name can be retrieved from the HttpContext.Current.Request which should never be null.

Converting from DbContext to ObjectContext for webform in MVC application

I have an MVC5 application with EF 6.1 and the basic forms work great. Need to develop some complex forms though so webforms seemed the better option. Followed all the advice on converting DbContext to ObjectContext in order to use EntityDataSource for database communication but just get the 'Cannot implicitly convert type System.Data.Entity.Core.Objects.ObjectContext to System.Data.Objects.ObjectContext' error despite updating to the latest version which is supposed to resolve this issue.
protected void EntityDataSource_ContextCreating(object sender, EntityDataSourceContextCreatingEventArgs e)
{
var db = new myDbContext();
e.Context = (db as IObjectContextAdapter).ObjectContext;
//also tried e.Context = ((IObjectContextAdapter)db).ObjectContext;
}
Would appreciate any advice on getting webforms running alongside MVC5, especially on getting the connection set up correctly for insert.

MVC3 Application Inside Webforms Application Routing is throwing a HttpContext.SetSessionStateBehavior Error in IIS7.5

I'm running a mixed MVC Application inside a sub folder of a web forms application.
Everything worked great in VS 2010 debug (Cassini) but when I deployed to IIS7.5
I got the following error:
'HttpContext.SetSessionStateBehavior' can only be invoked before
'HttpApplication.AcquireRequestState' event is raised.
It errors on the last line (httpHandler.ProcessRequest(HttpContext.Current);) in the default.aspx file of the MVC application sub folder.
public void Page_Load(object sender, System.EventArgs e)
{
string pathToRewriteTo = Request.Path.ToLowerInvariant().Replace("default.aspx", "Home/Index");
HttpContext.Current.RewritePath(pathToRewriteTo, false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
}
However if I manually navigate to Home/Index from the MVC root folder I can see my application fine from there.
I've looked up the error being thrown and I only find answers dealing with server transfers and not MVC routes.
I have also already checked my IIS7.5 configuration for the route handling module, Application pool running in integrated mode, etc.
Any help would be appreciated.
We faced a similar issue. There are changes to MVCHttpHandler in MVC2 and above.
You need to change it to use httpContext.Server.TransferRequest.
Try the below snippet:
var httpContext = HttpContext.Current;
httpContext.Server.TransferRequest(Url, true); // change to false to pass query string parameters if you have already processed them

ASP.NET MVC 3 Site Loading Is Extremely Slow

I really don't know where to begin with this question, but the site I'm working on at times has some really slow page loads. Especially after doing a build, but not always. I usually have to refresh the page 5-10 times before it actually comes up. I guess I am trying to see where exactly I should begin to look.
ASP.NET MVC 3
Ninject
AutoMapper
Entity Framework Code First 4.1
SQL Server 2008
Razor
UPDATES
Concerning some of the questions, it can do this long loading on every page, but after it loads its fairly quick on all the pages.
After posting this and getting your replies I started the application and it is still loading and probably won't ever load unless I click reload on the browser.
No caching, and the EF models aren't huge.
I am using Razor and Visual Studio 2010 with 6 GB of memory and an I7 processor.
I am using IIS Express and the default web server when debugging. It also does this on IIS7 on the main server.
I may look into the MVC Profiler and Glimpse to see what I can find.
Below I have some code this runs when it hits the homepage. I would say it never loads when I first start up the server. I put a break point at var model which never gets hit. If I reload the page then it does.
public ActionResult Index()
{
var model = new HomeViewModel();
model.RecentHeadlines = _headlineService.GetHeadlines(1, Config.RecentHeadlinesPageSize, string.Empty);
return View(model);
}
Below is my datacontext setup also.
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private DataContext _dataContext;
public DataContext Get()
{
return _dataContext ?? (_dataContext = new DataContext());
}
protected override void DisposeCore()
{
if (_dataContext != null)
_dataContext.Dispose();
}
}
public class Disposable : IDisposable
{
private bool isDisposed;
~Disposable()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!isDisposed && disposing)
{
DisposeCore();
}
isDisposed = true;
}
protected virtual void DisposeCore()
{
}
}
public class UnitOfWork : IUnitOfWork
{
private readonly IDatabaseFactory _databaseFactory;
private DataContext _dataContext;
public UnitOfWork(IDatabaseFactory databaseFactory)
{
_databaseFactory = databaseFactory;
}
protected DataContext DataContext
{
get { return _dataContext ?? (_dataContext = _databaseFactory.Get()); }
}
public void Commit()
{
DataContext.Commit();
}
}
I'd start by checking what the timeouts are set to in IIS for the process to be recycling itself.
I'm also a very big fan of the MVC Mini-Profiler which could show you exactly how long various parts of your page load are taking, definitely take a look at it.
Edit:
It is worth noting that the Glimpse project is also great for this task these days.
Sounds like it might be an issue with IIS AppPool recycling if you're experiencing it after builds or after periods of inactivity.
To help with AppPool timeouts you can utilize a batch file I created to help mitigate the issue.
That won't solve the problem for you after new builds because your ASP.NET MVC application needs to be JIT-compiled upon first run. If you're really eager to eliminate that issue, you can use ASP.NET precompliation.
Try Glimpse or use ASP.NET Tracing.
You could also precompile your views if you are using the Razor view engine via Razor Single File Generator for MVC.
It depends on what happened in your previous run, sometimes if you throw an error and don't clear that out then you will have issues running the application. It helps to restart the browser every time you build if there was an error.
However, this could be an issue of caching. It is possible that your database is caching due to poorly maintained context disposing. This would cause the lookups to run faster and faster as they were encountered in pages. Make sure you always call .dispose() when done with your database transactions.
funny - I've noticed something similar once with unity and mvc but the problem I believe resolved itself. You could also try ants profiler to see if the problem is outside of MVC.
If you let a single request sit there (without requesting 5+ times) what happens?
Let a single request run - is ANY of your code hit? (setup logging log4net, nlog, etc) to run application_start, etc to see if any code is getting called after the compile.

Resources