Joseph Michael Pesch
VP Programming

Piranha CMS Uses TinyMCE and Removes Certain Tags Like FontAwesome <i> Tags

by 9. May 2015 10:27

I was using Piranha CMS with the out-of-the-box implementation in conjunction with an MVC Bootstrap HTML/CSS template.  This was working great with the exception of certain tags (specifically in my case the <i> tag used in conjunction with FontAwesome) would get removed.  This is because by default the TinyMCE html editor that Piranha CMS uses will only retain the configured allowable tags.  I fixed this issue by adding my <i> tag to the configuration of allowable tags using the "extended_valid_elements" configuration setting of TinyMCE.  This setting adds additional allowed tags/attributes in the TinyMCE editor in addition to the default allowed tags/attributes. 

In my case the specific setting looked like this: extended_valid_elements : 'i[*]'

In order to implement this with Piranha CMS I needed to add a new file "TinyMCE.cshtml" to the folder "Areas\Manager\Views\Shared\Partial" in my MVC project (side note, that full folder path did not already exist so I added the necessary sub-folders).  Here is the full content of the TinyMCE.cshtml file:

<script type="text/javascript" src="~/res.ashx/areas/manager/content/js/ext/tiny_mce/tinymce.min.js"></script>
<script type="text/javascript">
  tinymce.init({
    extended_valid_elements : 'i[*]',
    mode: 'specific_textareas',
    editor_selector: "editor",
    convert_urls: false,
    plugins: [
        "autoresize autolink code hr paste piranhaimage link"
    ],
    width: "100%",
    height: "340",
    autoresize_min_height: 340,
    @if (File.Exists(Server.MapPath("~/areas/manager/content/css/editor.css"))) {
        <text>content_css: "@Url.Content("~/areas/manager/content/css/editor.css")",</text>
        }
    toolbar: "bold italic underline | bullist numlist hr | formatselect removeformat | cut copy paste | link piranhaimage | code",
  });
</script>

Tags:

ASP.Net | MVC

TSQL Function to Return Number of Weekdays Between Two Dates (Excludes Weekend Days)

by 4. May 2015 10:41

TSQL function to return a number of weekdays between two dates (i.e. excludes weekend days):

create function WeekdayDateDiff
(
 @BegDt as DATETIME,
 @EndDt as DATETIME
) returns int as begin
  return (datediff(dd, @BegDt, @EndDt) + 1)
  -(datediff(wk, @BegDt, @EndDt) * 2)
  -(case when datepart(dw, @BegDt) = 1 then 1 else 0 end)
  -(case when datepart(dw, @EndDt) = 7 then 1 else 0 end)
end

Tags:

SQL Server

SharePoint PowerPivot Data Refresh - Can't Open the Workbook Because it Uses Unsupported Features

by 14. April 2015 07:44

Trying to run the SharePoint PowerPivot Unattended Data Refresh errors with: "We're sorry. We can't open the workbook in the browser because it uses these unsupported features: • Comments, Shapes, or other objects"

Use this tool from: http://blogs.msdn.com/b/cumgranosalis/archive/2007/06/29/excel-services-compatibility-checker-download-page.aspx

to fix the workbook.

Tags:

Sharepoint

IIS Application Pool (AppPool) Using Default Identity of "ApplicationPoolIdentity"

by 10. March 2015 04:46

To assign Windows security (for example local folder permissions) to the ApplicationPoolIdentity user there is a user for each website like this: IIS APPPOOL\website

 


Tags:

Installing and Configuring Web Deploy on IIS 8.0 or Later

by 10. March 2015 04:37

 

1) Install the "Web Platform Installer" (version 4.6 at time of this post).

2) Use the "Web Platform Installer"to install the "Recommended Server Configuration for Web Hosting Providers" (search for "recommended" should locate this item).

 

See full blog post here: http://www.iis.net/learn/install/installing-publishing-technologies/installing-and-configuring-web-deploy-on-iis-80-or-later

 


Tags:

Microsoft SQL Server TSQL Script to View All User Role Assignments

by 10. March 2015 04:01

 

/* The following will list all user role assignments in current database */


