2013年11月1日星期五

ASP.NET MVC 4使用技巧9:使用Google Charts和JSON

Google Charts 令人爱不释手,功能强大而且简单美观,文档非常完善。

https://developers.google.com/chart/

这里同时推荐一下Playerground,真是是一个非常好用的“工具”,可以非常方便地进行测试。

http://code.google.com/apis/ajax/playground/

如果想画一个line chart,并使用JSON得到做图的数据,很简单,以下就是一个简单的例子,在我们的.cshtml中添加上我们需要的js代码,在这个例子中,

  • 引用jsapi库并使用一系列Google Chart API,进行做图。
  • 通过点击一个button激活做图function。
  • 通过google.visualization.events.addListener得到点击line的事件。
  • 通过$.post('/YourController/GetDrawJsonData', {}, function (d) { … …); }); 从我们的Controller中得到Json数据。
<script type="text/javascript" src="//www.google.com/jsapi"></script>



    <script type="text/javascript">






        google.load("visualization", "1", { packages: ["corechart"] });



        google.setOnLoadCallback(drawChart);



        function drawChart() {



            var chart = new google.visualization.LineChart(document.getElementById('chart_div'));






            var button_show_all = document.getElementById('show_all');



            //-- Set a button onclick event



            // Multi graph.



            button_show_all.onclick = function () {



                var options =



                {



                    title: 'All Heuristic Methods',



                    colors: ['#E6E6E6'],



                    //colors: ['#93ACE7'],



                    legend: { position: 'none' }



                    //legend: { position: 'top', maxLines: '5' }



                    //series: [{ color: 'blue', visibleInLegend: true }, { color: 'blue', visibleInLegend: true }]



                };






                // Add our selection handler.



                google.visualization.events.addListener(chart, 'select', lineChartHandler);



                //-- Chart click event



                function lineChartHandler() {



                    var selection = chart.getSelection();



                    if (selection.length > 0) {



                        alert('A Line was selected');



                    }



                }






                $.post('/Plan/GetDrawJsonData', {},



                function (d) {



                    //alert(d);



                    var data = google.visualization.arrayToDataTable(d);



                    // At the end draw the chart.



                    chart.draw(data, options);



                });



            }



   }






</script>








它的html代码就更简单了:



<input id="show_all" type="button" class="btn btn-info" value="Show All Charts"  />



<br />



<div id="chart_div" style="width: auto; height: 400px;">



</div>





在Controller中只需要加入生成JSON数据的方法:



public ActionResult GetDrawJsonData()



{



     List<object> data_todraw = ... ... ...;



    return Json(data_todraw);



}


 


进阶一下,如果想要通过JSON改变做图的options,譬如说是颜色,其实也很方便,先在js中加入一个chart_opt的arrary:



var chart_opt = new Object();



chart_opt.title = "Heuristic Method";



var colors = new Array();



colors[0] = "#93ACE7"



chart_opt.colors = colors;



var lengend = new Object();



lengend.position = 'none';



chart_opt.legend = lengend;


 


然后通过一个function得到json数据,这里的row: input_counter是一个输入,我们的Controller的方法可以通过这样的方式得到这个输入:



$.post('/YourController/GetDrawJsonOptionSingle', { row: input_counter },



function (f) {



   //console.log(f);



   //If for some reason you cannot modify your server side script to provide 



   //a valid JSON in the tags property you could still use eval instead of $.parseJSON:var tags = $.parseJSON(response.tags);



   var colors_tmp = eval(f);



   console.log(colors_tmp);



   for (i = 0; i < colors_tmp.colors.length; i++) {



       colors[i] = colors_tmp.colors[i];



   }



});


与之对应的Controller里的method,需要使用一个Class里面定义colors的List,最后通过return Json(…)返回JSON数据:



public class ChartOptions
{
    public List<string> colors;
}


 

public ActionResult GetDrawJsonOptionSingle(int row)
{

 

    ChartOptions tmp = new ChartOptions();



    tmp.colors = new List<string>();



    for (int i = 0; i < ROW_COUNT_ALL; i++)



    {



        if (i == row)



        {



            tmp.colors.Add("#F30A0A");



        }



        else



        {



            tmp.colors.Add("#E6E6E6");



        }



    }



    return Json(tmp);



}

2013年8月13日星期二

ASP.NET MVC 4使用技巧8:自定义CheckBox及ActionResult的Subtypes

今天简单介绍一下如何编写一个自定义的CheckBox:

<script type="text/javascript">
    function unhide(id_name, check_box) {
        var check = (check_box.checked) ? "block" : "none";
        document.getElementById(id_name).style.display = check;
    }
</script>



