Oct 30 2012

How to use Notepad++ to fix invalid date formats.

I was just sent some xml files that had dates in this format... 31/09/2012 (dd/mm/yyyy) This date format won't work in some of our systems so I needed to change some of the dates to the format 09/31/2012 (mm/dd/yyyy). Notepad++ to the rescue. I opened up the Find/Replace dialog (CTRL-H) in n++ and set the Search Mode to Regular expression. In the "Find what:" box I put this... (\d{2})/(\d{2})/(\d{4}) In the "Replace with:" box I put this... $2/$1/$3 It worked perfectly!! Seth
Oct 26 2012

Comment by Seth Spearman on How do I call an Index action and conditionally pass it a value in an ASP.NET MVC app

Given my lack of detail (sorry about that...I was rather in a hurry) you pretty much nailed what I was after. Thanks for the answer. Now let me try it out.
Oct 25 2012

How do I call an Index action and conditionally pass it a value in an ASP.NET MVC app

I have an index action on a controller as follows...
public ActionResult Index(string errorMsg = "")
   {
      //do stuff
      ViewBag.ErrorMsg=erorMsg;

      return View();
   }
I have another action that is an http post for Index. When there is something wrong I want to reload the Index page and show the error... I have my view already conditionally showing errorMsg. But I cannot figure out how to call Index and pass in the error string?
Oct 25 2012

How do I call an Index action and conditionally pass it a value in an ASP.NET MVC app

        <p>I have an index action on a controller as follows...</p>
public ActionResult Index(string errorMsg = "")
   {
      //do stuff
      ViewBag.ErrorMsg=erorMsg;

      return View();
   }

I have another action that is an http post for Index.

When there is something wrong I want to reload the Index page and show the error...

I have my view already conditionally showing errorMsg. But I cannot figure out how to call Index and pass in the error string?

Oct 24 2012

How do I get files AND form values from an ASP.NET MVC 4 website?

I have an ASP.NET MVC Website that has a dropdown list that is being created using this in the view...

@Html.DropDownList("Programs")

Programs is populated from a Business Object collection and stuffed into the ViewBag in the index action on the Home Controller...

\\get items...
ViewBag.Programs = items;

The view also has potentially three files I am getting like this in the same view...

<input type="file" name="files" id="txtUploadPlayer" size="40" />  
<input type="file" name="files" id="txtUploadCoaches" size="40" />  
<input type="file" name="files" id="txtUploadVolunteers" size="40" /> 

All of the aforementioned controls are contained in a Form that is created in the view using...

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
     <!--  file and other input types  -->
     <input type="submit" name="btnSubmit" value="Import Data" />
}

My problems is that I cannot find a way to process all of the files AND reference the form fields.

Specifically, I need to know what Program the user selected from the dropdown.

I can process the files using this code with no problem...

[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files)
//public ActionResult Index(FormCollection form)
{

    _tmpFilePath = Server.MapPath("~/App_Data/uploads");

    if (files == null) return RedirectToAction("Index");
    foreach (var file in files)
    {
        if (file != null && file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(_tmpFilePath, fileName);
            if (System.IO.File.Exists(path)) System.IO.File.Delete(path);

            _file = file;

            file.SaveAs(path);

            break;  //just use the first file that was not null.
        }
    }



    //SelectedProgramId = 0;

    //DoImport();

    return RedirectToAction("Index");
}

But I cannot figure how to ALSO get access to the POST form values especially the Programs dropdown selected value (and for the record there is also a checkbox that I cannot read the value from.) Fiddler shows me that the Response has the file references AND the selected program but I cannot figure out how to get them out of the POST using ASP.NET MVC.

I know this question is pretty basic but I am stilling learning the whole web/http thing not just MVC.

EDIT Thanks for your answers. I had the thought that the answer might lie in passing in both the files and the form values into the POST.

So my last question is ... how do I change the HTML.BeginForm block to pass in both the files and form values? Right now I have ...

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
  //do stuff
}

What should that using statement be to get both form values and files as separate parameters of the ActionResult?

