I am building a Multi-Lingual site in webforms aspx project, and I am thinking of the best solution to do this.
I have some images on the MasterPage, and once clicked, I am calling a Jquery method, that should redirect to a web method.
In turn I have a base page that is initializing the Culture, and all the pages, except for the MasterPage are inheriting from it.
So far I have the following:-
HTML:-
<div class="LocalizationFlags">
<img src="Images/gb.png" onclick="langSelection('gb')" />
<img src="Images/fr.png" onclick="langSelection('fr')"/>
<img src="Images/es.png" onclick="langSelection('es')"/>
<img src="Images/de.png" onclick="langSelection('de')"/>
<img src="Images/it.png" onclick="langSelection('it')"/>
</div>
JQuery :-
function langSelection(lang) {
setSession(lang);
};
function setSession(Lang) {
var args = {
lang: Lang
};
$.ajax({
type: "POST",
url: "Site.Master.aspx/SetUserCulture",
data: JSON.stringify(args),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
alert('Success.');
},
error: function () {
alert("Fail");
}
});
};
Site.Master.cs
[WebMethod(EnableSession = true)]
private void SetUserCulture(string lang)
{
HttpContext.Current.Session["CurrentUI"] = lang;
}
BasePage.cs
protected override void InitializeCulture()
{
if (Session["CurrentUI"] != null)
{
String selectedLanguage = (string)Session["CurrentUI"];
UICulture = selectedLanguage;
Culture = selectedLanguage;
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentUICulture = new
CultureInfo(selectedLanguage);
}
base.InitializeCulture();
}
Now there are several problems with what I have at the moment. Jquery does not work, throws a "Fail", and also I know that I cannot use the Site.Master.cs to put the webmethod in.
Is it just a case of creating a WCF service for this method, and then calling it from the Jquery code?
Am I on the right track here?
Thanks for your help and time
Your ajax request most likely fails because it does not reach the destination - as you said you cannot have WebMethod in the master's codebehind. Also there is no need to serialize your parameters with JSON, plain object should work just as well. Besides, dataType: json is not needed here - you do not return any data for this request.
There is no need for a web service here - a simple HTTP handler will suffice. Just do not forget to implement marker interface IRequiresSessionState to have an access to the session inside the handler.
In general cookies might be a better place to store user's culture, since you might want to retain this information across different visits of the same user. Another option is also user profile in the DB - in case you are dealing with registered users. However your current implementation that uses session should work.
Related
I want to offer a user discount (pop up) after 30 seconds being on site (any page). Since this project implements WebForms master page, I put the timer inside Master.aspx, and the method that communicates with db inside Master.cs. The method checks eligibility through calling stored procedure, and returns bool.
I set javascript timer inside aspx Master page, so after the time out, I want to call the method providing it userID. How can I call this isUserEligibleForDiscount method that's inside Master.cs using javascript?
setTimeout(function () {
if (sessionStorage.getItem('timer') == 'on') {
if (isUserEligibleForDiscount(userID)) {
$('#myModal').modal('show');
}
sessionStorage.setItem('timer', 'off');
}
}, 30000);
Use [WebMethod] attribute. It makes the method callable from remote Web clients (WebMethodAttribute Class).
Decorate your isUserEligibleForDiscount with that attribute.
You can then call the method via Ajax. You specify your page in the URL for the Ajax call: 'yourpage.aspx/isUserEligibleForDiscount'
You can put your method(s) into a page that does nothing but hold code, or you could call an asmx web service.
setTimeout(function() {
doAjaxPageMethodCall();
//if (sessionStorage.getItem('timer') == 'on') {
// if (isUserEligibleForDiscount(userID)) {
// $('#myModal').modal('show');
// }
// sessionStorage.setItem('timer', 'off');
//}
}, 3000);
function doAjaxPageMethodCall() {
$.ajax({
type: "POST",
// page-methods.aspx holds your methods.
// replace AjaxPageMethodCall w/ isUserEligibleForDiscount.
url: "/page-methods.aspx/AjaxPageMethodCall",
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(function(data) {
if(data.d===true) {
// show modal .
}
}).fail(function() {
$("#lbl").html("Houston...");
});
}
Of course you can combine the 2 functions, they're just split up for testing.
Web service is similar:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="/web-services/test-service.asmx" />
</Services>
</asp:ScriptManager>
And the only change to the ajax call is the url:
url: "/web-services/test-service.asmx/HelloWorld", ...
Your test-service.cs file will hold the actual methods.
I'm working with an asp.net MVC project. A coworker was new to MVC and handled all of the populating of data and click actions by using ajax calls. I know this isn't how MVC should be set up, but it's what I'm stuck with. I'm just trying to work around that the best I can. Anyway, within the method the ajax goes to, I need to redirect the user to a new page. How do I do that?
I tried Response.Redirect, but I got an error saying it didn't exist. I tried to add a using class, but couldn't it to work.
I found System.Diagnostics.Process.Start, but it opens in a new browser tab. Could there possibly be a way to open in the same tab?
So here's the ajax call. This is triggered in a javascript function when the user clicks a button:
$.ajax({
contentType: "application/json",
dataType: "json",
type: "post",
url: "/api/WoApi/PostWoApprGen/" + vUsr,
data: JSON.stringify(invObj),
success: function (res)
{
if (res)
{
var inv = $('#DivInv');
inv.html(res);
output = $('#TmpMsg');
output.html("");
opStatMsg("success", "rptGenWin");
}
else
{
opStatMsg("error", "rptGenWin");
}
}
});
That goes to a class in the controller directory, filename WoApiController.cs:
public string PostWoInv([FromBody] Koorsen.OpenAccess.WrkOrdTemp obj)
{
var currentUser = ClsUtility.GetCurrentUser();
if (currentUser == 0)
{
rep.UpdateWorkOrderStatusInvoiced(obj.WoTempId, currentUser, obj);
}
else
{
System.Diagnostics.Process.Start("~Admin/Login");
}
.............
.............
In your success callback, simply do
location.href = 'Home/Index';
or, preferably, using Razor and a method called Index in HomeController
location.href = '#Url.Action("Index", "Home")';
I am trying to get access a drop-down that is in aspx page from static web method but it seems i can't get access and not what am i doing wrong. I want to set the dropdown index value to -1. thanks
this is what i am trying to do:
[System.Web.Services.WebMethod]
public static void Cancel()
{
myDDL.SelectedIndex = -1;
}
here is the javascript call
<script type="text/javascript" language="javascript">
function Func() {
//alert("hello!")
var result = confirm('WARNING');
if (result) {
//click ok button
PageMethods.Delete();
}
else {
//click cancel button
PageMethods.Cancel();
}
}
</script>
I am trying to get access a drop-down that is in aspx page from static web method
the web method in asp.net page are static, this mean are executed without page context(not completely true, you can access to Session), so what you need its retrieve result from web method, then make your update client side, something like(not tested, sorry):
jQuery.ajax({
url: 'callAJAX.aspx/Cancel',
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
var result = data.d.result;
$('#yourDropDownID')[0].selectedIndex = result;
}
});
It should be myDDL.selectedIndex = -1;
You cannot access a control inside webmethod..At the web service method level you cannot see anything about the page structure..
You can try this code for clearing dropdown..
Instead of calling pagemethod Cancel you can clear it inside javascript function itself..
var ddl = document.getElementById('myDDL');
ddl.options[ddl.selectedIndex] = 0;
Refer this link for extra reading..
I want to open a html page when user presses a function key.
Now the capturing of the function key works fine, but the logic to open the appropriate page is written in Code-Behind of master page.
I read on internet that if I want to call function in code behind then I have to create a web- service and call the webservice method from master page.
But for some reason this is not working.May be I am not calling the web service properly.
Can some body please help?
Many Thanks
<cc1:ToolkitScriptManager ID="ScriptManager1" runat="server" ScriptMode="Release" EnableHistory="true" EnableSecureHistoryState="false"
EnablePageMethods="true" CombineScripts="false">
<Scripts>
<asp:ScriptReference Path="~/ShowHelpPage.asmx" />
</Scripts>
</cc1:ToolkitScriptManager>
document.onkeydown = function(event){
if(window.event && window.event.keyCode == 113)
{
window.open("HelpFile/index.html");
}
else if(event.which == 113)
{
window.open("HelpFile/index.html");
DisplayHelpFile();
}
}
function DisplayHelpFile()
{
var i = PageMethods.DisplayHelpPage();// I think this is wrong
alert(i);
}
Web Method
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class ShowHelpPage : System.Web.Services.WebService
{
[WebMethod]
public string DisplayHelpPage()
{
return "Window.Html";
}
}
"I read on internet that if I want to call function in code behind
then I have to create a web- service and call the webservice method
from master page"
I assume in the context you are refering to methods and not functions. Do you want to call a method when you master page loads? I would think that you dont need to create a Web Service for this? Unless you want the client to initiate the request through Async and you are using JavaScript and AJAX to make the request. What are you trying to achieve? It seems to me this can be achieved through just javascript. If you call a page through JavaScript it should load itself?
Below achieving what you want but using just javascript.
function keyHandler(e)
{
... key handling script
if(myKey == 'F1')
{
window.location.href = '...';
}
}
document.onkeypress = keyHandler;
If you need to call this Web Service and it needs to be initiated from the Client you could use JQuery to do this. Use the same approach with ShowHelpPage.asmx storing the processing and your rendering handled through JavaScript. This also to the best of my knowledge removes the dependency on ToolkitScriptManager.
function DisplayHelpFile()
{
$.ajax({
type: "POST",
url: "ShowHelpPage.asmx/DisplayHelpPage",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success:function(result)
{
alert(result);
}
},
error: ErrorMessage
});
function ErrorMessage(result)
{
alert(result.status + ' ' + result.statusText + ' ' + result.responseText);
}
}
Your web method needs to be static.
Simply put I want to call public static methods decorated with WebMethod attribute inside my code-behind C# file from jquery.ajax to get some json and other simple stuff (in different functions). But instead I'm getting whole page :'(
I'm not using asp.net AJAX though I'm developing for .NET 3.5 framework and using VS 2008. (There are some restrictions from client)
Please let me know if I can use page-methods with using asp.net ajax or If not what is other simple solution?
After much deliberations I found the problem. I was using jquery's editable plugin. This was source of the problem. When jeditable calls jquery's ajax it sets ajax options like this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
success: function(result, status) {
if (ajaxoptions.dataType == 'html') {
$(self).html(result);
}
self.editing = false;
callback.apply(self, [result, settings]);
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
},
error: function(xhr, status, error) {
onerror.apply(form, [settings, self, xhr]);
}
};
so it was sending the things as simple html and to use this with page methods we need to setup the things so that it sends as json. So we need to add something to the settings like this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
dataType: 'json', //Data Type
contentType: 'application/json; charset=utf-8', //Content Type
//....other settings
};
So I put two new properties in settings dataType and contentType and changed above to this:
var ajaxoptions = {
type: 'POST',
data: submitdata,
url: settings.target,
dataType: settings.dataType,
contentType: settings.contentType,
//....other settings
};
Now another problem arised :( it was sending data (from submitdata property) as normal query-string which asp.net does not accept with json requests. So I had to use jquery's json plugin and change the way data is sent in ajax using following test on dataType:
if (settings.dataType == "json") {
if ($.toJSON) {
submitdata = $.toJSON(submitdata);
}
}
and it works like breeze!!!
Russ Cam posted this link in response to another question (so if this helps, go up vote his answer ;)):
Using jQuery to directly call ASP.NET AJAX Page Methods
Dave Ward has a series of posts that use jQuery directly with ASP.Net PageMethods, no MS Ajax UpdatePanel required. In particular this post will get you started.
I am not sure but i think WebMethods are accessible only through asp.net AJAX. I may be wrong though, because we dont use it that way at all. We do it in a slightly different way.
We have built a aspx page which accepts all our AJAX requests and passes them to the subsequent methods.
Server side code
If Not (Request("method") Is Nothing) Then
method = Request("method")
username = HttpContext.Current.User.Identity.Name.ToString
Select Case UCase(method)
Case "GETPROJECTS"
Response.ContentType = "text/json"
Response.Write(GetProjects(Request("cid"), Request("status")))
Exit Select
end select
end if
Client Side code [using jquery]
$.ajaxSetup({
error: function(xhr, msg) { alert(xhr, msg) },
type: "POST",
url: "Ajax.aspx",
beforeSend: function() { showLoader(el); },
data: { method: 'GetProjects', cid: "2", status:"open"},
success: function(msg) {
var data = JSON.parse(msg);
alert(data.Message);
},
complete: function() { hideLoader(el); }
});
Hope this helps.