ASP.NET MVC: Show Busy Indicator on Form Submit using JQuery and Ajax

Posted on December 22 2013 05:57 PM by John Atten in CodeProject, C#, ASP.NET MVC, ASP.Net   ||   Comments (6)

ajaxAs we all know, users are impatient. We also know that if we don't tell them our application is "doing something" they tend to do silly things like click the mouse repeatedly, seeking some sign that the requested action is indeed being performed.

For this reason, it is a good idea to throw up some sort of "busy" indicator when a user-initiated action may invoke a long-running process which requires them to wait.

In this article we are going to demonstrate a very basic way to achieve this which will be effective in most cases.

If you are new to ASP.NET MVC, you may want to check out my previous posts on Routing Basics and Route Customization as well. While not critical to understanding what we discuss here, some background on the basics of MVC routing will certainly help in understanding what's going on in places.

Image by Martin Abegglen | Some Rights Reserved

The fully-functioning source code for the example used in this article is available from my Github Repo. You will need to use Nuget Package Restore to pull down all the package goodness so that the project will run. If you are unsure what that means, see Keep Nuget Packages Out of Source Control with Nuget Package Manager Restore.

What the Hell is Ajax?

Ajax is an acronym for Asynchronous JavaScript and XML. Ajax represents a broad range of technologies used to facilitate client-server communication without interfering with the current state of the page.

In the main, we most often use the term when we speak of making an Ajax Request to the server, usually in the context of posting or retrieving data, and updating only a portion of the page, as opposed to completely refreshing a page simply because a small sub-area needs to be updated.

Upon the introduction of the term circa 2005, XML represented what many believed would be the primary data interchange format for this type of client-server transaction. Since then, JavaScript Object Notation (JSON) has become more and more of a standard. While XML is not gone, you are as likely to send and receive JSON in the course of an Ajax request as you are XML.

At present, we often find Ajax used in conjunction with JQuery (more properly, one often uses JQuery to make an Ajax request) when we need to retain the current state of our page while a request is made to the server and then update the portion of the page affected by the information returned from the request.

Adding a Busy indicator to a Page with JQuery and Ajax

The common way to display a busy indicator on a page while we wait for a long-running request to return from the server is to throw up an animated Gif, to let users know something is in fact happening. Equally as often, we need to then remove or hide the animation when the process completes, and refresh the portion of the page affected by our new data.

There really is no good way to do this from the server side in an MVC application – we need to use Ajax. We do this with JavaScript. in this case, we are going to use the popular JQuery library, because it is ubiquitous, it ships with and in integrated into the core MVC project.

Let's take a look at a quick example.

Basic Example – The View

First we will look at a basic view. We've kept it simple here – we will display a couple of data entry fields, and a button to submit the data entered by the user. The essential cshtml code for this is as follows:

A Basic View:
@model JqueryBusyExample.Models.DemoViewModel
@{
    ViewBag.Title = "Home Page";
}
  
<h3>Enter Your Name and Submit:</h3>
  
@using (Html.BeginForm("LongRunningDemoProcess", 
    "Home", FormMethod.Post, 
    new { encType = "multipart/form-data", id="myform", name = "myform" }))
{
    <div class="form-group">
        @Html.LabelFor(model => model.FirstName, 
            new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.LastName, 
            new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
    </div>
    
    <input type="submit" name="operation" id="process" value="process" />
}

 

As we can see, there is nothing unusual here. We use standard Razor syntax to create a form with a couple data entry fields for First and Last names, and a submit button. In the opening of the using statement, The form is wired to a method named LongRunningDemoProcess on our HomeController.

In the form declaration, the syntax is:

Html.BeginForm(<actionName>, <controllerName>, <Http Method Type>, <Html Attributes>)

 

The above basically determines what happens when the form is submitted, and specifies a specific method, and a specific controller as a target for the Http request. It also defines the request method type (GET, POST, PUT, DELETE).

In our example case, we want to send our model data in the POST body. On our controller, the LongRunningDemoProcess method will need to be decorated with the [HttpPost] attribute, and accept the POST body payload as an argument.

Now let's take a look at our Home controller.

Basic Example – The Controller

For our purpose here, I have simply added a method named LongRunningDemoProcess to the stock ASP.NET MVC Home Controller which is part of the default MVC 5 project template:

A Basic Controller with Long-Running Process:
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
    [HttpPost]
    public JsonResult LongRunningDemoProcess(DemoViewModel model)
    {
        Thread.Sleep(1000);
        return Json(model, "json");
    }
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";
        return View();
    }
    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";
        return View();
    }
}

 

