.NET MVC Localization (JavaScript) - javascript

I am trying to localize the Script Files.
Currently, I am able to localize the HTML Files by using the Resources,
It is like;
BaseController;
public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
string cultureName = null;
// Attempt to read the culture cookie from Request
HttpCookie cultureCookie = Request.Cookies["_culture"];
if (cultureCookie != null)
cultureName = cultureCookie.Value;
else
cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ?
Request.UserLanguages[0] : // obtain it from HTTP header AcceptLanguages
null;
// Validate culture name
cultureName = InDoor.CultureHelper.GetImplementedCulture(cultureName); // This is safe
// Modify current thread's cultures
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture;
return base.BeginExecuteCore(callback, state);
}
}
Home Controller;
public class HomeController : BaseController{
...
}
Plus some classes.
To localize script, I have to merge the script file into .cshtml file, But I want both cshtml and script files be separetly.
How can I do this ?
Thanks in Advance

You may want to look at this post:
http://www.c-sharpcorner.com/uploadfile/4d9083/globalization-and-localization-in-asp-net-mvc-4/

Related

Miagration Asp.Net Core 2 to .Net 6 gave me XMLHttpRequest problems

I folks, I just migrated my ASP.Net Core 2 MVC app to .Net 6, but since that, I have a weird problem: my XMLHttpRequest responses texts are always empty, "{}" or [{},{},{},{}] for arrays, despite my backend really returning data.
Here's an example of a controler method (TestLoad) returning a simple class (TestClass). Notice that when I break on the return line, the value returned is ok, or at least I don't see anything wrong (see image for debug infos):
backend
public class TestClass
{
public int id = 0;
public string title = "Title";
public bool active = false;
}
public JsonResult TestLoad()
{
TestClass testClass = new TestClass();
testClass.id = 10;
testClass.title = "Yeah man!";
testClass.active = true;
JsonResult jsonRes = Json(testClass);
return jsonRes;
}
But once on the front end, I got an empty object, not undefined nor null, but really an empty object (see image for debug infos):
frontend
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var dt = JSON.parse(xmlhttp.responseText);
if (dt == 'err') {
alert('error');
}
else if (dt !== null) {
alert(dt.title);
}
}
else {
alert(xmlhttp.status);
}
}
}
ldwait(false, false);
xmlhttp.open("GET", rv + "ajxGame/TestLoad", true);
xmlhttp.setRequestHeader('Cache-Control', 'no-store');
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send();
Any help would be greatly appreciated since I completely clueless of what happened. Again, my code hasn't changed, but my project has migrated from .Net Core 2 to .Net 6.
Thank you
i would add a response type, and replace onreadystatechange with onload
xmlhttp.responseType = 'json';
xmlhttp.onload = () => {
console.log("load - "+ JSON.stringify(xhr.response));
var data = xhr.response;
}
Are you using Razor pages in your Asp.net core 6 ?
If so, the way you call your method maybe the issue. For post requests, call from the client ?handler=TestLoad and on the server make sure the method name is OnPostTestLoad().
Get requests are disabled by default and need to be enabled.
Microsoft Warning Message
For more info, check this link from Microsoft docs
Another issue maybe the way you return your class. Try returning it as a JSON object instead.
return new JsonResult(new {objClass: testClass});
And on the client side, get your class as an object property
let objClass = result.objClass;
Actually, my error was simply that I forgot to add { get; set; } on each property of my TestClass in the backend part! It worked without it in .Net Core 2, but it seems like this is now mandatory in .Net 6
public class TestClass
{
public int id {get; set;} = 0;
public string title {get; set;} = "Title";
public bool active {get; set;} = false;
}
...thanks to those who attempted an answer!

How to call Export PDF with Reserved.ReportViewerWebControl.axd....URL from BackEnd C# Code

