Thursday, December 15, 2011

ASMX service in MVC 3 Razor

We at Anthem Infotech pvt. ltd. recently came across an issue with using ASP.net asmx service with ASP.net MVC 3 Razor project, so we set out on a quest to resolve the issue with a number of options in mind 


  1. Using Javascript to call and handle the service calls
  2. consuming the service by simply adding a web reference in the page controllers (naah too easy)
so we decided to go the Javascript way as it best suited our needs and was a challenge for us in technical terms.

before moving to describing the solution, here are the 2 urls which where very helpful in working out a solution



Step 1 is a copy of step 3 from dotnet by example blog, to enable the service to be callable from javascript you need to add the [ScriptService] tag on the top of the web service class.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class DemoService : System.Web.Services.WebService
{
 [WebMethod]
 public string HelloWorld( string ToSomeone )
 {
   return "Hello World" + ToSomeone;
 }
}

Step 2: Is adding web reference of the service as we normally do in any case


Step 3:


add 2 script tags like below
 src="@Url.Content("~/Scripts/MicrosoftAjax.js")"


 src="@Url.Content("service.asmx/js")"


first tag refers to the microsoftajax.js already present in the script folder of the MVC 3 project and second tag refers to the service asmx page with a trailing "/js" tag this gives the scripted version of service which can then be directly called in javascript methods.


function Regscan() {
 var   ip = hdIP.value; // hdIP is a hidden variable that has the IP value

 demoproject.service.Registeruser(ip, RegscanCallback); 
 // Service call with call back method that is pass the result.

      }

 function RegscanCallback(result) {
          var id = result;
          somemethod(id);
      }







for seeing the asmx java script simply call the web service url with trailing /js you will see the methods that you can call. 


Hold Up

Wednesday, November 2, 2011

ASP.net Base Page


The auto-generated ASP.NET page class must extend the Page class (as shown in the code below), You can optionally create a base class from which all pages will derive from, When creating a base class, you'll typically have this base class extend the Page class. If you are using the code-behind model your code-behind classes will need to be modified to inherit from the new base class as opposed to the Page class. This gives you greater flexibility in controlling your application and reduce code significantly if done correctly for example if you where to place a simple check of user roles and check access on any number of pages by just Inheriting the page from the custom base class you created. 


Standard ASP.NET page code

public class WebForm1 : System.Web.UI.Page
{
 private void Page_Load(object sender, System.EventArgs e)
 {
  // Put user code to initialize the page here
 }

 #region Web Form Designer generated code
    ... code removed for brevity ...
 #endregion
}



Base Page class inheriting System.Web.UI.Page

public class MyBaseClass : System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
       // ... add custom logic here ...
       
       // Be sure to call the base class's OnLoad method!
       base.OnLoad(e);
    }
}



Now Page is inheriting from MyBaseClass and not directly from the Page Class

public class WebForm1 : MyBaseClass
{
 private void Page_Load(object sender, System.EventArgs e)
 {
  // Put user code to initialize the page here
 }

}



Now in the  above code we see  that in the MyBaseClass we are overriding the page load method and can add custom code here, I posted a example of base page implementation in my earlier blog about Multilingual website where we had easily implemented the base page across the website and checked the database for user language preference and updated the page culture accordingly with minimal code.


You can get tips on good usage of Base page from this article http://dotnetslackers.com/articles/aspnet/Four-Helpful-Features-to-Add-to-Your-Base-Page-Class.aspx


In the end I would like to state that with Base page you can handle a complex task or a very simple task within the page execution cycle and not having to re-write the code at several locations. 



Hold Up

Thursday, October 20, 2011

calling Javascript methods on updatepanel events

Recently came up with a scenario where I need to call a Javascript function to update a label with client side time on auto save, while auto saving was working fine, the only issue was capturing the time, since the label was updated at server we would end up with server time, so the do get client side time the option is to call a JS function at end request of update panel now the problem, there are multiple update panels on the page how do we know which panel is called, after digging a lot, I fond this discussion on stack overflow http://stackoverflow.com/questions/338702/how-to-call-a-client-side-javascript-function-after-a-specific-updatepanel-has-b 


Code on stack overflow


$(document).ready(function() {
 panelsLoaded = 1;   Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(PageLoaded) 
 }); 


 function PageLoaded(sender, args) { 
   console.log("I have occured " + panelsLoaded++ + " times!"); 
   var panelsCreated = args.get_panelsCreated(); 


   for (var i = 0; i < panelsCreated.length; i++) { 
     console.log("Panels Updating: " + panelsCreated[i].id); 
   } 
  var panelsUpdated = args.get_panelsUpdated(); 


 for (var i = 0; i < panelsUpdated.length; i++) { 
 console.log("Panels Updating: " + panelsUpdated[i].id); 
 } 
 } 


My Modified version 


$(document).ready(function () {        Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(PageLoaded) 
 }); 


function PageLoaded(sender, args) { 
  var panelsUpdated = args.get_panelsUpdated(); 


  for (var i = 0; i < panelsUpdated.length; i++) { 
     if(panelsUpdated[i].id == "<%=UpdatePanel2.ClientID%>") 
                 alert('timer called');                     
         } 
     } 
 } 


This enabled us to call timer string update after isolating the update panel, we thanks james for sharing this code, in the first place. Hope this is useful to you, please give your comments and share this article if you do.




Hold Up


kick it on DotNetKicks.com

Monday, September 19, 2011

Multilingual website in asp.net

While its neither new nor overly complex to implement multiple languages in ASP.net, it can be at times confusing and at times bit over the top in certain scenarios. ASP.net provides resource files which can be used to update the content based on browser language choice. The other option is to have a button or user choice saved in the database which is picked up as soon as user logs in. 

Before moving further let me explain a bit what need to done at the html level, first this is key as if you have not planned for this from the start doing this at the last step can get very irritating, while defining the labels/ literals that need to switched over to the other language in addition to ID and Runat tag you need to define resource key like meta:resourceKey ="FirstName" the same needs to be define in the corresponding resource file. with this out of the way, we need to set the page UICulture and Culture the same can be set at Page directive level and in web.config level if you want it to static at global level in the application. 

now we need to override the page Initialize Culture method as shown below, here we are fetching user selected language from class user as a property. and rest is just setting of values no rocket science here.

protected override void InitializeCulture()

 {

        clsUsers obj = new cls.Users();
                                String selectedLanguage = obj.Language;

        UICulture = selectedLanguage;

        Culture = selectedLanguage;

        Thread.CurrentThread.CurrentCulture =
                CultureInfo.CreateSpecificCulture(selectedLanguage);
       Thread.CurrentThread.CurrentUICulture = new
       CultureInfo(selectedLanguage);
      base.InitializeCulture()

}

an alternative to doing this at every page is using a base page class, here a class is inherited by System.Web.UI.Page and above method is written once and same is applicable in all the pages that inherit from base page instead of System.Web.UI.Page. More on base page is updated on the blog.

This is how the class will look like 
public class BasePage : System.Web.UI.Page

This how pages.cs will look like
public partial class UserInfo : SomeProject_BLL.BasePage

Looking forward to your comments 


Hold Up