In the above, we use Thread.Sleep to mimic a long-running process on the server. You will need to add a reference to the System.Threading namespace in the using statement imports at the top of your file.

As we can see, LongRunningDemoProcess is the target of for our HTTP Post request from the Index view when form submission occurs. We want to use the Json data returned from the request to update our view, and let the user know their submit succeeded.

At the moment, though, things are not all they could be. We can load up our page, type some data into the form, and hit submit. What happens next, though, is that our page freezes up while the long-running process runs, and then our Json data is returned to a new tab in our browser (Chrome) or we are prompted to Save or Open (IE). 

What we WANT to happen is to display a busy indicator, and then somehow indicate to the user that their submission was successful (or something!).

Get a Busy Indicator GIF

One of the more useful little sites I've found recently is AjaxLoad.Info, which presents a handy library of various customizable animated GIFs. You can specify some basic parameters (Size, Type, Foreground Color, etc.) and then download, ready to use.

Go get one, add it to your project in a location which makes sense (I am using ASP.NET MVC 5 project in VS 2013, so I placed mine at the root level of the Content folder).

Next, let's modify our view, and add a div we can show and hide as needed, and which contains our gif:

The View, with Animated GIF and Placeholder for Submission Result

In the highlighted area below, we have added a div element to contain our Gif. While we're at it, we also added another div, to hold the result when our long-running process returns:

Modified View with Animated Gif and Placeholder Div:
@model JqueryBusyExample.Models.DemoViewModel
@{
    ViewBag.Title = "Home Page";
}
  
<h3>Enter Your Name and Submit:</h3>
  