EDIT MY EDIT
It seems that I don't have to make any changes...the debugger is showing that both files and form are non-null. Cool! Is that right?

Oct 24 2012

How do I get files AND form values from an ASP.NET MVC 4 website?

        <p>I have an ASP.NET MVC Website that has a dropdown list that is being created using this in the view...   </p>
@Html.DropDownList("Programs")
Programs is populated from a Business Object collection and stuffed into the ViewBag in the index action on the Home Controller...
\\get items...
ViewBag.Programs = items;
The view also has potentially three files I am getting like this in the same view...
<input type="file" name="files" id="txtUploadPlayer" size="40" />  
<input type="file" name="files" id="txtUploadCoaches" size="40" />  
<input type="file" name="files" id="txtUploadVolunteers" size="40" /> 
All of the aforementioned controls are contained in a Form that is created in the view using...
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
     <!--  file and other input types  -->
     <input type="submit" name="btnSubmit" value="Import Data" />
}
My problems is that I cannot find a way to process all of the files AND reference the form fields. Specifically, I need to know what Program the user selected from the dropdown. I can process the files using this code with no problem...
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files)
//public ActionResult Index(FormCollection form)
{

    _tmpFilePath = Server.MapPath("~/App_Data/uploads");

    if (files == null) return RedirectToAction("Index");
    foreach (var file in files)
    {
        if (file != null && file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(_tmpFilePath, fileName);
            if (System.IO.File.Exists(path)) System.IO.File.Delete(path);

            _file = file;

            file.SaveAs(path);

            break;  //just use the first file that was not null.
        }
    }



    //SelectedProgramId = 0;

    //DoImport();

    return RedirectToAction("Index");
}
But I cannot figure how to ALSO get access to the POST form values especially the Programs dropdown selected value (and for the record there is also a checkbox that I cannot read the value from.) Fiddler shows me that the Response has the file references AND the selected program but I cannot figure out how to get them out of the POST using ASP.NET MVC. I know this question is pretty basic but I am stilling learning the whole web/http thing not just MVC. EDIT Thanks for your answers. I had the thought that the answer might lie in passing in both the files and the form values into the POST. So my last question is ... how do I change the HTML.BeginForm block to pass in both the files and form values? Right now I have ...
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
  //do stuff
}
What should that using statement be to get both form values and files as separate parameters of the ActionResult? EDIT MY EDIT
It seems that I don't have to make any changes...the debugger is showing that both files and form are non-null. Cool! Is that right?
Oct 18 2012

Comment by Seth Spearman on is it bad form to have your continuous integration system commit to a repository

Chris. This is a great idea and I will, in fact, be doing something like it. (Although I will be using MSBuild to accomplish it rather than powershell).
Oct 17 2012

MSBuild Tutorial # 4

Last time we talked about controlling the order that Targets execute.

There is one other way I want to mention that is pretty cool.  Try this…

<?xml version="1.0" encoding="utf-8"?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Target1" DependsOnTargets="Target2">

        <Message Text="Target 1, Message1" />

        <Message Text="Target 1, Message2" />

    </Target>

    <Target Name="Target2" DependsOnTargets="Target3">

        <Message Text="Target 2, Message1" />

        <Message Text="Target 2, Message2" />

    </Target>  

    <Target Name="Target3">

        <Message Text="Target 3, Message1" />

        <Message Text="Target 3, Message2" />

    </Target>

</Project>

 

Notice that the Target node supports a DependsOnTarget attribute.  Even though Target 1  was supposed to execute first, when you run it you get this output…

Microsoft (R) Build Engine version 4.0.30319.17929

[Microsoft .NET Framework, version 4.0.30319.17929]

Copyright (C) Microsoft Corporation. All rights reserved.

 

Build started 10/17/2012 4:45:26 PM.

Project "C:\Users\sspearman\Documents\MSBuild\test.build" on node 1 (default targets).

Target3:

  Target 3, Message1

  Target 3, Message2

Target2:

  Target 2, Message1

  Target 2, Message2

Target1:

  Target 1, Message1

  Target 1, Message2