@Html.CheckBoxFor(model => model.NotifyEmail, new { @checked = "unchecked" , @onclick="unhide('hidden-input-email', this)"})Email Notification<br>
<div id="hidden-input-email" style="display:none">
<p>
   @Html.LabelFor(model => model.Email) 
   @Html.TextBoxFor(model => model.Email, new { @readonly="readonly" })
</p>
<div class="editor-field">
   @Html.TextAreaFor(model => model.EmailInfos, new { style = "width: 200px; height: 100px;" })
</div>


       
上面的View代码,使用了自定义的CheckBox
简单的说明一下:

  1. @Html.CheckBoxFor(model => model.NotifyEmail, new { @checked = "unchecked" , @onclick="unhide('hidden-input-email', this)"})Email Notification<br>
  2. 当我们点击这个CheckBox的时候会将隐藏的输入框显示出来,这里使用了一个简单的Javascript,当@onclick的事件被触发时。
  3. 同时这里使用@checked = "unchecked"设置初始为unchecked。
  4. 参数:model => model.NotifyEmail是我们对于checkbox的view model binding。
  5. 我们的TextAreaFor也通过参数:new { style = "width: 200px; height: 100px;" }自定义了大小。

 

ActionResult有很多种Subtypes,我今天才知道,以前只用过3种。
出处:http://forums.asp.net/t/1448398.aspx


       
ViewResult - Renders a specifed view to the response stream

PartialViewResult - Renders a specifed partial view to the response stream

EmptyResult - An empty response is returned

RedirectResult - Performs an HTTP redirection to a specifed URL

RedirectToRouteResult - Performs an HTTP redirection to a URL that is determined by the routing engine, based on given route data

JsonResult - Serializes a given ViewData object to JSON format

JavaScriptResult - Returns a piece of JavaScript code that can be executed on the client

ContentResult - Writes content to the response stream without requiring a view

FileContentResult - Returns a file to the client

FileStreamResult - Returns a file to the client, which is provided by a Stream

FilePathResult - Returns a file to the client       

2013年8月11日星期日

ASP.NET MVC 4使用技巧7:加入角色(Roles.AddUserToRoles)和使用者授权

加入角色

1. 加入角色信息到webpages_Roles表中

我们可以在Server Explorer中非常方便地加入角色信息进入webpages_Roles表,如下图所示:

howto_show_table_data

然后加入信息,如下图所示,我们加入5种角色。

webpages_roles_table

2. 在Controller中给注册的用户信息加入角色,需要使用到Roles.AddUserToRoles方法,具体可以参阅:

http://msdn.microsoft.com/en-us/library/system.web.security.roles.addusertoroles.aspx

在下面的例子中,我们在Register方法(位于AccountController.cs中)使用了Roles.AddUserToRoles方法(它也就是一个User, Roles, and Membership static classes ),将得到的model的role信息存入,这里需要对应model和view,关于register的model和view这里就不多写了。

[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid)
    {
    your code…. your code
             string choosenRole;
                if (model.Position == 0)
                    choosenRole = "Admin";
                else if (model.Position == 1)
                    choosenRole = "Planer";
                else if (model.Position == 2)
                    choosenRole = "Controller";
                else if (model.Position == 3)
                    choosenRole = "Manager";
                else
                    choosenRole = "Employee";

                System.Web.Security.Roles.AddUserToRole(model.UserName, choosenRole);
    WebSecurity.Login(model.UserName, model.Password);

                return RedirectToAction("Index", "Home");
            }
your code … your code
return View(model);
}

使用者授权


需要使用membership的role控制这样才能使用,很简单我们使用[Authorize]修饰词

譬如
[Authorize(Roles = "Admin,Manager")]

或者
[Authorize(Roles = "Manager")]

[Authorize(Roles = "Admin")]

也可以限定用户,譬如

[Authorize(User="Alex")] 

譬如在HomeController.cs中:

[Authorize(Roles = "Manager")]
public ActionResult Contact()
{
    ViewBag.Message = "";
    return View();
}

2013年8月9日星期五

ASP.NET MVC 4使用技巧6:Bundle和fullcalendar

fullcalendar是我见过最好的开源jQuery plugin,提供drag & drop calendar功能,而且是使用MIT license。

1. 下载fullcalendar,先将所有需要的东西放入Scripts和Content文件夹里

2. 设置BundleConfig.cs

在App_Start可以找到BundleConfig.cs

加入

bundles.Add(new ScriptBundle("~/bundles/calendar").Include("~/Scripts/fullcalendar.min.js"));

bundles.Add(new StyleBundle("~/Content/calendar").Include(
                           "~/Content/fullcalendar.css"));

其中("~/bundles/calendar")为初始化的虚拟目录,它的名称不能跟真正的目录相同 也就是 后面的Include里的目录。

