Tag Archives: C#

Example test your controller, Nunit test

for you home controller:

using System.Web.Mvc;

namespace WestBanking.Controllers
{
    public class HomeController : Controller
    {
       

        public ActionResult Index()
        {
            return Redirect("http://netbank.test.com");
        }
    }
}

here is your test

using WestBanking.Controllers;
using NUnit.Framework;
using TestStack.FluentMVCTesting;

namespace WestBanking.ControllerTests   
{
    [TestFixture]
    public class HomeControllerTests
    {
        [Test]
        public void ShouldRedirect()
        {
            var sut = new HomeController();

            sut.WithCallTo(x => x.Index()).ShouldRedirectTo("http://netbank.test.com");
        }
    }
}

Advertisements

Nunit test in Visio Studio – Set up – To be continue

Recently my job need write all the unit test for my project and I haven’t done this before, and I like share my experience here, and hope that could help someone else.

First, Install an test runner  that will help you do the test in Visual Studio.

Tool > extension and updates > search online> nunit test adapter

nunit test

Second, create an test project

Third, Open the PM console, install some useful packages:

Nunit

Moq

TestStack.FluentMVCTesting

Create custom HtmlHelper to Render different type of Twitter Card

In this day, all the social media site is very important, I have task need implement the Twitter Cards into all the existing projects.

Render partial View is fine, but since just need same meta data, so I just create a custom HtmlHelpler, I put my works here, anyone think that helpful, could plug into your site.

public static class TwitterCardHelper
    {
        //this is the base method
        public static MvcHtmlString TwitterCard(this HtmlHelper html, string cardType, string title, string description, string image = null, object listAttributes = null,object productAttributes = null)
        {           
            
            var format = @"<meta name=""twitter:{0}"" content=""{1}"" />";
            var sb = new StringBuilder();
            var config = ProjectConfigurationSection.GetConfig();
            sb.AppendFormat(format, "card", html.Encode(cardType));
            sb.AppendFormat(format, "site", config.ProjectEnvironment == ProjectEnvironment.Production ? config.ProjectDisplayName : String.Format("{0} ({1})", config.ProjectDisplayName, config.ProjectEnvironment.GetDescription()));
            sb.AppendFormat(format, "title", html.Encode(title));
            sb.AppendFormat(format, "description", html.Encode(description));
            if (cardType == "summary" || cardType == "summary_large_image")
            { 
                sb.AppendFormat(format, "image", UriExtensions.Parse(image).AbsoluteUri);
            }

            if(listAttributes !=null)
            {
                 sb.Append(GetHtmlAttributes(listAttributes));
            } 

            return MvcHtmlString.Create(sb.ToString());
        }

        //below is several overloads method for your to choose different type of TwitterCard 
        public static MvcHtmlString TwitterSummaryCard(this HtmlHelper html, string title, string description, string image = null)
        {
            return TwitterCard(html, "summary", title, description, image);
        }

        public static MvcHtmlString TwitterSummaryCardWithLargeImage(this HtmlHelper html, string title, string description, string image = null)
        {

            return TwitterCard(html, "summary_large_image", title, description, image);
        }


        //listAttributes sample:
        //    new{
        //         iphoneName ="iphoneName",
        //         iphoneId="iphoneId",
        //         iphoneUrl="iphoneUrl",
        //         ipadName = "ipadName",
        //             ipadId="ipadId",
        //         ipadUrl="ipadUrl",
        //         googleplayName="googleplayName",
        //         googleplayId="googleplayId",
        //         googleplayUrl="googleplayUrl"
        //      }
        public static MvcHtmlString TwitterAppCard(this HtmlHelper html,string title,string description,object listAttribute)
        {
            return TwitterCard(html, "app", title, description, null, listAttribute);
        }

        
      //below two member is to render anonymous type of object to string
        private static string GetHtmlAttributes(object listAttributes)
        {
           
             var format = @"<meta name=""twitter:app:{0}:{1}"" content=""{2}"" />";
            var sb = new StringBuilder();

            if (listAttributes != null)
            {
                var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(listAttributes);
                foreach (var item in attributes)
                {
                   
                    if (item.Key == "iphoneName") sb.AppendFormat(format, "name", "iphone", item.Value);
                    if (item.Key == "iphoneId") sb.AppendFormat(format, "id", "iphone", item.Value);
                    if (item.Key == "iphoneUrl") sb.AppendFormat(format, "url", "iphone", item.Value);

                    if (item.Key == "ipadName") sb.AppendFormat(format, "name", "ipad", item.Value);
                    if (item.Key == "ipadId") sb.AppendFormat(format, "id", "ipad", item.Value);
                    if (item.Key == "ipadUrl") sb.AppendFormat(format, "url", "ipad", item.Value);

                    if (item.Key == "googleplayName") sb.AppendFormat(format, "name", "googleplay", item.Value);
                    if (item.Key == "googleplayId") sb.AppendFormat(format, "id", "googleplay", item.Value);
                    if (item.Key == "googleplayUrl") sb.AppendFormat(format, "url", "googleplay", item.Value);
                    
                }

            }

            return sb.ToString();
        }

Intergrate with google analytics — retrieve data back from google analytics

Recently task need retrieve data back from google analytics and put it into the existing website. Online have a lot tutorial explain how to do it.

Here I just record my one over there hope could help my fans.

And I have a exsiting asp.net C# mvc project is on life and they are already embedded google analytics, and my job is to create a admin function so when the projects admin login there is a page display that google analytics datas.

And google already have a client side library for the .net developer to user it.

Step1: PM> Install-Package Google.Apis.Analytics.v3

Step2: For retrieve data from google analytics, you actially just need do two things.

1) Authenticate with google analytics

