Monday, May 15, 2017

A better way to configure Intelli-sense for Javascript in VS2015

Now, I'm moving toward the direction of developing fat client using Javascript (JS) and I need a
better way of enable the intelli-sense support for Javascript in the fat client.

Earlier, I found out that we can include the reference in each JS file by adding the following line.
When the number of JS files that you are developing are increasing, added this reference line might be headache.

   /// <reference path="jquery-1.7.js" />

Here is a better way:

1. Add a "_references.js" file into "js" folder (let says you are keeping all your JS files in a folder call "js" instead of "scripts").

2. In the Quick Launch bar (located at top right corner), key in "Javascript" and look for "IntelliSense -> References"  option. Clicks on it.



3. Choose "Implicit (Web)" option.
4. In the "Add a reference to current group" field, key in "~/js/_references.js".
5. Click Add button.
6. Click OK.



7. Back to the Solution Explorer. Right click on _references.js and you will find two new options.

- Auto-sync- means that VS will add all the JS files automatically.
- Update Javascript References - this is manually sync the JS files.















Monday, May 1, 2017

Asp.net Core/MVC routing

Routing is necessary for controlling the accessible path in the URL.

1) In the Startup.Configure proc, you can add a route to "ContactUs" that looks like this:

            app.UseMvc(route =>
            {
                // adding a new route for http://localhost:57477/contactUs
                route.MapRoute(name: "contact_us",
                            template: "contactUs",
                            defaults: new { controller = "Home", action = "ContactUs" });

                // if the path in the url is blank, call HomeController.
                route.MapRoute(name: "default",
                                template: "{controller=Home}/{action=Index}/{id?}");

            });

And the HomeController looks like below. Simple and straight forward.

    public class HomeController : Controller
    {
        // returns the default page.
        public IActionResult Index()
        {
            return View();
        }

        //returns the contact us page.
        public IActionResult ContactUs()
        {
            return View();
        }
    }

2) You may also add a new route by adding HttpGet attribute to the method and add Route attribute to the class.

    [Route("[controller]")]
    public class ValuesController : Controller
    {
        // GET values
        // http://localhost:57477/values/
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET values/5
        // http://localhost:57477/values/7890
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value=" + id.ToString();
        }

        // GET values/getjson/5
        //http://localhost:57477/values/getjson/1234
        // returns the data in json format.
        [HttpGet("GetJson/{id?}")]
        public IActionResult GetJson(int id)
        {
            var v = new { v = "value=" + id.ToString() };
            return new ObjectResult(v);
        }
    }

Tuesday, April 25, 2017

Compiling asp.net 3.5 manually

I have a ASP.Net web project that was done in VS2010 and now I want to publish it with VS2015. Then, the compiler complained that there are many compilation errors such as CS0117 (method or extension method not found) and CS0246 (type or namespace not found). After hours of research on the web, still cannot find any solution to have VS2015 to publish the ASP.net 3.5 project.

Finally, I decided not to use VS2015 to publish the old project. Instead using command line to publish it even though the steps are a bit lengthy.

Here is the steps:

1. Run VS2015 and open the ASP.net 3.5 web project.
2. Choose Release mode.
3. Choose Rebuild Solution.
4. Upon rebuild done, copy the entire website folder into "d:\manual-compile" folder (or whichever folder that you like).
5. Then, run the following command in command prompt:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -v /website1 -p d:\manual-compile\website1 -u -fixednames d:\manual-compile\website1-compiled


Wait for a while and you will see the precompiled version of ASP.net appeared in "d:\manual-compile\website1-compiled" folder. There you go.


Creating Asp.net Core/MVC from a miminal Asp.net Core project template

Creating a new project from the Web Application template is troublesome in deleting the unwanted files. Let's try to create a minimal Asp.net Core project (not an Empty project).

First thing, you have to create a Web API Asp.net Core project and then follow the following steps to complete the project.

1. Add HomeController class into Controllers folder and the code is shown as follow:

     public class HomeController : Controller
    {
        // returns the default page.
        public IActionResult Index()
        {
            return View();
        }

        //returns the contact us page.
        public IActionResult ContactUs()
        {
            return View();
        }
    }

2. Modify the Configure() in Startup.cs

            app.UseMvc(route =>
            {
                // adding a new route for http://localhost:xxx/contactUs
                route.MapRoute(name: "contact_us",
                            template: "contactUs",
                            defaults: new { controller = "Home", action = "ContactUs" });

                // if the path in the url is blank, call HomeController.
                route.MapRoute(name: "default",
                                template: "{controller=Home}/{action=Index}/{id?}");

            });

3.  Add Index.cshtml and ContactUs.cshtml into Views\Home folder.

In the Index page,  it looks like this:

    @{
        ViewData["Title"] = "Home";
    }

    <h1>MY APP</h1>
    <h2>This is Home page</h2>
    <a href="ContactUs">Jump to Contact Us page</a>

In the ContactUs page, it looks like this:

    @{
        ViewData["Title"] = "Contact Us";
    }

    <h1>MY APP</h1>
    <h2>This is Contact Us page</h2>
    <a href="">Jump to Home page</a>

