I am working on a project that has page flow controlled by a Controller of the MVC framework. For some complcated pages I must use the Classic WebForm type, rather than a regular View page. 
When the page in Classic ASP.net WebForm has finished its job, the page needs to redirect back to the MVC controller and go to next page decided by the Business logic in the Controller

Here, I listed some redirect code that may be useful.

In classic Web Form page
  protected void btnContinue_Click(object sender, EventArgs e)
        {
            BillingProcess process = CurrentProcess;//BillingmanagementService.GetProcess(Uid);
            process.CurrentStep = BillingManagementStep.TempCreditStart;//this is required, to make sure the current step
            Response.Redirect(ViewMapUti.GetProcessUrl("continue", process.CurrentStep, Uid));
           // Response.Redirect(string.Format("/BillingManage/Process/continue/{0}/{1}",process.CurrentStep, Uid));
        }

In Controller
    protected ActionResult GoToPage(BillingProcess process)
        {
            if (process != null)
            {
                RedirectResult rUrl = CheckIfClassicPage(process);
                if (rUrl != null)
                    return rUrl;
                return View(ViewMapUti.GetMapPage(process.CurrentPage), process);
            }
            else
                return View("Index");
        }
   protected RedirectResult CheckIfClassicPage(BillingProcess process)
        {
            string url = ViewMapUti.GetClassicUrl(process.CurrentStep, process.UidCustomerId);
            if (url != null)
                return Redirect(url);
            else
                return null;

        }


   In Help class ViewMapUti.cs
    public class ViewMapUti
{

// this need put in MapHelper.cs in the root public static String GetMapPage(string key)
{
///TODO:we should have a map in xml do defined which current viwe will be used. ///for example, we have made the change of Page1, rename to page2, but want keep the page2, ///just need add the page1 page2 in the mapfile if(key.Equals("initial",StringComparison.CurrentCultureIgnoreCase))
{
key="StartProcess";
}
return key;
}
public static string GetProcessUrl(string actionButton, BillingManagementStep step, long uid)
{
return GetProcessUrl("Process", actionButton, step, uid);
}
public static string GetProcessUrl(string view, string actionButton, BillingManagementStep step, long uid)
{
if (view == null )
return GetHomeUrl();
/// 1.{controller}/{step}/{uid}/{action}.aspx/{actionButton} // return string.Format("/{0}/{1}/{2}/{3}.aspx/{4}", "BillingManage", step,uid, view, actionButton); ///2. /BillingManage/Process.aspx?uid=121&actionButton=process&step=ProcessingRequest /// return GetVirtualPath() + string.Format("/{0}/{1}.aspx?uid={2}&actionButton={3}&step={4}", "BillingManage", view, uid, actionButton, step);
}
public static string GetHomeUrl()
{
return HttpRuntime.AppDomainAppVirtualPath+"BillingManage/Index.aspx";
}
public static string GetClassicUrl(BillingManagementStep step, long uid)
{
if (step == BillingManagementStep.StartProcess ||step==BillingManagementStep.Initial)
{
//if need classic //Don't use transfer, it will cause javascript error in Ajax sometime(not every time). //Server.Transfer("/Classic/startProcess.aspx?uid=" + uid); return (GetVirtualPath() + "/Classic/startProcess.aspx?uid=" + uid);

}
else if (step == BillingManagementStep.EcouponCredit)
{
return (GetVirtualPath() + "/Classic/EcouponCredit.aspx?uid=" + uid);
}
else if (step == BillingManagementStep.TempCreditStart)
{
return (GetVirtualPath() + "/Classic/TempCredit.aspx?uid=" + uid);
}
return null;
}
public static string GetVirtualPath()
{
return HttpRuntime.AppDomainAppVirtualPath.Equals("/") ? "" : HttpRuntime.AppDomainAppVirtualPath + "/";
}
}


  


 
Categories: Asp.net | MVC

When I try to export a complex page which has RadGrid Control to PDF file, it always returns an error message like
Script control '' is not a registered script control. 
Script controls must be registered using RegisterScriptControl() before calling RegisterScriptDescriptors().
Parameter name: scriptControl