@using (Html.BeginForm("LongRunningDemoProcess", "Home", FormMethod.Post, 
    new { encType = "multipart/form-data", id="myform", name = "myform" }))
{
    <div class="form-group">
        @Html.LabelFor(model => model.FirstName, 
            new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.LastName, 
            new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
    </div>
    
    <input type="submit" name="operation" id="process" value="process" />
}
   
// We want to show this while the server process is running:
<div id="divProcessing">
    <p>Processing, please wait . . . <img src="../../Content/ajax-loader.gif"></p>
</div>
  
// We want to display the result from our submission in here:
<div id="divResult">
</div>

 

Now, in order to tie all this together, we need to add an Ajax request.

Adding the Ajax Request

The easiest way to achieve what we want is to use JavaScript on the client to show our animated gif, and then submit our data to the server. We also want to be able to respond when the Json is returned by the server by updating our page, without refreshing the whole thing.

For our example, I am going to add the JavaScript right on the view. This may or may not make sense in a production application, but we will do it here for simplicity.

I've added the JQuery code below our now-familiar view:

The View, with JQuery Added:
@model JqueryBusyExample.Models.DemoViewModel
@{
    ViewBag.Title = "Home Page";
}
  
<h3>Enter Your Name and Submit:</h3>
  
@using (Html.BeginForm("LongRunningDemoProcess", "Home", FormMethod.Post, 
    new { encType = "multipart/form-data", id="myform", name = "myform" }))
{
    <div class="form-group">
        @Html.LabelFor(model => model.FirstName, 
            new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.LastName, 
            new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
    </div>
    
    <input type="submit" name="operation" id="process" value="process" />
}
    
// We want to show this while the server process is running:
<div id="divProcessing">
    <p>Processing, please wait . . . <img src="../../Content/ajax-loader.gif"></p>
</div>
    
// We want to display the result from our submission in here:
<div id="divResult">
  
</div>
  
@section Scripts {
  @Scripts.Render("~/bundles/jqueryval")
  
  <script type="text/javascript">
  
    $(document).ready(function () {
  
      // Hide the "busy" Gif at load:
      $("#divProcessing").hide();
  
      // Attach click handler to the submit button:
      $('#process').click(function () {
          $('#myform').submit();
      });
  
      // Handle the form submit event, and make the Ajax request:
      $("#myform").on("submit", function (event) {
        event.preventDefault();
  
        // Show the "busy" Gif:
        $("#divProcessing").show();
        var url = $(this).attr("action");
        var formData = $(this).serialize();
        $.ajax({
          url: url,
          type: "POST",
          data: formData,
          dataType: "json",
          success: function (resp) {
  
            // Hide the "busy" gif:
            $("#divProcessing").hide();
  
            // Do something useful with the data:
            $("<h3>" + resp.FirstName + " " + resp.LastName + "</h3>").appendTo("#divResult");
          }
        })
      });
    });
  </script>
}

 

In the above, we start with the standard JQuery document.ready function, and hide the div containing our animated Gif.

We then attach the form submit event to the click event of the submit button we defined in our View (Isn't it already attached, you ask? We'll get to why we do this in a moment), and then we handle the form submit event.

Handling the Form Submit Event with an Ajax Request

This is where things get interesting. There are a few things occurring inside this function, in a rather specific order. Let's walk through it. 

First, we want to prevent the default action using (wait for it . . .) the JQuery preventDefault() method when the form submit event occurs, otherwise, form submission will proceed automatically, as before, and any code we place in our handler will not work properly.

Next, we show our animated Gif. Once shown, it will do its thing, giving the user the impression that something  useful is happening.

Finally, we collect what we need from our form in order to submit our Ajax request. First, we grab the Url and stow it in a variable by accessing the form's action attribute using JQuery. The action attribute essentially pulls a Url which matches the route we specified in the form declaration (remember?  ActionMethod, ControllerName, HttpMethodType, etc?).

Next, we serialize the form data ( in this case, our model data) into another variable, again using JQuery.

Once we have collected these things, we can set up our Ajax request by making the property assignments shown. Note that we need to specify the data type as Json, so that when the request returns, JQuery will recognize it as valid Json. Then, we come to the all-important success property.

We have assigned a function here, which will execute when our long-running process returns a response. The resp argument will contain the Json returned from our controller method. In this very simple case, it is merely the data we already submitted. However, it could just as easily be the result of persisting some data in a database on the server. In any case, we know that when this function is called, our remote, long-running task has completed.

That being the case, the first thing we want to do is hide our animated Gif. Next, we push the returned data into the div we set up as a placeholder (after doing a little formatting, of course).

Fairly Simple, but Not Always Obvious

And there you have it. The example we have examined is pretty basic, but gives a good look at how to both display a busy indicator, and how to make Ajax requests from your ASP.NET MVC page.

There is a lot more to learn about Ajax, and it provides a foundation for much of the interactivity found in today's modern websites. I welcome comments and constructive criticism in the comments section below (especially if I got something wrong here . . .)!

You can clone or download the example project from my Github Repo. Note that you will need to use Nuget Package Restore to pull in all the package dependencies. If you don't know what that means, see Keep Nuget Packages Out of Source Control with Nuget Package Manager Restore.

Additional Resources and Items of Interest

 

Posted on December 22 2013 05:57 PM by John Atten     

Comments (6)

C# SMTP Configuration for Outlook.Com SMTP Host

Posted on December 20 2013 09:18 PM by jatten in C#, CodeProject   ||   Comments (0)

3306827131_eff5401a63If you want to send Email programmatically using your Outlook.com or Gmail account as the SMTP host, there are a few things to pay attention to in order to get it all working.

Using the basic System.Net.Mail library, sending email is generally fairly straightforward. However, if you want to send using your Outlook.Com or Gmail account as the SMTP host, you will most likely need to take a few extra steps, if you have two-stage authorization enabled (and you DO have two-stage auth enabled, RIGHT??!!).

Image by JASE Group LLC | Some Rights Reserved

 

SMTP Configuration Example for Outlook.Com SMTP Host

Here is a basic class with SMPT configuration for sending mail using Outlook.Com SMTP:

Basic Mail Configuration Settings for Outlook.Com SMTP:
using System;
  
// You will need to add a reference to this library:
using System.Net.Mail;
  
namespace SmtpMailConnections
{
    public class OutlookDotComMail
    {
        string _sender = "";
        string _password = "";
        public OutlookDotComMail(string sender, string password)
        {
            _sender = sender;
            _password = password;
        }
  
  
        public void SendMail(string recipient, string subject, string message)
        {
            SmtpClient client = new SmtpClient("smtp-mail.outlook.com");
  
            client.Port = 587;
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.UseDefaultCredentials = false;
            System.Net.NetworkCredential credentials = 
                new System.Net.NetworkCredential(_sender, _password);
            client.EnableSsl = true;
            client.Credentials = credentials;
  
            try
            {
                var mail = new MailMessage(_sender.Trim(), recipient.Trim());
                mail.Subject = subject;
                mail.Body = message;
                client.Send(mail);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw ex;
            }
        }
    }
}

 

As you can see, we have kept this pretty minimal for the purpose of clarity. We initialize our simple class with a user name (in this case, out Outlook.Com email address) and a password.

Example Usage

We can call into this class to send mail like this (this example is a simple console application):

Sending Mail Using the Mail Sender Class
class Program
{
    static void Main(string[] args)
    {
        string mailUser = "YourAccount@outlook.com";
        string mailUserPwd = "YourPassword";
  
        var sender = new OutlookDotComMail(mailUser, mailUserPwd);
        sender.SendMail("recipient@example.com", "Test Mail", "Hello!");
    }
}

 

If you run the code above, using your own Outlook.Com Email address and password, all should work fine.

Unless you have enabled two-stage authorization on your Outlook.Com account. If you have, you will need to create an application specific password, or the code above will throw an exception when your credentials are refused by the Outlook.Com SMTP server.

Create an App-Specific Password if You Have 2-Stage Auth Enabled

To create an App-Specific Password, log in to your Outlook.com account, and go to Account Settings –> Security Info –> App Passwords:

outlook-com-app-passwords

Click on the Create a new app password link, and voila – you now have a new password for use within your application:

create-new-app-password

Use this as the password in your code, and all should be well:

Use the App Password Instead of Your Outlook.Com Account Password:
class Program
{
    static void Main(string[] args)
    {
        string mailUser = "YourAccount@outlook.com";
        string mailUserPwd = "bnppnnenfmpiixty";
  
        var sender = new OutlookDotComMail(mailUser, mailUserPwd);
        sender.SendMail("recipient@example.com", "Test Mail", "Hello!");
    }
}

 

You can find the Code Samples above at my Github repo.

Additional Resources and Items of Interest

 

Posted on December 20 2013 09:18 PM by jatten     

Comments (0)

Visual Studio–Painlessly Renaming Your Project and Solution Directories

Posted on December 15 2013 12:05 PM by jatten in CodeProject, Tools   ||   Comments (0)

Visual_Studio_2013_LogoWorking in Visual Studio, we often find ourselves needing to rename our project and/or solution and the directories they live in. In particular, when we clone a project from Github, what we end up with the a complete, workable solution, but named other than what we would like.

As an example, I recently posted articles on Creating a Stripped-down ASP.NET Web Api Solution,as well as an article on Extending Identity Accounts and   Implementing Role-Based Security in ASP.NET MVC 5. In both cases, I linked to example projects on my Github repo which not only serve as examples for the article content, but in fact present the workable start for your own solution.

Except, they are named "YadaYadaYadaExample."

NOTE: I go into what may seem like excruciating detail in this article. Experienced users may wonder what the fuss is about, that it should take this much space to explain how this works. This is targeted at those newer to Visual Studio who may be running into this for the first time.

The history of people struggling with project and solution renaming in Visual Studio is long. While experienced users generally understand how to do this (or how to figure it out), the first time you run into it, it can be confusing. Especially since VS allows you to rename your project and solution even from within VS, but the directory names remain unchanged.

Let's take a quick walkthrough. We will see where the problem starts, and how to quickly address it and move on with building out our project. Our example will start off by cloning a project from Github, but the manner in which we modify the project, solution, and directory names after that is applicable to any project. If you are a new user and not familiar with Git or Github, just download the zip file from the Github page instead, and extract into the directory of choice on your local machine.

We'll start by simply cloning the example project on Github that I used in the article on Extending Identity Accounts. Navigate to the directory where you want to create your new project, and clone:

Clone the Example Project from the Github Repo:
$ git clone https://github.com/xivSolutions/AspNetRoleBasedSecurityExample

 

You should now find the cloned project in target directory:

The Visual Studio Solution Cloned into the Target Folder:

explorer-view-of-cloned-project

Open and build the project in VS

Let's open this project in Visual Studio.

NOTE ABOUT THE EXAMPLE PROJECT: The first time you open this specific project after cloning, you will see a host of errors in the VS Error List window. This is because in order to host the source code for this project on Github, I enabled Nuget Package Restore for the project, so that I didn't need to also host all the Nuget Packages attendant to an MVC solution. Using Nuget Package Restore, the required packages are downloaded and updated on build. For more info see Keep Nuget Packages Out of Source Control with Nuget Package Manager Restore.

Changing the Project and Solution Names in Visual Studio

Just within VS, there are a number of items we probably want to change in order to name the cloned project appropriately for our needs. Let's say we have cloned this solution from Github with the intention of using it as the starting point for our own company website.  When we first open the project, we see that everything is names consistently with the name of the Github project, and with the folder we found in our local directory after cloning:

The Solution and Project Structure in Visual Studio After Cloning:

cloned-solution-in-vs-solution-explorer

In Solution Explorer, we can easily rename the project and the Solution simply by clicking on the current name and editing. This part, most can figure out on their own:

Renaming the Project and Solution in Solution Explorer:

renaming-project-in-solution-explorer

You can do the same thing for the Solution Name.

This is only the beginning, though. Now, we most likely want to rename the assembly and the default namespace. To do this, we go open the project Properties designer and type the new project name into the Assembly name field, and also into the Default namespace field (unless we want our default namespace to be other than our project name, in which case type whatever name you want to be your default namespace):

Changing the Assembly and Default Namespace in Project Properties Designer:

rename-assembly-and-namespace

Update the Namespacing Used on the Project Files

Ok, so now you have changed the default project namespace. However, all of the files included in the project when you cloned it still contain the old namespace, For example, if we open the AccountContoller file, we see the following:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using AspNetRoleBasedSecurity.Models;
namespace AspNetRoleBasedSecurity.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        public AccountController()
            : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
        {
        }
  
  
        public AccountController(UserManager<ApplicationUser> userManager)
        {
            UserManager = userManager;
        }
  
        // . . . MORE CODE (ommitted for brevity)
    }
}

 