WITH RoleMembers (member_principal_id, role_principal_id)
AS
(
  SELECT
   rm1.member_principal_id,
   rm1.role_principal_id
  FROM sys.database_role_members rm1 (NOLOCK)
   UNION ALL
  SELECT
   d.member_principal_id,
   rm.role_principal_id
  FROM sys.database_role_members rm (NOLOCK)
   INNER JOIN RoleMembers AS d
   ON rm.member_principal_id = d.role_principal_id
)
select distinct rp.name as database_role, mp.name as database_user
from RoleMembers drm
  join sys.database_principals rp on (drm.role_principal_id = rp.principal_id)
  join sys.database_principals mp on (drm.member_principal_id = mp.principal_id)
order by rp.name

/* The following will list all user role assignments in all databases except master and tempdb */

create table #tmp(DatabaseName varchar(150), DatabaseRole varchar(150), DatabaseUser varchar(150))

declare @command varchar(max)

select @command = '
if ''?'' not in(''master'', ''tempdb'')
begin
    print ''?''
    use [?]
  ;
  WITH RoleMembers (member_principal_id, role_principal_id)
  AS
  (
    SELECT
     rm1.member_principal_id,
     rm1.role_principal_id
    FROM sys.database_role_members rm1 (NOLOCK)
     UNION ALL
    SELECT
     d.member_principal_id,
     rm.role_principal_id
    FROM sys.database_role_members rm (NOLOCK)
     INNER JOIN RoleMembers AS d
     ON rm.member_principal_id = d.role_principal_id
  )
  insert into #tmp select distinct ''?'', rp.name, mp.name
  from RoleMembers drm
    join sys.database_principals rp on (drm.role_principal_id = rp.principal_id)
    join sys.database_principals mp on (drm.member_principal_id = mp.principal_id)
  order by rp.name

end
'
exec sp_msforeachdb @command1 = @command

select * from #tmp

drop table #tmp

Tags:

SQL Server

ASP.Net Visual Studio General XML Configuration File Transformation

by 3. March 2015 05:19

Slow Cheetah is a Visual Studio addin (VSIX Installer available here: https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5) that enables build specific transformations for any XML configuration file (similar to the out of the box Visual Studio support for Web.config transformation files).  Here is a blog from Scott Hanselman talking about the tool: http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx

 

Tags:

Piranha CMS for MVC Installation

by 22. February 2015 05:44

When I first installed Prianha CMS for MVC I was having issues running it.  I started over and installed via NuGet package manager console in the following order:

PM > Install-Package PiranhaCMS.Core

PM > Install-Package PiranhaCMS.WebPages

PM > Install-Package PiranhaCMS.MVC

PM > Install-Package PiranhaCMSMVC

 

Tags:

C# | MVC

Convert Standard MVC Website to SPA (Single Page Application) Using Sammy.js

by 19. February 2015 07:17

Step One: The Layout Page

For MVC the layout page is a template that ASP.NET uses to render a single HTML document by merging it with the markup in a view page.  In a SPA, the Layout becomes a shell page into which the view's markup is loaded via AJAX calls. The Layout page's lifespan is now the user's session, rather than just the lifespan of the page, so be careful what you scope at this level; the safety net of a page refresh that cleans up after us is gone, and browser memory leaks are distinctly counter-excellent in nature.

To convert a standard MVC website to SPA we'll use NuGet to add Sammy.js to our project. Sammy (among other things) is a jQuery-dependent JavaScript framework which lets us add URL routing to the client side of our app.

Once we've brought in Sammy, we'll add it to a bundle (along with jQuery) in BundleConfig.RegisterBundles:

bundles.Add(new ScriptBundle("~/js/mvc-spa").Include(
    "~/Scripts/jquery-{version}.js",
    "~/Scripts/sammy-{version}.js"));

Then we'll render the bundle at the bottom of our Layout page:

            @Scripts.Render("~/js/mvc-spa")
    </body>
</html>

We'll also need to designate the area of the Layout where the view content will be loaded by finding the element we are currently calling RenderBody and giving it a unique id. For this example, let's go with "page".

<!-- ... -->
</header>
<section id="page">
	@RenderBody()
</section>
<footer>
<!-- ... -->    

Step Two: Go Partial

Next, we need to go through our views, and, with the exception of the Home/Index view, convert each to a Partial View.