2) using Google analytics core reporter

I have some words about  Authenticate with google analytics, for me I personally think that just use the Service Account is fine. if you like restrict who is going to see that datas in asp.net mvc is very easily to retrieve it.

So for Authenticate with google analytics using Service Account steps:

1) you need have google account, I mean google account, could be your gmail account and could be your company email.

2)Then use you google account register a Google analytics account.

3) go to the google console enable Google analytics.

4)Create a service account by:

  • First click create a new OAuth2 projects( that is google recommend), then pop out a new window choose the service account, and download that key, put this key into your application,
  • Second don’t forget to go back to google analytics, register that service account email to give permission to this email address.

All of above things ready, now you could start write your code to using the core reporter service.

Here is my implementation class for

   
namespace XXX.XXX.Service.GAServices
{
    #region two way Authenticate with google analytics
    public  class GAAuthenticateHelper
    {
        public static AnalyticsService AuthenticateServiceAccount(string serviceAccountEmail, string keyFilePath)
        {

            // check the file exists
            if (!File.Exists(keyFilePath))
            {
                Console.WriteLine("An Error occurred - Key file does not exist");
                return null;
            }

            string[] scopes = new string[] { 
                
                      AnalyticsService.Scope.Analytics,  // view and manage your analytics data
                     // AnalyticsService.Scope.AnalyticsEdit,  // edit management actives
                     // AnalyticsService.Scope.AnalyticsManageUsers,   // manage users
                      AnalyticsService.Scope.AnalyticsReadonly
                                           };     // View analytics data            

            var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
            try
            {
                ServiceAccountCredential credential = new ServiceAccountCredential(
                    new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = scopes
                    }.FromCertificate(certificate));

                // Create the service.
                AnalyticsService service = new AnalyticsService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "GA Dashboard", // to do this
                });
                return service;
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.InnerException);
                return null;

            }
        }
    }

    #endregion


    #region Google analytics core reporter
    // Google analytics query help for retrieve datas https://ga-dev-tools.appspot.com/query-explorer/
  public class GAReportingHelper
  {
      public class OptionalValues
      {
          private string dimensions { get; set; }
          private string filter { get; set; }
          private string sort { get; set; }
          private string segment { get; set; }
          private int maxResults { get; set; }
          private DataResource.GaResource.GetRequest.SamplingLevelEnum sampleingLevel = DataResource.GaResource.GetRequest.SamplingLevelEnum.DEFAULT;

          public string Dimensions { get { return dimensions; } set { dimensions = value; } }
          public string Filter { get { return filter; } set { filter = value; } }
          public string Sort { get { return sort; } set { sort = value; } }
          public string Segment { get { return segment; } set { segment = value; } }
          public int MaxResults { get { return maxResults; } set { maxResults = value; } }
          public DataResource.GaResource.GetRequest.SamplingLevelEnum Sampling { get { return sampleingLevel; } set { sampleingLevel = value; } }
          public OptionalValues()
          {
              this.dimensions = null;
              this.filter = null;
              this.sort = null;
              this.segment = null;
              this.sampleingLevel = DataResource.GaResource.GetRequest.SamplingLevelEnum.DEFAULT;
              this.maxResults = 1000;
          }
      }

      public static GaData Get(AnalyticsService service, string profileId, string startDate, string endDate, string metrics, OptionalValues optionalValues)
      {
          DataResource.GaResource.GetRequest request = service.Data.Ga.Get(String.Format("ga:{0}", profileId), startDate, endDate, metrics);
          if (optionalValues == null)
          {
              request.MaxResults = 1000;
          }
          else
          {
              request.MaxResults = optionalValues.MaxResults;
              request.Dimensions = optionalValues.Dimensions;
              request.SamplingLevel = optionalValues.Sampling;
              request.Segment = optionalValues.Segment;
              request.Sort = optionalValues.Sort;
              request.Filters = optionalValues.Filter;

          }
          return ProcessResults(request);
      }
      // Just loops though getting all the rows.  
      private static GaData ProcessResults(DataResource.GaResource.GetRequest request)
      {
          try
          {
              GaData result = request.Execute();
              List<IList> allRows = new List<IList>();
              // Loop through until we arrive at an empty page
              while (result.Rows != null)
              {
                  //Add the rows to the final list
                  allRows.AddRange(result.Rows);
                  // We will know we are on the last page when the next page token is
                  // null.
                  // If this is the case, break.
                  if (result.NextLink == null)
                  {
                      break;
                  }
                  // Prepare the next page of results             
                  request.StartIndex = request.StartIndex + request.MaxResults;
                  // Execute and process the next page request
                  result = request.Execute();
              }
              GaData allData = result;
              allData.Rows = (List<IList>)allRows;
              return allData;
          }
          catch (Exception ex)
          {
              Console.WriteLine(ex.Message);
              return null;
          }

      }
  }