See the namespace AspNetRoleBasedSecurity.Controllers declaration there at the top? More than likely, we don't want that as our default namespace for our new project. So we should do a global replacement on our solution and replace all instances of the AspNetRoleBasedSecurity with MyNewProjectName.

IMPORTANT NOTE: Be careful here. This may not always be the best approach if there is any chance that the old namespace also matches other items in the project you do not wish to rename. Sometimes you may need to handle this on a file-by-file basis. Just be aware the global find/replace across the entire solution requires some forethought!

To do this, select the existing namespace, then hit Ctrl-h to open the find/replace window. Type the new namespace into the "replace" field, and make sure to select "Entire Solution" in the drop-down. Then click the "replace all" icon:

Replace Existing Namespace in Entire Solution:

replace-namespace-entire-solution

Up to this point, everything in our project still works fine (or, it should, anyway).  The project should build and run properly. However, there is still the issue of the project and solution directory folders, and this is where the trouble usually starts.

Changing the Name of the Project Directories in Windows Explorer

Usually, we would like the directory name for our solution to reflect the overall solution or project. In our current example, we probably don't want our newly renamed project and solution to live in a folder named AspNetRoleBasedSecurity (or whatever the original name of the solution in question is).

To change the directory names, close visual studio. Also, if you used Git to clone the project, close the terminal (or whatever open applications might be referencing the project).