Unlike vanilla MVC Views, Partial Views are not merged with the Layout page to render as complete HTML documents. When you make a controller request that returns a Partial View, the response is merely an HTML fragment–precisely what we're looking for in a SPA page.

To convert a View to a Partial, simply change the View call to a call to PartialView in its corresponding Controller Action:

public class SpaFtwController : Controller {
    public ActionResult Index() {
        return PartialView();
    }
}

As I may have mentioned above, do not convert your default view to a partial. This view is the "single page" in "single-page application", and it still needs to render as a complete HTML document, just the once. However, we should move this Index view's content into a separate Partial View, and replace it with some sort of splash content that will only display while our app is still loading. More on that in the next step.

Step Three: One Route to rule them all

The typical usage of Sammy is to describe multiple hash-based routes, along with the js to be executed when the user navigates to them. What we're going to do in this case, though, is create a solitary Sammy route that acts as a pass-through to the existing MVC routing already in place on the server-side.

For example, a request to /#/spaftw would load the content from /SpaFTW into our app. Using fragment identifiers for routing is a classic SPA technique; it changes the browser's URL without causing a whole page request, while also allowing the back button to still work as expected, and enables deep-linking into the app.

Here is a module that contains the code to do just this. We'll add it to our project in a file named Routing.js.

var Routing = function (appRoot, contentSelector, defaultRoute) {
function getUrlFromHash(hash) { var url = hash.replace('#/', ''); if (url === appRoot) url = defaultRoute; return url; }
return { init: function () { Sammy(contentSelector, function () { this.get(/\#\/(.*)/, function (context) { var url = getUrlFromHash(context.path); context.load(url).swap(); }); }).run('#/'); } }; }

Let's unpack that. See the this.get call about two-thirds of the way down? That's Sammy's bread and butter. We're using a regular expression to describe a route URL that captures any href beginning with '/#'. When a request is made for a URL matching this expression, Sammy intercepts it and runs the function that we've passed as get's second parameter. This function grabs this path, strips out the hash, makes an AJAX request for the Partial View for that URL, and swaps it into the element designated by contentSelector. Which, of course, will be our content area in the Layout page.

Finally, we need to wire this into our Layout page. Add Routing.js to our bundle, after Sammy.js:

bundles.Add(new ScriptBundle("~/js/mvc-spa").Include(
        "~/Scripts/jquery-{version}.js",
        "~/Scripts/sammy-{version}.js",
        "~/Scripts/Routing.js"));

Then, add the following script block to the Layout page, after rendering the bundle:

@Scripts.Render("~/js/mvc-spa")
<script>
$(function () {
    var routing = new Routing('@Url.Content("~/")', '#page', 'welcome');
    routing.init();
});
</script>

This instantiates a Routing instance with the root URL for the application (this becomes important if our app is deployed anywhere other than '/'), the selector of our content area ('#page'), and the route to default to when the user navigates to the root of the app. This should be the Partial View that inherited the original content from our Home/Index view, in step two.

Original version of this modified post published here:

http://blog.apterainc.com/bid/313071/Turn-your-ASP-NET-MVC-app-into-a-Single-Page-Application-with-one-classy-Sammy-js-route

 

Tags:

C# | MVC

Restore NUGET Packages in Visual Studio Online TFS Continuous Integration Builds

by 16. February 2015 13:25

http://geekswithblogs.net/TarunArora/archive/2014/09/14/auto-restore-nuget-packages-with-tfs-build-the-right-way.aspx

  • Step 1 - Enable NuGet Package Restore

        image

        Projects that use MSBuild-Integrated package restore typically contain a .nuget folder with three files:

    • NuGet.Config
    • NuGet.exe
    • NuGet.targets

Since the presence of a NuGet.targets file determines whether NuGet will continue to use the MSBuild-Integrated approach, this file must be removed. Also, as the .nuget\NuGet.exe file is not used by Automatic Package Restore, it likewise can be removed. By default, the NuGet.Config file instructs NuGet to bypass adding package binaries to source control. Automatic Package Restore will honour this as long as you leave this file in place. Note that NuGet.Config only has an effect when using Visual Studio to integrate with Team Foundation Server (TFS). In addition to these files, NuGet modifies the project files in the solution to reference the NuGet.targets file so it can participate in the build process. When migrating to Automatic Package Restore, these references must also be removed.

       Remove the NuGet.exe and NuGet.targets files from the solution's .nuget folder. Make sure the files themselves are also removed from the solution workspace.
       Retain the NuGet.Config file to continue to bypass adding packages to source control.

  • Step 2 – Close Down Visual Studio

        Each project in your solution that has picked up any of the below listed tags in the project properties will need to be removed. Open the project in Notepad and look for the below tags, remove these tags…

1. ------------------- 
<RestorePackages>true</RestorePackages>
----------------------

2. -------------------
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />  
----------------------

3. --------------------
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">  
    <PropertyGroup>
        <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, 
see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
------------------------
  • Step 3 – Open the solution and check in the changes

        Once you have made the above listed changes, you are good to check in the changes.

Trigger the  build now, the build server should now be able to successfully resolve the package references…

More details here… http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages

Tags:

ASP.Net | TFS | Visual Studio

Microsoft ASP.Net Identity 2.1.0

by 10. January 2015 11:10

http://blogs.msdn.com/b/webdev/archive/2014/08/05/announcing-rtm-of-asp-net-identity-2-1-0.aspx

Tags:

Issue with ASP.Net Identity from Default Local File System Database to SQL Server Based Database

by 22. December 2014 10:12

I created a new MVC 5 web application with the "Individual User Account" option that configures the ASP.Net Identity model.  By default this uses Entity Framework Code First model with a local file system database created in the local App_Data folder.  I tried moving this to an actual SQL Server database location by creating the five dbo.aspnet_... tables and changing the web.config to point to the new location.  However, in doing so I received the error below.  Turns out to solve this I just needed to change the connection string in the web.config from the Entity Framework style to the basic style (see old vs. new connection strings below).

 <connectionStrings>

    <addname="NewSimpleConnection"connectionString="Data Source=SERVER_NAME_HERE;initial catalog=DB_NAME_HERE;user id=USER_ID_HERE;password=PASSWORD_HERE;Integrated Security=False"providerName="System.Data.SqlClient" />

    <addname="OldEtityFConnection"connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=SERVER_NAME_HERE;initial catalog=DB_NAME_HERE;user id=USER_ID_HERE;password=PASSWORD_HERE;MultipleActiveResultSets=True;App=EntityFramework&quot;"providerName="System.Data.EntityClient" />

  </connectionStrings> 

Server Error in '/' Application.


 

Unable to load the specified metadata resource.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.Entity.Core.MetadataException: Unable to load the specified metadata resource.

Source Error:

 

Line 114:      {
Line 115:        var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
Line 116:        IdentityResult result = await UserManager.CreateAsync(user, model.Password);
Line 117:        if (result.Succeeded)
Line 118:        {

Tags:

ASP.Net | C# | SQL Server

Window Update Slow or Stuck Checking for Updates

by 25. November 2014 06:53

After a fresh install of Windows 7 my Windows Update would take a long time (and typically never finish) when Checking for Updates.  In order to fix this I followed the steps below:

  1. Open the Windows Update panel and set to “Never Check For Updates (Not Recommended)”
  2. Stop the Windows Update Service (cmd: net stop wuauserv)
  3. Delete the folder: "C:\Windows\SoftwareDistribution"
  4. Restart the Windows Update Service (cmd: net start wuauserv)
  5. Download and install the two KB updates listed below:

 

Tags:

Windows

JavaScript Testing Tools

by 25. September 2014 06:35

Tags:

JavaScript

AdventureWorks Sample Database

by 23. September 2014 08:26

Download the 2012 SQL DB version of Microsoft AdventureWorks Sample Database here:


http://msftdbprodsamples.codeplex.com/downloads/get/165399

 

Tags:

SQL Server

Parse JSON in TSQL

by 11. July 2014 06:44

Parsing JSON using TSQL.

/*
  Repost from: https://www.simple-talk.com/sql/t-sql-programming/consuming-json-strings-in-sql-server/
*/

CREATE FUNCTION dbo.parseJSON(@JSON NVARCHAR(MAX))
RETURNS @hierarchy TABLE
  (
   element_id INT IDENTITY(1, 1) NOT NULL,/* internal surrogate primary key gives the order of parsing and the list order */
   sequenceNo [int] NULL, /* the place in the sequence for the element */
   parent_ID INT,/* if the element has a parent then it is in this column. The document is the ultimate parent, so you can get the structure from recursing from the document */
   Object_ID INT,/* each list or object has an object id. This ties all elements to a parent. Lists are treated as objects here */
   NAME NVARCHAR(2000),/* the name of the object */
   StringValue NVARCHAR(MAX)NOT NULL,/*the string representation of the value of the element. */
   ValueType VARCHAR(10) NOT null/* the declared type of the value represented as a string in StringValue*/
  )
AS
BEGIN
  DECLARE
    @FirstObject INT, --the index of the first open bracket found in the JSON string
    @OpenDelimiter INT,--the index of the next open bracket found in the JSON string
    @NextOpenDelimiter INT,--the index of subsequent open bracket found in the JSON string
    @NextCloseDelimiter INT,--the index of subsequent close bracket found in the JSON string
    @Type NVARCHAR(10),--whether it denotes an object or an array
    @NextCloseDelimiterChar CHAR(1),--either a '}' or a ']'
    @Contents NVARCHAR(MAX),--the unparsed contents of the bracketed expression
    @Start INT, --index of the start of the token that you are parsing
    @end INT,--index of the end of the token that you are parsing
    @param INT,--the parameter at the end of the next Object/Array token
    @EndOfName INT,--the index of the start of the parameter at end of Object/Array token
    @token NVARCHAR(200),--either a string or object
    @value NVARCHAR(MAX),-- the value as a string
    @SequenceNo int, -- the sequence number within a list
    @name NVARCHAR(200),--the name as a string
    @parent_ID INT,--the next parent ID to allocate
    @lenJSON INT,--the current length of the JSON String
    @characters NCHAR(36),--used to convert hex to decimal
    @result BIGINT,--the value of the hex symbol being parsed
    @index SMALLINT,--used for parsing the hex value
    @Escape INT --the index of the next escape character
  DECLARE @Strings TABLE /* in this temporary table we keep all strings, even the names of the elements, since they are 'escaped' in a different way, and may contain, unescaped, brackets denoting objects or lists. These are replaced in the JSON string by tokens representing the string */
    (
     String_ID INT IDENTITY(1, 1),
     StringValue NVARCHAR(MAX)
    )
  SELECT--initialise the characters to convert hex to ascii
    @characters='0123456789abcdefghijklmnopqrstuvwxyz',
    @SequenceNo=0,--set the sequence no. to something sensible.
  /* firstly we process all strings. This is done because [{} and ] aren't escaped in strings, which complicates an iterative parse. */
    @parent_ID=0;
  WHILE 1=1 --forever until there is nothing more to do
    BEGIN
      SELECT
        @start=PATINDEX('%[^a-zA-Z]["]%', @json collate SQL_Latin1_General_CP850_Bin);--next delimited string
      IF @start=0 BREAK--no more so drop through the WHILE loop
      IF SUBSTRING(@json, @start+1, 1)='"'
        BEGIN --Delimited Name
          SET @start=@Start+1;
          SET @end=PATINDEX('%[^\]["]%',RIGHT(@json, LEN(@json+'|')-@start)collate SQL_Latin1_General_CP850_Bin);
        END
      IF @end=0 --no end delimiter to last string
        BREAK --no more
      SELECT @token=SUBSTRING(@json, @start+1, @end-1)
      --now put in the escaped control characters
      SELECT @token=REPLACE(@token, FROMString, TOString)
      FROM
        (SELECT
          '\"' AS FromString,'"' AS ToString
         UNION ALL SELECT'\\', '\'
         UNION ALL SELECT'\/', '/'
         UNION ALL SELECT'\b', CHAR(08)
         UNION ALL SELECT'\f', CHAR(12)
         UNION ALL SELECT'\n', CHAR(10)
         UNION ALL SELECT'\r', CHAR(13)
         UNION ALL SELECT'\t', CHAR(09)
        ) substitutions
      SELECT @result=0, @escape=1
  --Begin to take out any hex escape codes
      WHILE @escape>0
        BEGIN
          SELECT @index=0,
          --find the next hex escape sequence
          @escape=PATINDEX('%\x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]%', @token collate SQL_Latin1_General_CP850_Bin)
          IF @escape>0 --if there is one
            BEGIN
              WHILE @index<4 --there are always four digits to a \x sequence  
                BEGIN
                  SELECT --determine its value
                    @result=@result+POWER(16, @index)
                    *(CHARINDEX(SUBSTRING(@token, @escape+2+3-@index, 1),
                                @characters)-1), @index=@index+1 ;
                END
                -- and replace the hex sequence by its unicode value
              SELECT @token=STUFF(@token, @escape, 6, NCHAR(@result))
            END
        END
      --now store the string away
      INSERT INTO @Strings (StringValue) SELECT @token
      -- and replace the string with a token
      SELECT @JSON=STUFF(@json, @start, @end+1,
                    '@string'+CONVERT(NVARCHAR(5),@@identity))
    END
  -- all strings are now removed. Now we find the first leaf. 
  WHILE 1=1  --forever until there is nothing more to do
  BEGIN
  SELECT @parent_ID=@parent_ID+1
  --find the first object or list by looking for the open bracket
  SELECT @FirstObject=PATINDEX('%[{[[]%', @json collate SQL_Latin1_General_CP850_Bin)--object or array
  IF @FirstObject = 0 BREAK
  IF (SUBSTRING(@json, @FirstObject, 1)='{')
    SELECT @NextCloseDelimiterChar='}', @type='object'
  ELSE
    SELECT @NextCloseDelimiterChar=']', @type='array'
  SELECT @OpenDelimiter=@firstObject
  WHILE 1=1 --find the innermost object or list...
    BEGIN
      SELECT
        @lenJSON=LEN(@JSON+'|')-1
  --find the matching close-delimiter proceeding after the open-delimiter
      SELECT
        @NextCloseDelimiter=CHARINDEX(@NextCloseDelimiterChar, @json,
                                      @OpenDelimiter+1)
  --is there an intervening open-delimiter of either type
      SELECT @NextOpenDelimiter=PATINDEX('%[{[[]%',
             RIGHT(@json, @lenJSON-@OpenDelimiter)collate SQL_Latin1_General_CP850_Bin)--object
      IF @NextOpenDelimiter=0
        BREAK
      SELECT @NextOpenDelimiter=@NextOpenDelimiter+@OpenDelimiter
      IF @NextCloseDelimiter<@NextOpenDelimiter
        BREAK
      IF SUBSTRING(@json, @NextOpenDelimiter, 1)='{'
        SELECT @NextCloseDelimiterChar='}', @type='object'
      ELSE
        SELECT @NextCloseDelimiterChar=']', @type='array'
      SELECT @OpenDelimiter=@NextOpenDelimiter
    END
  ---and parse out the list or name/value pairs
  SELECT
    @contents=SUBSTRING(@json, @OpenDelimiter+1,
                        @NextCloseDelimiter-@OpenDelimiter-1)
  SELECT
    @JSON=STUFF(@json, @OpenDelimiter,
                @NextCloseDelimiter-@OpenDelimiter+1,
                '@'+@type+CONVERT(NVARCHAR(5), @parent_ID))
  WHILE (PATINDEX('%[A-Za-z0-9@+.e]%', @contents collate SQL_Latin1_General_CP850_Bin))<>0
    BEGIN
      IF @Type='Object'--it will be a 0-n list containing a string followed by a string, number,boolean, or null
        BEGIN
          SELECT
            @SequenceNo=0,@end=CHARINDEX(':',' '+@contents)--if there is anything, it will be a string-based name.
          SELECT  @start=PATINDEX('%[^A-Za-z@][@]%',' '+@contents collate SQL_Latin1_General_CP850_Bin)--AAAAAAAA
          SELECT @token=SUBSTRING(' '+@contents, @start+1, @End-@Start-1),
            @endofname=PATINDEX('%[0-9]%', @token collate SQL_Latin1_General_CP850_Bin),
            @param=RIGHT(@token,LEN(@token)-@endofname+1)
          SELECT
            @token=LEFT(@token, @endofname-1),
            @Contents=RIGHT(' '+@contents,LEN(' '+@contents+'|')-@end-1)
          SELECT  @name=stringvalue FROM @strings
            WHERE string_id=@param --fetch the name
        END
      ELSE
        SELECT @Name=null,@SequenceNo=@SequenceNo+1
      SELECT
        @end=CHARINDEX(',', @contents)-- a string-token, object-token, list-token, number,boolean, or null
      IF @end=0
        SELECT  @end=PATINDEX('%[A-Za-z0-9@+.e][^A-Za-z0-9@+.e]%', @Contents+' ' collate SQL_Latin1_General_CP850_Bin)
          +1
       SELECT
        @start=PATINDEX('%[^A-Za-z0-9@+.e][A-Za-z0-9@+.e]%',' '+@contents collate SQL_Latin1_General_CP850_Bin)
      --select @start,@end, LEN(@contents+'|'), @contents 
      SELECT
        @Value=RTRIM(SUBSTRING(@contents, @start, @End-@Start)),
        @Contents=RIGHT(@contents+' ', LEN(@contents+'|')-@end)
      IF SUBSTRING(@value, 1, 7)='@object'
        INSERT INTO @hierarchy
          (NAME, SequenceNo, parent_ID, StringValue,Object_ID, ValueType)
          SELECT @name, @SequenceNo, @parent_ID, SUBSTRING(@value, 8, 5),
            SUBSTRING(@value, 8, 5), 'object'
      ELSE
        IF SUBSTRING(@value, 1, 6)='@array'
          INSERT INTO @hierarchy
            (NAME, SequenceNo, parent_ID, StringValue,Object_ID, ValueType)
            SELECT @name, @SequenceNo, @parent_ID, SUBSTRING(@value, 7, 5),
              SUBSTRING(@value, 7, 5), 'array'
        ELSE
          IF SUBSTRING(@value, 1, 7)='@string'
            INSERT INTO @hierarchy
              (NAME, SequenceNo, parent_ID, StringValue, ValueType)
              SELECT @name, @SequenceNo, @parent_ID, stringvalue, 'string'
              FROM @strings
              WHERE string_id=SUBSTRING(@value, 8, 5)
          ELSE
            IF @value IN ('true','false')
              INSERT INTO @hierarchy
                (NAME, SequenceNo, parent_ID, StringValue, ValueType)
                SELECT @name, @SequenceNo, @parent_ID, @value, 'boolean'
            ELSE
              IF @value='null'
                INSERT INTO @hierarchy
                  (NAME, SequenceNo, parent_ID, StringValue, ValueType)
                  SELECT @name, @SequenceNo, @parent_ID, @value, 'null'
              ELSE
                IF PATINDEX('%[^0-9]%', @value collate SQL_Latin1_General_CP850_Bin)>0
                  INSERT INTO @hierarchy
                    (NAME, SequenceNo, parent_ID, StringValue, ValueType)
                    SELECT @name, @SequenceNo, @parent_ID, @value, 'real'
                ELSE
                  INSERT INTO @hierarchy
                    (NAME, SequenceNo, parent_ID, StringValue, ValueType)
                    SELECT @name, @SequenceNo, @parent_ID, @value, 'int'
      if @Contents=' 'Select @SequenceNo=0
    END
  END
INSERT INTO @hierarchy (NAME, SequenceNo, parent_ID, StringValue,Object_ID, ValueType)
  SELECT '-',1,NULL, '', @parent_id-1, @type
--
   RETURN
END
GO

-- Create the data type
IF EXISTS (SELECT * FROM sys.types WHERE name LIKE 'Hierarchy')
  DROP TYPE dbo.Hierarchy
go
CREATE TYPE dbo.Hierarchy AS TABLE
(
   element_id INT NOT NULL, /* internal surrogate primary key gives the order of parsing and the list order */
   sequenceNo [int] NULL, /* the place in the sequence for the element */
   parent_ID INT,/* if the element has a parent then it is in this column. The document is the ultimate parent, so you can get the structure from recursing from the document */
   [Object_ID] INT,/* each list or object has an object id. This ties all elements to a parent. Lists are treated as objects here */
   NAME NVARCHAR(2000),/* the name of the object, null if it hasn't got one */
   StringValue NVARCHAR(MAX) NOT NULL,/*the string representation of the value of the element. */
   ValueType VARCHAR(10) NOT null /* the declared type of the value represented as a string in StringValue*/
    PRIMARY KEY (element_id)
)

Tags:

SQL Server

Forcing HTTPS Over HTTP

by 7. July 2014 15:32

The <rewrite> section below will force HTTPS over HTTP:

  <system.webServer>
    <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <rewrite>
      <rules>
        <rule name="Redirect to https">
          <match url="(.*)"/>
          <conditions>
            <add input="{HTTPS}" pattern="Off"/>
            <add input="{REQUEST_METHOD}" pattern="^get$|^head$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

Tags:

ASP.Net

ASP.Net MVC Bind Boolean to DropDownList Using @Html.DropDownListFor

by 25. June 2014 07:41

I was having difficulty binding a bool property to a DropDownList using the @Html.DropDownListFor() method.  What ended up working well was to do the following:

 

Add this to the View Controller class:

private void Select_YN_Rebind()
{
  List<SelectListItem> Select_YN = new List<SelectListItem>();
  Select_YN.Add(new SelectListItem
  {
    Text = "No",
    Value = bool.FalseString
  });
  Select_YN.Add(new SelectListItem
  {
    Text = "Yes",
    Value = bool.TrueString
  });
  ViewData["Select_YN"] = Select_YN;
}


Add call to the new method in the View Controller Create method (or whatever other method is appropriate) before returning the view:

public ActionResult Create()
{
  Select_YN_Rebind();
  return View();
}

Call the @Html.DropDownListFor() as shown below:

 @Html.DropDownListFor(model => model.YourBoolPropertyHere
, (IEnumerable<SelectListItem>)ViewData["Select_YN"])

 

Tags:

ASP.Net | MVC

ASP.Net MVC 5 Issue Validating Numbers (Decimal) when Number Contains Commas

by 20. June 2014 11:37

ASP.Net MVC 5 number (decimal) validation failing when user entered data contains commas.  To get around this issue I created a custom

Create the following object and bind it in the Global.asax as shown below.  NOTE: For javascript client side validations create a new *.js file and make sure to include it AFTER the jquery.validate* in the BundleConfig.cs.

JAVASCRIPT OVERRIDE

$.validator.methods.range = function (value, element, param) {
  var globalizedValue = value.replace(",", ".");
  return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}
$.validator.methods.number = function (value, element) {
  return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
};

GLOBAL.ASAX ADDITION

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

NEW .CS FILE

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyApp.Models.Binders
{
  public class DecimalModelBinder : IModelBinder
  {
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
      ValueProviderResult valueResult = bindingContext.ValueProvider
          .GetValue(bindingContext.ModelName);
      ModelState modelState = new ModelState { Value = valueResult };
      object actualValue = null;
      try
      {
        //Check if this is a nullable decimal and a null or empty string has been passed
        var isNullableAndNull = (bindingContext.ModelMetadata.IsNullableValueType &&
                                 string.IsNullOrEmpty(valueResult.AttemptedValue));

        //If not nullable and null then we should try and parse the decimal
        if (!isNullableAndNull)
        {
          actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
        }
      }
      catch (FormatException e)
      {
        modelState.Errors.Add(e);
      }

      bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
      return actualValue;
    }
  }
}

Tags:

ASP.Net | MVC

ASP.Net MVC 5 Issue Validating Numbers (Decimal) when Number Contains Commas

by 20. June 2014 11:37

ASP.Net MVC 5 number (decimal) validation failing when user entered data contains commas.  To get around this issue I created a custom

Create the following object and bind it in the Global.asax as shown below.

GLOBAL.ASAX

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

NEW .CS FILE

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyApp.Models.Binders
{
  public class DecimalModelBinder : IModelBinder
  {
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
      ValueProviderResult valueResult = bindingContext.ValueProvider
          .GetValue(bindingContext.ModelName);
      ModelState modelState = new ModelState { Value = valueResult };
      object actualValue = null;
      try
      {
        //Check if this is a nullable decimal and a null or empty string has been passed
        var isNullableAndNull = (bindingContext.ModelMetadata.IsNullableValueType &&
                                 string.IsNullOrEmpty(valueResult.AttemptedValue));

        //If not nullable and null then we should try and parse the decimal
        if (!isNullableAndNull)
        {
          actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
        }
      }
      catch (FormatException e)
      {
        modelState.Errors.Add(e);
      }

      bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
      return actualValue;
    }
  }
}

Tags:

ASP.Net