#endregion


}

If you have some red line show, just use ctrl + . to add the reference.
Now I create a google analytics service class file, so in my controller, I just need call that method.
And In my controller, I create a method:

private static GADATA.GaData GaReportingDatas(AdminStatsVM model)//I only allow my admin to see, here I pass my admin data over there, and once I got the data will asign to my adminStatsVM model
        {
            AnalyticsService gaService;            
            string email = "yourserviceaccountemail@developer.gserviceaccount.com";
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\yourprivatekey.p12");
  //this is your download file put here, 
            gaService = GAAuthenticateHelper.AuthenticateServiceAccount(email, path);
            string profileId = "XXXXX";//this can find in google analytics
            string metricsStr = "ga:sessions,ga:users,ga:pageviews,ga:pageviewspersession,ga:avgsessionDuration,ga:bounces,ga:percentNewSessions";//google allow pass multiply metrics by separate by comma
            string startDate = model.StartDate.ToString("yyyy-MM-dd");
            string endDate =  model.EndDate.ToString("yyyy-MM-dd"); 
            var gaData = GAReportingHelper.Get(gaService, profileId, startDate, endDate, metricsStr, null);
            return gaData;
        }

Now you can use it anyway you like.
How to renter to the page?
here in my model I have one member

 public GaData GaDatas { get; set; }

so in my controller, I assign it to

 var record = new AdminStatsVM
            {
                ...
                GaDatas = GaReportingDatas(model);//call that method above

            };

here in the view:

@foreach (var item in Model.GaDatas.Rows)
                        {
                                                        
                            foreach (string col in item)
                            {@col.FormatDigit()

} }@Model.GoogleAnalyticsUrl

What is FormatDigit(),

 public static String FormatDigit(this String input)
        {
            decimal myNum = decimal.Parse(input);           
            return  String.Format((Math.Round(myNum,2) == myNum) ? "{0:0.00}" : "{0:0}",myNum);
        }

I was following

http://www.daimto.com/google-analytics-api-v3-with-c/#Google_Analytics_API_8211_Introduction

Anything don’t understand it, could have view this link first.

very helpful.

Have fun!

Using viewbag pass data to the view and bind it to my dropdownlist.

In my booking view I has a dropdownlist need bind to my database table, In this tast I just use viewbag. I know it is good habit bind the view to your viewmodel, but sometime you need do some nasty thing to get the job quickly done. So here is the code in my controller to retrive the data and pass it to the viewbag.

retrevedatafromdatabses

here I pass to SelectLists to my view.

I my view you just need this one line of code to get it.

@Html.DropDownList(“SydneySuburb”, null, “Select »”, new { @id = “to_suburb” })

@Html.DropDownList(“SydneySuburb”, null, “Select »”, new {  @id = “from_suburb” })

the dropdown is look like this

dropdownlistcontroller

Simple isn’t it!!!

First I tried to do this, I search internet, there are expert write it in very complexed way. The expert alway like to write it like that to make them looking like expert( in my view).

here I just figure it out in very simple way.

Have fun!

JQuery Auto complete work with bakcode by using asp.net mvc

Recently to convert the new website, I have a bookinng form for the clients to finished the booking,there is some exiting data need to using auto complete. In the past I alway use ajax tool control kits to achieve that result. But now I am kind of fun for JQuery. Here is the Jquery Autocomplete textbox

First I have databses contain all the subuerbs, here is my database table.

databaseSuburbs

here is my action in my BookController:

databseJasonResult

I let it return json because json is the fast and easy analyse data at moment.

Then in your view , just add the reference to JQuery UI:

autocompleteJqury

You could ignore the timepicker.min.css, and timepicker.min.js, I use it to picker up the time, for autocomplete don’t need those two references.

here just in you view you just need one more line.