4. Add _Layout.cshtml into Views\Shared folder and the content looks like this:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />

        <title>@ViewData["Title"] - My App </title>
           
        <environment names="Development">
            <link rel="stylesheet" href="~/css/site.css" />
        </environment>
        <environment names="Staging,Production">
            <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
        </environment>

    </head>
    <body>
   
        <div class="container body-content">
            @RenderBody()

            <hr />
            <footer>
                <p>&copy; 2016 - My App</p>
            </footer>
        </div>

        <environment names="Development">
            <script src="~/lib/jquery/dist/jquery.js"></script>
            <script src="~/js/site.js" asp-append-version="true"></script>
        </environment>
        <environment names="Staging,Production">
            <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                    asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                    asp-fallback-test="window.jQuery">
            </script>
            <script src="~/js/site.min.js" asp-append-version="true"></script>
        </environment>       

        @RenderSection("scripts", required: false)
    </body>
    </html>

5. Add _ViewStart.cshtml into Views folder with the following content. Now, the Asp.net will merge all the views with this "_Layout.cshtml".

    @{
        Layout = "_Layout";
    }

6. Add site.css into wwwroot\css folder with the following contents:

    body {
        font-family:Tahoma;
        font-size: 12pt;
        color: #757575;
        margin: 0;
    }

7. Press F5 to run your website.

8. You might notice that the site.css was not loaded. Let's continue by calling up the NuGet Package Manager. Search the "Microsoft.AspNetCore.StaticFiles" and include it into your project.

9. In Configure() in the Startup.cs file, add the following code before the app.UseMvc()

    app.UseStaticFiles();

10. Press F5 to run your website and the css file will be loaded into the browser.


Tuesday, February 7, 2017

Something about Asp.net Core/MVC

This is something that you should know about Asp.net Core:

1) To create a link that points to the correct virtual directory, you can use the following:

  <a href="~/api/mybook">See my books</a>

OR

   var s = " root is= " + Url.Content("~/");

2) To expose the controller class to the desired URL path, you have to add the "Route" class attribute. In the following case, "MyBook" service is accessible through "http://localhost:1234/api/MyBook" while "Values" is accessible through "http://localhost:1234/values/"

   [Route("api/[controller]")
   public class MyBookController : Controller {..}

    [Route("[controller]")]
    public class ValuesController : Controller {..}


In Startup.cs:

            app.UseMvc(routes =>
            {              
                // set the default route
                routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}"
                    );
            });

3) To publish the static files, you must called out the NuGet and then add the reference to this library "Microsoft.AspNetCore.StaticFiles". After that, you will be able to use the code in Startup.Configure() proc:

   app.UseStaticFiles();

4) To setup the application in IIS, first, you need to add an application pool with "No Managed Code" option. Then, publish a new virtual application that points to the output path. For example,

   src\WebApplication1\bin\Release\PublishOutput

5)

5.1) To return the HTML content, you must return the View() and the Index.cshtml file must be stored in the Views\MyBook folder.

        [HttpGet]
        public ActionResult Index()
        {
            var l = this._my_book.GetList();
            return View(l);
        }

5.2) To return the value as plain content type:

       [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value=" + id.ToString();
        }

5.3) To return the data in JSON format:

        [HttpGet("{id}", Name = "GetTodo")]
        public IActionResult GetById(string id)
        {
            var item = TodoItems.Find(id);
            if (item == null)
            {               
                return NotFound();
            }

            return new ObjectResult(item);
        }

6) Receiving the dynamic JObject param:

          [HttpPost]
          public System.Net.Http.HttpResponseMessage Post([FromBody]Newtonsoft.Json.Linq.JObject value)
          {
             //...
          }

7)

protected bool CheckStatus304(DateTime lastModified)
        {
            //http://weblogs.asp.net/jeff/304-your-images-from-a-database
            if (!String.IsNullOrEmpty(Request.Headers["If-Modified-Since"]))
            {
                CultureInfo provider = CultureInfo.InvariantCulture;
                var lastMod = DateTime.ParseExact(Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
                if (lastMod == lastModified.AddMilliseconds(-lastModified.Millisecond))
                {
                    Response.StatusCode = 304;
                    //Response.StatusDescription = "Not Modified";
                    return true;
                }
            }

            //Response.Cache.SetCacheability(HttpCacheability.Public);
            //Response.Cache.SetLastModified(lastModified);

            //use this instead of the above:
            //string timeString = lastModified.ToUniversalTime().ToString("R");           
            //Response.Headers.Append("Last-Modified", timeString);

            return false;
        }

Thursday, January 19, 2017

Setting up the delete permission in IIS

The following content was copied from this reference:

http://stackoverflow.com/questions/7334216/iis7-permissions-overview-applicationpoolidentity

ApplicationPoolIdentity is actually the best practice to use in IIS7. It is a dynamically created, unprivelaged account. To add file system security for a particular application pool see IIS.net's "Application Pool Identities". The quick version:

If you application pool is named "DefaultAppPool" (just replace this text below if it is named differently)

    Open Windows Explorer
    Select a file or directory.
    Right click the file and select "Properties"
    Select the "Security" tab
    Click the "Edit" and then "Add" button
    Click the "Locations" button and make sure you select the local machine. (Not the Windows domain if the server belongs to one.)
    Enter "IIS AppPool\DefaultAppPool" in the "Enter the object names to select:" text box. (Don't forget to change "DefaultAppPool" here to whatever you named your application pool.)
    Click the "Check Names" button and click "OK".