After trying many different ways, I finally found the right solution to exporting the page without exception: Override the "Render" method in the page or the UserControl.
The code is below:

protected override void Render(HtmlTextWriter writer)
    {

        if (_isExport)
        {
            StringWriter stringWriter = new StringWriter(); //System.IO namespace should be used

            HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
            base.Render(htmlTextWriter);

            Response.Clear(); //this clears the Response of any headers or previous output
            Response.Buffer = true; //make sure that the entire output is rendered simultaneously

            ///
            ///Set content type to MS Excel sheet
            ///Use "application/msword" for MS Word doc files
            ///"application/pdf" for PDF files
            ///"application/vnd.ms-excel";
            Response.AddHeader("content-disposition", "attachment;filename=ShippingSheet.doc");

            Response.Charset = "";
            Response.ContentType = "application/msword";

            ///
            ///Render the entire Page control in the HtmlTextWriter object
            ///We can render individual controls also, like a DataGrid to be
            ///exported in custom format (excel, word etc)
            ///
            // PrintableShippingSheet1.RenderControl(htmlTextWriter);
            Response.Write(stringWriter.ToString());
            Response.End();

        }
        else
            base.Render(writer);
    }


 
Categories: Asp.net | C# | Telerik Controls

Just deployed my MVC project to another server. that server has asp.net framework 3.5 sp1 installed, but no MVC.

1. At First I got Http 403 Error, that because the server didn't support url like "/Home/Index/", this error message said that you don't have permission to browser the direction.  If you have full control of the web server, you can configure the IIS to recongize your MVC url, but it not works in many situation,  that's because the change may affect other applications in that server.

One of the solution is: Let your url looks like regular aspx page. for example "Home/Index.aspx".