We have two directories here that need new names – the outer solution directory, and the project directory itself. Rename each to match your new solution and project names respectively:

Solution Folder Structure with Folders Which Need to be Renamed:

solution-folders-in-windows-explorer

Once we have changed the Solution and Project folder names, our directory structure looks like this:

Directory Structure After Renaming Project and Solution Folders

solution-folders-after-rename-in-windows-explorer

Rename the Solution File

If we open the solution folder, we find that the actual VS solution file is still named for our old project (the solution file is the one with the .sln extension):

The VS Solution File Before Renaming:

rename-solution-file

Rename this to also match our newly chosen solution name.

Having done that, let's open our solution again, and see what happens.

Uh oh:

Project Load Fails After Renaming:

project-load-failed

Everything we have done up to this point has been rather rudimentary, hardly worth the length of the post. I have included the previous steps for those who are brand-new to Visual Studio, but in reality most of us know how to rename projects, namespaces, and directories.

What is not obvious is that restoring our renamed project to full-functionality involves editing the solution file, to point things back where they belong.

Editing the Solution File

This is where most people get hung up on the solution renaming process. The next step is actually fairly trivial in execution, it's just not obvious to the uninitiated.

Navigate into the solution directory and open the solution file using your preferred text editor (I use Sublime Text or Notepad++, but any standard text editor will do). Right-Click on the solution file and select "Open with" your text editor. You should see something resembling this (note – if the solution contains multiple projects, you will see each of them listed instead of just one as below):

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyNewProjectName", "AspNetRoleBasedSecurity\MyNewProjectName.csproj", "{D7ADA016-6E82-4F70-B6CF-B687A3B6F6EA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{6DCF7BBA-8C8E-4E64-A6F0-3CB2A778DA69}"
	ProjectSection(SolutionItems) = preProject
		.nuget\NuGet.Config = .nuget\NuGet.Config
		.nuget\NuGet.exe = .nuget\NuGet.exe
		.nuget\NuGet.targets = .nuget\NuGet.targets
	EndProjectSection
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{D7ADA016-6E82-4F70-B6CF-B687A3B6F6EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{D7ADA016-6E82-4F70-B6CF-B687A3B6F6EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{D7ADA016-6E82-4F70-B6CF-B687A3B6F6EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{D7ADA016-6E82-4F70-B6CF-B687A3B6F6EA}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal

 

Note the highlighted line. See how it is still looking for the newly-named project file in the OLD directory?

Change this:

Change the Path to the Project file(s) in the Solution File:
"AspNetRoleBasedSecurity\MyNewProjectName.csproj"

 

to this:

Modified Path to the Project file(s) in the Solution File:
"MyNewProjectName\MyNewProjectName.csproj"

 

If you are working with a solution which contains multiple projects, you will need to repeat the previous modification for each project within the solution (or do find . . . replace all)

Now, save the modified solution file, and try opening your project once again. If all has gone well, everything should now be fine, and work as expected.

Additional Resources and Items of Interest

 

Posted on December 15 2013 12:05 PM by jatten     

Comments (0)

About the author

My name is John Atten, and my "handle" on many of my online accounts is xivSolutions. I am Fascinated by all things technology and software development. I work mostly with C#, JavaScript/Node, and databases of many flavors. Actively learning always. I dig web development. I am always looking for new information, and value your feedback (especially where I got something wrong!). You can email me at:

jatten at typecastexception dot com

Web Hosting by