3. 在譬如\Views\Shared\_testLayout.cshtml中加入fullcalendar的css和其需要的js库。

需要加入以下两行代码:

@Styles.Render("~/Content/calendar") //就是 calling "~/Content/fullcalendar.css"。

@Scripts.Render("~/bundles/fullcalendar") //就是 calling "~/Scripts/fullcalendar.min.js"。

注意,导入js库的顺序,否则将不能使用,最后导入fullcalendar。

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/fullcalendar")
@RenderSection("scripts", required: false)
 

有两个要点需要注意的:a. 要将它们放入<header> </header>中,而不是<body> </body>中延迟调用。

b. 注意如果要实现drag & drop calendar功能,需要使用<script src='~/Script/jquery-ui-1.10.2.custom.min.js'></script>,这可以加入到<header> </header>,当然也可以使用bundles。

4. 这时候可以添加View,选择Use a layout or master page,在下拉菜单中可以选择我们刚刚做的_testLayout.cshtml,最后在生成的view加入

<div id='calendar'></div>    

就可以了,现在可以看到一个空的calendar。

5. 最后我们使用MVC,我们需要编写model和controller,生成json的events传递给calendar,以下代码来自于http://szahariev.blogspot.de/2009/08/jquery-fullcalendar-and-aspnet-mvc.html。

Model:

public class CalendarDTO
{
    public int id { get; set; }
    public string title { get; set; }
    public long start { get; set; }
    public long end { get; set; }
    public string url { get; set; }
}

 

Controller:

public ActionResult CalendarData()
{
    IList<CalendarDTO> tasksList = new List<CalendarDTO>();

    tasksList.Add(new CalendarDTO
    {
        id = 1,
        title = "test",
        start = ToUnixTimespan(DateTime.Now),
        end = ToUnixTimespan(DateTime.Now.AddHours(4)),
        url = ""
    });

    return Json(tasksList, JsonRequestBehavior.AllowGet);

    //return View();
}

private long ToUnixTimespan(DateTime date)
{
    TimeSpan tspan = date.ToUniversalTime().Subtract(
    new DateTime(1970, 1, 1, 0, 0, 0));

    return (long)Math.Truncate(tspan.TotalSeconds);
}

 

6. 最后在view里面加一个js funcution,就完成了

View:

<script type="text/javascript">
       $(document).ready(function() {
           $('#calendar').fullCalendar({
               events: "/YourControllerName/CalendarData"
           });
       });  
 </script>

<div id="calendar">
</div>

2013年8月7日星期三

ASP.NET MVC 4使用技巧5:SQL命令

在这篇文章简要介绍SQL在C#中的使用,和MVC没有太大关系。

需要:

using System.Configuration;
using System.Data.SqlClient;

譬如,Controller中的一个方法:

public ActionResult Information()
{
      string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
      List<string> users = new List<string>();
      using (SqlConnection conn = new SqlConnection(connectionString))
      {
              // Open the connection
            conn.Open();
            string sql = "SELECT * FROM UserProfile";
            using (SqlCommand cmd = new SqlCommand(sql, conn))
            {
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    users.Add(reader["UserName"].ToString());
                }
                reader.Close();  
            }
            conn.Close();
       }
       ViewBag.Message = "Info";
       return View(users);
}

先总体简要解释一下以上Controller方法代码:

其实一般而言,基本SQL操作需要以下5步,这里还是以上面的代码为例进行介绍:

1. 连接服务器

string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

using (SqlConnection conn = new SqlConnection(connectionString))

conn.Open();

2.SQL 字符串赋值(需要执行的sql命令)

string sql = "SELECT * FROM UserProfile";

3. 新建命令

using (SqlCommand cmd = new SqlCommand(sql, conn))

4. 执行命令

分为三种命令,相应调用不同的方法:

a 不需要查询的(插入,更新,删除)

cmd.ExecuteNonQuery();

该函数会返回收到影响的总行数。

b 只需要查询一个值的

cmd.ExecuteScalar();

该函数会返回使用的sql语言查询的结果

譬如:

string user_name = "John";

var sql = String.Format("SELECT Company FROM UserProfile WHERE [UserName] = '{0}'", user_name);

using (SqlCommand cmd = new SqlCommand(sql, conn))

{

    string test = cmd.ExecuteScalar().ToString();

}

c 需要同时查询得到多个值的

//新建一个SqlDataReader 

SqlDataReader  reader = cmd.ExecuteReader(); 

//读取一行数据到Reader中

(reader.Read())

{

//将Reader中的数据读取走

users.Add(reader["UserName"].ToString());

}

//关闭Reader

reader.Close();  


5. 关闭连接
conn.Close();

更多内容请参考:

http://www.dotnetperls.com/sqlcommand