Here is my new route map definition in global.ascx

 routes.MapRoute(
           "Default",                                              // Route name
           "{controller}/{action}.aspx/{id}",                           // URL with parameters
           new { controller = "Home", action = "Index", id = ""// Parameter defaults
       );
routes.MapRoute(
           "Process",                                              // Route name
           "{controller}/{step}/{uid}/{action}.aspx/{actionButton}",                           // URL with parameters
            new {controller = "BillingManage", action = "Index",step=0, actionButton="", uid = "0"// Parameter defaults
        );

2. Then it still not works in the site root. I need add a default.aspx file in the site root. In the default.aspx file, you can redirect the page to your real default "Home/Index.aspx".

3. But there are still another error happen, MVC.dll not found.  Ahha! that's easy, just need copy MVC.dll to the bin folder.

Find the C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 2\Assemblies

copy System.Web.Mvc.dll and Microsoft.Web.Mvc.Build.dll to your bin..

Bingo!

4. The last note of today: you can't put Telerik scriptmanager  with the MicrosoftMvcAjax.js in the same page , the ajax javascipt tell you "'sys.mvc.asynchyperlink' is null or not an object".



 
Categories: MVC

If you don't like the Layout create by template of MVC ValidationHelper, You can break it apart, and make your own.

    <% using (Html.BeginForm()) {%>       
UserName:
   <%=Html.EditorFor( model => model.UserName) %> 
<%=Html.ValidationMessage("UserName")%>
   Email:
   <%=Html.EditorFor( model => model.Email) %>   <%=Html.EditorFor( model => model.UserName) %>            <p>
                <input type="submit" value="Save" />
            </p>
    <% } %>
Just get this from Hariri's blog.
http://hadihariri.com/blogengine/post/2009/10/08/The-Principle-of-Least-Surprise.aspx

 
Categories: MVC

1. Create a Model for the View if you don't have one.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace BillingManagementWebGUI.Models
{
    public class IndexPageModel
    {
        [Required()]
        [Range(1, 99)]
        public long CustomerId { get; set; }
    }
}

2. Add Javascript to the SiteMast, becareful you must keep the Same Order like below.

 <script src="<%= Url.Content("~/Scripts/jquery-1.3.2.js") %>" type="text/javascript"></script> 
 <script src="<%= Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
 <script src="<%= Url.Content("~/Scripts/MicrosoftMvcJqueryValidation.js") %>" type="text/javascript"></script>
  
3. Update the View
 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<BillingManagementWebGUI.Models.IndexPageModel>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">      Start Page </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Billing Management Start Process</h2> <span id="msg" style=" color:Red;"><%=Html.Encode(TempData["MSG"]) %></span><br /> <% Html.ClientValidationEnabled = true; %> <% using (Html.BeginForm("StartProcess","BillingManage") ){ %> <fieldset> <%= Html.ValidationSummary("Broken stuff:") %> <%= Html.EditorForModel() %> <input id="btnStartProcess" value="Process" name="btnStartProcess" type="submit" /> </fieldset> <% } %> </asp:Content>

4. Run the code

here is the Magic piece:
<script type="text/javascript">
//<![CDATA[
EnableClientValidation({"Fields":[{"FieldName":"CustomerId","ValidationRules":[{"ErrorMessage":"The field CustomerId must be between 1 and 99.","ValidationParameters":{"minimum":1,"maximum":99},"ValidationType":"range"},{"ErrorMessage":"The CustomerId field is required.","ValidationParameters":{},"ValidationType":"required"}],"ValidatorId":"form0_CustomerId_validator"}],"FormId":"form0"}, null);
//]]> </script>

 
Categories: MVC

here is some blog for MVC2 Preview 2

http://blogs.msdn.com/shaan/archive/2009/10/01/new-features-in-asp-net-mvc-2-preview.aspx

and I need the Client side validation feature.

here is some more blog

https://blogs.msdn.com/pietrobr/archive/2009/10/03/asp-net-mvc-2-preview-2-client-validation.aspx

http://blogs.msdn.com/rickandy/archive/2009/10/03/client-side-validation-for-mvc-2-p2.aspx

http://blogs.imeta.co.uk/HHariri/archive/2009/10/07/client-side-validation-in-mvc-2.0.aspx

http://hadihariri.com/blogengine/post/2009/10/06/Client-Side-Validation-in-MVC-20.aspx

Pietro Brambati's blog: 

  • use Html.EnableClientValidation method on the View file
  • insert three javascript files : jquery-1.3.2.js, jquery.validate.js, MicrosoftMvcJQueryValidation.js. These files are included in the Scripts directory coming with ASP.NET MVC 2 Preview 2 project template

    Hariri find only with "using" the javascript code will be render

    <% Html.ClientValidationEnabled = true; %>
    
      <% using (Html.BeginForm()) {%>
    
            <%=Html.EditorForModel()%>   
                <p>
                    <input type="submit" value="Save" />
                </p>
        <% } %>
    
    here is the Model code:
      public class Customer
     {
         [Required(ErrorMessage = "First name is required")]
    
         public string FirstName { get; set; }
         [Required(ErrorMessage = "Last name is required")]
    
         public string LastName { get; set; }
    
         public string Email { get; set; }
    
     }
    
    public class Pals {
           [Required()]
           [Range(33,99)]
           public float Height { get; set; }
           [Required()]
           [StringLength(7)]
           public string Name { get; set; }
           [ScaffoldColumn(false)]
           public int ID { get; set; }
           public bool cool { get; set; }
           [DataType(DataType.EmailAddress)]
           [RegularExpression(@"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$")]
           public string email { get; set; }
           [DataType(DataType.MultilineText)]
           public string Bio { get; set; }
       }
    And here is Controller:
            [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult Edit(int id, Customer customer)
            {
                if (ModelState.IsValid)
                {
                    // TODO: Do whatever...
                    return RedirectToAction("Index");
                }
                return View(customer);
            }
    
    

    I will do post some my code in later.


  •  
    Categories: MVC

    Currently I am working on a project are using ASP.NET MVC, and I need reuse some user controls with Telerik Controls,
    As you know, many of those user controls for WebForm need enable ViewSate.
    So I had combined both new MVC and old WebForm pages in this project.
    and I had encountered and solved many issues both for integration and MVC
    I write some key points here as my collections and want to share with my visitors.
    Here is an article about adding MVC to regular website :link

     1. setup Route in Global.asax

      
    public static void RegisterRoutes(RouteCollection routes)
    {

    // routes.IgnoreRoute("Classic/{resource}.aspx?{*requestUrl}"); //the ? is not allow in the route config
    routes.IgnoreRoute("{resource}.aspx/{*pathInfo}"); //All .aspx regard as webform.
    routes.IgnoreRoute("{resource}.ash/{*pathInfo}"); //other type need escape
    routes.IgnoreRoute("Classic/{resource}.aspx/{*pathInfo}"); //I put my webform files in classic folder

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults
    );

    }
    2. Make your old UserControls work



    3. Fix those weird problems of Visual Studio 2008
    After copy the Classes such as "BaseUserControl.cs" to MVC project, whatever how many times I clean and rebuild the project, Those classes always can't be found by other classes.
    And another issue happen frequently is the Pages have using Telerik controls, always have error message 'Error Creating Control' at design time.
    After some research, I found  those step will solve these issues like a magic.

       step 1. Close your Visual studio 2008 .
       step 2. Go to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\ folder, delete all sub directories.
       step 3. Go to C:\Documents and Settings\yourname\Local Settings\Application Data\Microsoft\VisualStudio\9.0\ProjectAssemblies\
                  Delete all sub diretories.
       step 4. Restart.

    And some people said, if copy the Telerik dlls to Global assembly will fix Telerik issue.
      
     

     
    Categories: Asp.net | MVC | Telerik Controls | VS 2008

    一、通用篇
      1.1 不用new关键词创建类的实例
      1.2 使用非阻塞I/O
      1.3 慎用异常
      1.4 不要重复初始化变量
      1.5 尽量指定类的final修饰符
      1.6 尽量使用局部变量
      1.7 乘法和除法

    一、通用篇

      “通用篇”讨论的问题适合于大多数Java应用。

    1.1 不用new关键词创建类的实例

      用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用。但如果一个对象实现了Cloneable接口,我们可以调用它的 clone()方法。clone()方法不会调用任何类构造函数。

      在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单。例如,下面是Factory模式的一个 典型实现:

    public static Credit getNewCredit() {
      return new Credit();
    }

      改进后的代码使用clone()方法,如下所示:

    private static Credit BaseCredit = new Credit();
    public static Credit getNewCredit() {
    return (Credit) BaseCredit.clone();
    }

      上面的思路对于数组处理同样很有用。

    1.2 使用非阻塞I/O

      版本较低的JDK不支持非阻塞I/O API。为避免I/O阻塞,一些应用采用了创建大量线程的办法(在较好的情况下,会使用一个缓冲池)。这种技术可以在许多必须支持并发I/O流的应用中见 到,如Web服务器、报价和拍卖应用等。然而,创建Java线程需要相当可观的开销。

      JDK 1.4引入了非阻塞的I/O库(java.nio)。如果应用要求使用版本较早的JDK,在这里有一个支持非阻塞I/O的软件包。

      请参见Sun中国网站的《调整Java的I/O性能》。

    1.3 慎用异常

      异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地 (Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过 程中创建了一个新的对象。

      异常只能用于错误处理,不应该用来控制程序流程。

    1.4 不要重复初始化变量

      默认情况下,调用类的构造函数时, Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byte、short、int、long)设置成0,float和 double变量设置成0.0,逻辑值设置成false。当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链 中的所有构造函数都会被自动调用。

    1.5 尽量指定类的final修饰符

      带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为 String类指定final防止了人们覆盖length()方法。

      另外,如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联(inline)所有的final方法(这和具体 的编译器实现有关)。此举能够使性能平均提高50%。

    1.6 尽量使用局部变量

      调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创 建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。请参见《尽可能使用堆栈变量》。

    1.7 乘法和除法

      考虑下面的代码:

    for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }

      用移位操作替代乘法操作可以极大地提高性能。下面是修改后的代码:

    for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }

      修改后的代码不再做乘以8的操作,而是改用等价的左移3位操作,每左移1位相当于乘以2。相应地,右移1位操作相当于除以2。值得一提的是,虽然移位 操作速度快,但可能使代码比较难于理解,所以最好加上一些注释。


     
    Categories: Interview Question | Java