@Html.TextBox(“SearhToSuburb”, null, new {type=”text”,@class=”form-control”, @id = “search_to_suburb” })

That’s it. Simply isn’t it. Have fun. Below is what will it looking like.feels

Using two Way Adding “active” tag to your navigation list in an asp.net mvc Layout page

Recently my task need convert this website http://www.royalecoach.com.au/royale.asp (this is wrote by using classic asp) into asp.net MVC.

First I need to create a layout.cshtml for my the new version of this website.Then navigation need add a class named active to it when the action method has been called.

The first way is very simpley, you could wirte a logic to your view, here is one solution:

addClassNametoLi

But the rule of MVC is the view must be simply as possible, I don’t like this nasty and yuck c# code sit in there. So there is a way just by write a CustomHtmlHelpers to improve it.

here is my class file:

htmlHelper

 

Then in your layout page ,your could use it like:

layoutMenu

That’s it. By the way, I am using asp mvc4. Hope that could help some one else.

Have fun:)

Basic struction — create Database first ASP MVC Application(Models in three way)

Here in the internet have a lot tutorial introduction about create code first asp mvc application, but in the real life world the database always aready is exsiting. I am not mvc experter, I am fresher now. It took me a while to get the basic struction a while.So I like to write it down wish this could help some people like me struggling in the beginning.

OK, let me asume that we are going to create a online store ecormmerce website.

Way one: basic struction

Then you create a new MVC project through VS2013, first thing is add a connection string to your root web.config file.

It is like this:connectionStr

Modelsisnothingjustclassfile

Models is nothing just class file. You map your table to class file, then when you create a controller you could select strongly type.

finally is the Add one line to Global.asax to stop populater some seed data

GlobalNeedAddOneLine

See the null meaning don’t popular seed data.

Way two: basic struction(Models is another project)

I won’t talk about the controller or the views. But Models could anything, Web services, WCF and don’t sit in your project, the model is not neccessary sit in your project.So your project only have controller and Views, but the Models is independent. Here is a simple practise I did in my Demo struction is like this:

separateModelMvc

Way three: basic struction(Model is your entity Framework)

MvcEntityFrameworkStruction

Create marquee news in front page and the news is read from the database with expired data,also included management page to insert news

My boss just saw other company website has a marquee new on the front page, so she asked me if I could make one and arrow her to insert news and the news will dispear at the expired data.

For achieve that task, first I create a table in my database table, here is my table:

breadNewTable

then I write a store proceedure, a little tip for fresh guy, alway use store preceedure to insert data for security reasons.

breadNewStoreProceedure

Now, We could start the front end job. I create a user control:marquee.ascx(so you could put it in anyway you like), to display the new, here is my html code:

frontUCmarquee

here is the backcod, I used ado.net to open the database and qurery what I need, and bind it to my BulledtedList:

databasereadertomarquee

See the code this if(!IsPostBack) is not neccessary, but I use web froms so it wil inherit maintain state so I don’t need retrieve database everytime postback.

here I am also happy to share the css file for style this unorder list to display inline:

MarqueeCssStyle

A tip for fresh guy, put this in the page your use control will stand it.

Now, you just need drag the usercontrol to any page you want it with this css style in top of the header it. You coud see it.

Then We could start create a page to arrow my boss to insert the bread news, I used boostrap format so it save my time to write css. here is the front page look like:

addNews

here is the html code:

htmlCodeAddnews

The form use jQury Validate, the jquery-ui.js, is for my boss click then will pop up the jQuery calender to arrow her to put the expired date. So simple isn’t, I am love JQure very much, save a lot of time. It remind me when I first time write javascript over 10 years ago, for every simply function I need write a lot codes.

Finally I just need write a event could be fired by this button.

storeIntodatabase

Ok, That’s all. Have fun!

Using c# code to force bootstrap modal stay open after page postback

Recently I write a small function into my asp.net application.To enable the driver to input the time the submit the pick up client and drop off the client time.
My boss like the pick up time and drop off time should been populate by just click.so I write a code on the back of page to retrive the time every time the driver click the button.
But the dropoff button driver me to nuts,Because When the dropoff button click I pop out the bootstrap modal.But the problems came out this button need make page postback to retrive the current time and after postback my modal need stay open.
It take me a while to fix out this.
Here is my solution.
first, I need write javascript like this is for to open the modal: #dropoffModal is my hidden modal.

 function openModal() {
$('#dropoffModal').modal({ show: true });
}
 

Second I have the the button is like this(See the button click will fire a event named:”Button_DropOff_Click” behind it):

 button_click_event_fire_javascript

Finally, just write your event on the page behind file:


protected void Button_DropOff_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "Pop", "openModal();", true);
}

here just a solution. by the way, You could use ScriptManager.RegisterStartupScript() this command call another function in your frond page javascript.