Done Building Project "C:\Users\sspearman.UPWARD\Documents\MSBuild\test.build" (default targets).

 

Build succeeded.

    0 Warning(s)

    0 Error(s)

 

Time Elapsed 00:00:00.03

 

The DependOnTarget attribute ensured that Target 2 ran first.  But Target 2 needed Target 3 to run first.  So the execution order was Target 3, Target 2, and then Target 1. 

Pretty cool.

Oct 15 2012

MSBuild Tutorial # 3

Last time we saw that an MSBuild file must have at least one Target node. 

But it can have as many Targets as you want…

<?xml version="1.0" encoding="utf-8"?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Target1">

        <Message Text="Target 1, Message1" />

        <Message Text="Target 1, Message2" />

    </Target>

    <Target Name="Target2">

        <Message Text="Target 2, Message1" />

        <Message Text="Target 2, Message2" />

    </Target>  

    <Target Name="Target3">

        <Message Text="Target 3, Message1" />

        <Message Text="Target 3, Message2" />

    </Target>

</Project>

 

Paste the above code snippet into Notepad++ and run it.  (If you don’t know how to run an MSBuild file from Notepad++ maybe you missed my 2nd Post.)

Here is the output…

 

Build started 10/15/2012 2:01:06 PM.

Project "C:\Users\sspearman.UPWARD\Documents\MSBuild\test.build" on node 1 (default targets).

Target1:

  Target 1, Message1

  Target 1, Message2

Done Building Project "C:\Users\sspearman.UPWARD\Documents\MSBuild\test.build" (default targets).

 

Build succeeded.

    0 Warning(s)

    0 Error(s)

 

Time Elapsed 00:00:00.05

 

Notice that MSBuild only ran the first Target.  It ran it because it was first. 

There are several other ways to configure which target gets run.

1.  You can change add a DefaultTargets as a project attribute.   Change the Project tag as follows…

 

<Project DefaultTargets="Target2" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

 

Now run it.  Notice that Target 2 is what gets run. 

 

You can also put multiple targets into that attribute…now change your Project node to be like this…

<Project DefaultTargets="Target2;Target3" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

Now when you run it both Target2 and Target3 are run. 

2.  One other way to control which Target runs is from the command line. 

In Notepad++ hit F6 and edit the Command to be the following…

"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" "$(FULL_CURRENT_PATH)"  /t:Target3

 

Test it and you will see that Target3 is run because of the /t switch.  And just as with the DefaultProjects, you can use this argument with a semi-colon delimited list of Targets.
Oct 15 2012

MSBuild Tutorial # 2

Two things today…

Two things today…

First…so that we can have fun with MSBuild…here’s how you would configure Notepad++ to run MSBuild files…

1.        Hit F6 to open the Execute dialog of Notepad++

2.       Paste in the following into the Command(s) box…
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" $(FULL_CURRENT_PATH)"
You need to verify your path to MSBuild but it should work for most of you unless you have a 32-bit machine.

3.       Click the Save… button and give the command a name.  I called it Run MSBuild.

4.       Click the Cancel dialog.

5.       Any time you want to run a build script just hit F6 and select Run MSBuild from the drop down.

Now on to MSBuild. 

Here is the anatomy of an MSBuild file…

IF you want to try it here is the raw text…

<?xml version="1.0" encoding="utf-8"?>

<Project xmlns="http://schemas.microsoft.com/developers/msbuild/2003" />

</ Project>

Try to run it.  It won’t work.  All MSBuild files have one required target…it must have a … well a Target …

Add this into the project node…

                <Target Name="test">

                </Target>

If you build it now it will build.  Of course, it doesn’t do anything.

What is a Target.  A target is a container for a series of Tasks.  There are a lot of tasks that are built into MSBuild.  Add this to the target node…

<Message Text="Hello Upward Developers" />

The Message task just emits a message to the host.  Your file should look like this and it should work.

<?xml version="1.0" encoding="utf-8"?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

                <Target Name="test">

                                <Message Text="Hello Upward Developers" />

                </Target>

</Project>

You can add as many Tasks to a target as you would like.