My Aim is to call ExportBaseUrl Link , that is given by Rdlc Exprot PDF button , on C# side, i want to do that because there are 285 reports and each one have diff parameters so this will take a lot time.
I have worked on one solution but that take 15 min to load 2 page RDLC to pdf.
Its taking time due to Response coming late or some deadlock is happening,
This is what i am doing.
JS file
var reportViewerName = ControlName; //Name attribute of report viewer control.
var src_url = $find(reportViewerName)._getInternalViewer().ExportUrlBase + 'PDF';
var contentDisposition = 'AlwaysInline'; //Content Disposition instructs the server to either return the PDF being requested as an attachment or a viewable report.
var src_new = src_url.replace(/(ContentDisposition=).*?(&)/, '$1' + contentDisposition + '$2');
window.open("/printPDF.asx?url=" + encodeURIComponent("http://localhost:5402"+src_new));
PrintPDF.aspx File is like this
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Action;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace WebApp.WebAPI
{
/// <summary>
/// Summary description for printPDF
/// </summary>
public class printPDF : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
string url = context.Request.QueryString["url"];
// Download data.
DownloadFile(url, context.Server.MapPath("~/pdf/pdffile.pdf"), context.Request).Wait();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(context.Server.MapPath("~/pdf/pdffile.pdf")), new PdfWriter(context.Server.MapPath("~/pdf/pdffileAuto.pdf")));
// add content
PdfAction action = PdfAction.CreateJavaScript("this.print({bUI: true, bSilent: true, bShrinkToFit: true});");
pdfDoc.GetCatalog().SetOpenAction(action);
pdfDoc.Close();
context.Response.Clear();
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("Content-Disposition",
"AlwaysInline;filename=\"FileName.pdf\"");
context.Response.BinaryWrite(File.ReadAllBytes(context.Server.MapPath("~/pdf/pdffileAuto.pdf")));
context.Response.Flush();
context.Response.End();
}
public async Task DownloadFile(string url, string destinationPath, HttpRequest req)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
var encoding = new UTF8Encoding();
request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-IN");
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
request.Accept = "text/html, application/xhtml+xml, image/jxr, */*";
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko";
request.KeepAlive = true;
request.Proxy = null;
request.CookieContainer = new CookieContainer();
Uri target = new Uri("http://localhost:5402/");
foreach (String item in req.Cookies)
{
request.CookieContainer.Add(new Cookie(item, req.Cookies[item].Value) { Domain = target.Host });
}
await request.GetResponseAsync().ContinueWith(t1 =>
{
using (var responseStream = t1.Result.GetResponseStream())
{
if (responseStream == null)
return;
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int bytesRead = 0;
using (FileStream fileStream = File.Create(destinationPath))
{
while ((bytesRead = responseStream.Read(buffer, 0, bufferSize)) != 0)
{
fileStream.Write(buffer, 0, bytesRead);
}
}
}
t1.Result.Close();
});
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
line
await request.GetResponseAsync().ContinueWith(t1 =>
with async and without async takes around 15 min time once, second time it go to deadlock/Freez
also i had to add cookie due to the url was throwing 500 internal server error.
And if i call url direct on browser it runs in 1 sec.
So if anyone know what is issue or can help then that would be really big help.
Thanks for Help in Advance.
Ok
I found what issue is,
Issue is tab request PrintPDF.aspx and that page request other URL on same site.
So untill PrintPDF.aspx response complete to tab that (HttpWebRequest) is not being called.
Any reason why? i set maxconnection in web.config though
I had to fix it by making 2 diff files, first ASPX file which show page and generate pdf in thread and on page load call Ashx file which checks if file is generated or not, if generated then return file.
there was not other way, so i fixed it by 2 links redirect call.
Thank Everyone who helped me.

Html to pdf conversion and download

I have an Angular web app for simple quizzes, at the end of the last quiz I bind the result into an HTML template.
Previously I could generate a pdf file using PHP mpdf library from this HTML template, now as I am building the business logic and the security in spring boot I want to do that as well in spring boot.
I used Flying saucer and i could generate a pdf file from an HTML-template in the resources folder.
The question is how can I get this HTML file from the front end and generate a pdf file out of it and download the last to my pc?
#Service
public class PdfService {
private static final String OUTPUT_FILE = "test.pdf";
private static final String UTF_8 = "UTF-8";
#Test
public void generatePdf() throws Exception {
// We set-up a Thymeleaf rendering engine. All Thymeleaf templates
// are HTML-based files located under "src/test/resources". Beside
// of the main HTML file, we also have partials like a footer.html or
// a header. We can re-use those partials in different documents.
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(HTML);
templateResolver.setCharacterEncoding(UTF_8);
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
// The data in our Thymeleaf templates is not hard-coded. Instead,
// we use placeholders in our templates. We fill these placeholders
// with actual data by passing in an object. In this example, we will
// write a letter to "John Doe".
//
// Note that we could also read this data from a JSON file, a database
// a web service or whatever.
Data data = exampleDataForJohnDoe();
Context context = new Context();
context.setVariable("data", data);
// Flying Saucer needs XHTML - not just normal HTML. To make our life
// easy, we use JTidy to convert the rendered Thymeleaf template to
// XHTML. Note that this might not work for very complicated HTML. But
// it's good enough for a simple letter.
String renderedHtmlContent = templateEngine.process("template", context);
String xHtml = convertToXhtml(renderedHtmlContent);
ITextRenderer renderer = new ITextRenderer();
renderer.getFontResolver().addFont("Code39.ttf", IDENTITY_H, EMBEDDED);
// FlyingSaucer has a working directory. If you run this test, the working directory
// will be the root folder of your project. However, all files (HTML, CSS, etc.) are
// located under "/src/test/resources". So we want to use this folder as the working
// directory.
String baseUrl = FileSystems
.getDefault()
.getPath("src", "test", "resources")
.toUri()
.toURL()
.toString();
renderer.setDocumentFromString(xHtml, baseUrl);
renderer.layout();
// And finally, we create the PDF:
OutputStream outputStream = new FileOutputStream(OUTPUT_FILE);
renderer.createPDF(outputStream);
outputStream.close();
}
private Data exampleDataForJohnDoe() {
Data data = new Data();
data.setFirstname("John");
data.setLastname("Doe");
data.setStreet("Example Street 1");
data.setZipCode("12345");
data.setCity("Example City");
return data;
}
static class Data {
private String firstname;
private String lastname;
private String street;
private String zipCode;
private String city;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
private String convertToXhtml(String html) throws UnsupportedEncodingException {
Tidy tidy = new Tidy();
tidy.setInputEncoding(UTF_8);
tidy.setOutputEncoding(UTF_8);
tidy.setXHTML(true);
ByteArrayInputStream inputStream = new ByteArrayInputStream(html.getBytes(UTF_8));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
tidy.parseDOM(inputStream, outputStream);
return outputStream.toString(UTF_8);
}

Parallel file upload XMLHttpRequest requests and why they won't work

I am trying to upload many (3 for now) files in parallel using XMLHttpRequest. If have some code that pulls them from a list of many dropped files and makes sure that at each moment I am sending 3 files (if available).
Here is my code, which is standard as far as I know:
var xhr = item._xhr = new XMLHttpRequest();
var form = new FormData();
var that = this;
angular.forEach(item.formData, function(obj) {
angular.forEach(obj, function(value, key) {
form.append(key, value);
});
});
form.append(item.alias, item._file, item.file.name);
xhr.upload.onprogress = function(event) {
// ...
};
xhr.onload = function() {
// ...
};
xhr.onerror = function() {
// ...
};
xhr.onabort = function() {
// ...
};
xhr.open(item.method, item.url, true);
xhr.withCredentials = item.withCredentials;
angular.forEach(item.headers, function(value, name) {
xhr.setRequestHeader(name, value);
});
xhr.send(form);
Looking at the network monitor in Opera's developer tools, I see that this kinda works and I get 3 files "in progress" at all times:
However, if I look the way the requests are progressing, I see that 2 of the 3 uploads (here, the seemingly long-running ones) are being put in status "Pending" and only 1 of the 3 requests is truly active at a time. This gets reflected in the upload times as well, since no time improvement appears to happen due to this parallelism.
I have placed console logs all over my code and it seems like this is not a problem with my code.
Are there any browser limitations to uploading files in parallel that I should know about? As far as I know, the AJAX limitations are quite higher in number of requests than what I use here... Is adding a file to the request changing things?
This turned out to be ASP.NET causing the issue.
Multiple requests coming from the same SessionId get serialized, because they lock the session object.
See here.
My fix was to make the session read-only for this particular action. That way, no locking was required.
This is my code (original code taken from here):
public class CustomControllerFactory : DefaultControllerFactory
{
protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return SessionStateBehavior.Default;
}
var actionName = requestContext.RouteData.Values["action"].ToString();
MethodInfo actionMethodInfo;
var methods = controllerType.GetMethods(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
actionMethodInfo = methods.FirstOrDefault(x => x.Name == actionName && x.GetCustomAttribute<ActionSessionStateAttribute>() != null);
if (actionMethodInfo != null)
{
var actionSessionStateAttr = actionMethodInfo.GetCustomAttributes(typeof(ActionSessionStateAttribute), false)
.OfType<ActionSessionStateAttribute>()
.FirstOrDefault();
if (actionSessionStateAttr != null)
{
return actionSessionStateAttr.Behavior;
}
}
return base.GetControllerSessionBehavior(requestContext, controllerType);
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ActionSessionStateAttribute : Attribute
{
public SessionStateBehavior Behavior { get; private set; }
public ActionSessionStateAttribute(SessionStateBehavior behavior)
{
this.Behavior = behavior;
}
}
// In your Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
// .........
ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
}
// You use it on the controller action like that:
[HttpPost]
[Authorize(Roles = "Administrators")]
[ValidateAntiForgeryToken]
[ActionSessionState(SessionStateBehavior.ReadOnly)]
public async Task<ActionResult> AngularUpload(HttpPostedFileBase file){}
And here is the glorious result:
The HTTP/1.1 RFC
Section 8.1.4 of the HTTP/1.1 RFC says a “single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.
Read more here: Roundup on Parallel Connections

Android - Is it possible to fire a native intent from an application wrapped in PhoneGap

I am developing an application on Sencha Touch 2.0.1 & PhoneGap.
I need to catch and transfer an event firing inside Sencha Touch to the native Android environment.
i.e: Some sencha touch-controlled-buttons need to fire an intent on click to start another activity (non-PhoneGap activities).
So far I have found various examples like webintents and this. But as far as I see, these are inapplicable in my case.
I seek to either drop PhoneGap and work with another wrapper, or somehow circumvent this issue. Thanks in advance!
I think you'll need to make your own phonegap plugin that launches the native activity from inside it's execute method.
There's a ContactView plugin you should be able to use as a guide for writing your own.
https://github.com/phonegap/phonegap-plugins/blob/master/Android/ContactView/ContactView.java
Specifically these two methods
#Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
startContactActivity();
PluginResult mPlugin = new PluginResult(PluginResult.Status.NO_RESULT);
mPlugin.setKeepCallback(true);
this.callback = callbackId;
return mPlugin;
}
public void startContactActivity() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
this.ctx.startActivityForResult((Plugin) this, intent, PICK_CONTACT);
}
Take a look at this, the explicit and implicit intent sections (1.2, 1.3):
http://www.vogella.de/articles/AndroidIntent/article.html
Then take a look at the source code for WebIntent.java, in particular the startActivity function:
https://github.com/phonegap/phonegap-plugins/blob/master/Android/WebIntent/WebIntent.java
void startActivity(String action, Uri uri, String type, Map<String, String> extras) {
Intent i = (uri != null ? new Intent(action, uri) : new Intent(action));
And then the intent constructors here (search for Constructors):
http://developer.android.com/reference/android/content/Intent.html
WebIntent does not support the Intent constructor that that takes an Android class.
But you can extend the function to have it work with an explicit intent (code below is quick and dirty and untested):
void startActivity(String action, Uri uri, String type, String className, Map<String, String> extras) {
Intent i;
if (uri != null)
i = new Intent(action, uri)
else if (className != null)
i = new Intent(this.ctx, Class.forName(className));
else
new Intent(action));
Above, in the execute function, you must also parse out the new parameter in the "Parse the arguments" section
// Parse the arguments
JSONObject obj = args.getJSONObject(0);
String type = obj.has("type") ? obj.getString("type") : null;
Uri uri = obj.has("url") ? Uri.parse(obj.getString("url")) : null;
String className = obj.has("className") ? obj.getString("className") : null;
JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null;
and then pass the new className string in the call to startActivity a few lines below:
startActivity(obj.getString("action"), uri, type, className, extrasMap);
Then you should be able to call an android activity by classname using something like:
Android.callByClassName = function(className) {
var extras = {};
extras[WebIntent.EXTRA_CUSTOM] = "my_custom";
extras[WebIntent.EXTRA_CUSTOM2] = "my_custom2";
window.plugins.webintent.startActivity({
className: className,
extras: extras
},
function() {},
function() {
alert('Failed to send call class by classname');
}
);
};
Where the classname is something like: com.company.ActivityName
DISCLAIMER: Rough code, not tested.

Categories

Resources