European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET 4.5 Cloud Hosting - Germany :: Claims-Based Security in ASP.NET 4.5

clock June 5, 2014 10:42 by author Scott

When you talk about authentication in ASP.NET you will most undoubtedly hear the mention of the MembershipProvider. I'm here to tell you not to go down that road. That road will only lead to tears and suffering. This post will help you understand and implement your ASP.NET authentication built on top of FormsAuthentication. I hope you take away that building this stuff is not hard as long as you don't try to over think it.

Before I show you how to implement a kick-butt authentication system, I'll show you the simplest solution you could build.

FormsAuthentication.SetAuthCookie(user.Id, createPersistentCookie: true);

Congratulations you are now officially signed into your ASP.NET application using forms authentication. Notice I don't have any SQL migrations, crazy classes, or any other crap you didn't ask for.

 

The code above writes a cookie to the response of the current HttpContext. On the user's next request that cookie will be passed back to the server and used to check whether they are authenticated or not.

Password Hasher

Hashing passwords is really easy with .NET. The trick is to generate a salt with every password. The idea of the salt is not to be a secret, but to be unique every time. This makes it difficult for hackers to process all your passwords in the case your system is compromised. This is my standard password hasher:

public static class PasswordHasher {
    private const int SaltSize = 64;

    public static Passphrase Hash(string password) {
        if (password == null) throw new ArgumentNullException("password");

        byte[] passwordBytes = Encoding.Unicode.GetBytes(password);
        byte[] saltBytes = CreateRandomSalt();
        string hashedPassword = ComputeHash(passwordBytes, saltBytes);

        return new Passphrase {
            Hash = hashedPassword,
            // Convert salt from byte[] to string
            Salt = Convert.ToBase64String(saltBytes)
        };
    }

    public static bool Equals(string password, string salt, string hash) {
        return String.CompareOrdinal(hash, Hash(password, salt)) == 0;
    }

    public static string GenerateRandomSalt(int size = SaltSize) {
        return Convert.ToBase64String(CreateRandomSalt(size));
    }

    private static string ComputeHash(byte[] password, byte[] salt) {
        var passwordAndSalt = new byte[salt.Length + password.Length];

        Buffer.BlockCopy(salt, 0, passwordAndSalt, 0, salt.Length);
        Buffer.BlockCopy(password, 0, passwordAndSalt, salt.Length, password.Length);
        byte[] computedHash;
        using (HashAlgorithm algorithm = new SHA256Managed()) {
            computedHash = algorithm.ComputeHash(passwordAndSalt);
        }
        return Convert.ToBase64String(computedHash);
    }

    private static string Hash(string password, string salt) {
        return ComputeHash(Encoding.Unicode.GetBytes(password), Convert.FromBase64String(salt));
    }

    private static byte[] CreateRandomSalt(int size = SaltSize) {
        if (size <= 0)
            throw new ArgumentException("size must be greater than zero.");

        var saltBytes = new Byte[size];
        using (var rng = new RNGCryptoServiceProvider()) {
            rng.GetBytes(saltBytes);
        }
        return saltBytes;
    }
}

public class Passphrase {
    public string Hash { get; set; }
    public string Salt { get; set; }
}

Principal and Identity

The IPrincipal and IIdentity interfaces are crucial to authentication in .NET. If you have ever used HttpContext, WebForms, or ASP.NET MVC then you are using derivations of these interfaces. It usually comes in the guise of a User property. You don't have to implement these classes, you can always use the GenericPrincipal and GenericIdentity. I like to implement them myself, because it allows me to pass a bit more useful data around in the cookie (remember cookies have size limits).

Let's first look at the IPrinicipal implementation:

public class MuchoPrincipal : IPrincipal {
    private readonly MuchoIdentity _identity;

    public MuchoPrincipal(MuchoIdentity identity) {
        _identity = identity;
    }

    #region IPrincipal Members

    public bool IsInRole(string role) {
        return
            _identity.Roles.Any(
                current => string.Compare(current, role, StringComparison.InvariantCultureIgnoreCase) == 0);
    }

    public IIdentity Identity {
        get { return _identity; }
    }

    public MuchoIdentity Information {
        get { return _identity; }
    }

    public bool IsUser {
        get { return !IsGuest; }
    }

    public bool IsGuest {
        get { return IsInRole("guest"); }
    }

    #endregion
}

Next up is the IIdentity, just take a look:

public class MuchoIdentity : IIdentity {
    public MuchoIdentity(FormsAuthenticationTicket ticket) {
        if (ticket == null) {
            Name = "Guest";
            Roles = new List<string> { "guest" };
            return;
        }

        var data = JsonConvert.DeserializeObject<MuchoCookie>(ticket.UserData);

        if (data == null) {
            AsGuest();
            return;
        }

        Id = data.Id;
        FirstName = data.FirstName;
        LastName = data.LastName;
        Name = string.IsNullOrWhiteSpace(FirstName) || string.IsNullOrWhiteSpace(LastName)
                   ? data.Email
                   : "{0} {1}".With(FirstName, LastName);
        Email = data.Email;
        Roles = data.Roles ?? new List<string> { "user" };
        RememberMe = data.RememberMe;

        try {
            TimeZone = TimeZoneInfo.FindSystemTimeZoneById(data.TimeZone);
        } catch (Exception) {
            TimeZone = TimeZoneInfo.Utc;
        }
    }

    public MuchoIdentity(User user) {
        if (user == null) {
            AsGuest();
            return;
        }

        Id = user.Id;
        Email = user.Email;
        FirstName = user.FirstName;
        LastName = user.LastName;
        Name = string.IsNullOrWhiteSpace(FirstName) || string.IsNullOrWhiteSpace(LastName)
                   ? user.Email
                   : "{0} {1}".With(FirstName, LastName);

        try {
            TimeZone = TimeZoneInfo.FindSystemTimeZoneById(user.TimeZone);
        } catch (Exception) {
            TimeZone = TimeZoneInfo.Utc;
        }
        Roles = new List<string> { user.Role ?? "user" };
    }

    private void AsGuest() {
        Name = "Guest";
        Roles = new List<string> { "guest" };
    }

    public int Id { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public TimeZoneInfo TimeZone { get; set; }
    public bool RememberMe { get; set; }
    public IList<string> Roles { get; set; }

    #region IIdentity Members

    public string AuthenticationType {
        get { return "MuchoForms"; }
    }

    public bool IsAuthenticated {
        get { return !( Id == 0 || string.IsNullOrWhiteSpace(Email)); }
    }

    public string Name { get; protected set;

    #endregion
}

C is for Cookie

The cookie object is really just a data transfer object. Nothing really mind blowing here. I usually create a structure to store my useful information. Again, keep in mind the size limitations of a cookie which is about 4kb (4096 bytes).

public class MuchoCookie {
    public MuchoCookie() {
        Roles = new List<string>();
    }

    public int Id { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string TimeZone { get; set; }
    public List<string> Roles { get; set; }
    public bool RememberMe { get; set; }
}

FormsAuthenticationService

FormsAuthentication is built right into ASP.NET, but I like to write a littler wrapper around it so I can test and inject it into other classes. Also I create the cookie from the previous section when a user successfully signs in.

public class FormsAuthenticationService : IFormsAuthenticationService {
    private readonly HttpContextBase _httpContext;

    public FormsAuthenticationService(HttpContextBase httpContext) {
        _httpContext = httpContext;
    }

    #region IFormsAuthenticationService Members

    public void SignIn(User user, bool createPersistentCookie) {
        if (user == null)
            throw new ArgumentNullException("user");

        var cookie = new MuchoCookie {
            Id = user.Id,
            Email = user.Email,
            FirstName = user.FirstName,
            LastName = user.LastName,
            RememberMe = createPersistentCookie,
            TimeZone = user.TimeZone,
            Roles = new List<string> { user.Role ?? "user" }
        };

        string userData = JsonConvert.SerializeObject(cookie);
        var ticket = new FormsAuthenticationTicket(1, cookie.Email, DateTime.Now,
                                                   DateTime.Now.Add(FormsAuthentication.Timeout),
                                                   createPersistentCookie, userData);
        string encTicket = FormsAuthentication.Encrypt(ticket);
        var httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = DateTime.Now.Add(FormsAuthentication.Timeout) };

        _httpContext.Response.Cookies.Add(httpCookie);
    }

    public void SignOut() {
        // Not worth covering, has been tested by Microsoft
        FormsAuthentication.SignOut();
    }

    #endregion
}

Notice the SignIn method creates the cookie and just writes it to the response using FormsAuthentication. We are leveraging what ASP.NET gives us. There is no reason to reinvent the wheel when it comes to passing secure cookies to the client.

PrincipalService

The principal service helps us get the information out of a cookie and rehydrate our IPrinipal and our IIdentity to our custom implementations. The other added benefit is we can actually set the User property to a Guest principal with extra information if we need it.

public class MuchoSupportPrincipalService : IPrincipalService {
    private readonly HttpContextBase _context;

    public MuchoSupportPrincipalService(HttpContextBase context) {
        _context = context;
    }

    #region IPrincipalService Members

    public IPrincipal GetCurrent() {
        IPrincipal user = _context.User;
        // if they are already signed in, and conversion has happened
        if (user != null && user is MuchoPrincipal)
            return user;

        // if they are signed in, but conversion has still not happened
        if (user != null && user.Identity.IsAuthenticated && user.Identity is FormsIdentity) {
            var id = (FormsIdentity)_context.User.Identity;

            var ticket = id.Ticket;
            if (FormsAuthentication.SlidingExpiration) 
                ticket = FormsAuthentication.RenewTicketIfOld(ticket);

            var fid = new MuchoIdentity(ticket);
            return new MuchoPrincipal(fid);
        }

        // not sure what's happening, let's just default here to a Guest
        return new MuchoPrincipal(new MuchoIdentity((FormsAuthenticationTicket)null));
    }

    #endregion
}

The trick here is just to check the current context for the cookie already being passed in with our request. You need to call this code from your Global.asax as such (note I am using ASP.NET MVC and the dependency resolver built into it).

protected void Application_AuthenticateRequest(object sender, EventArgs e) {
    var principalService = DependencyResolver.Current.GetService<IPrincipalService>();
    var context = DependencyResolver.Current.GetService<HttpContextBase>();
    // Set the HttpContext's User to our IPrincipal
    context.User = principalService.GetCurrent();
}

Usage in Your Code

This is what my ASP.NET MVC controller looks like:

[RequireScheme(Scheme.Https)]
public class AuthenticationController : ApplicationController {
public ActionResult Login(string returnUrl) {

if (User.Identity.IsAuthenticated) {
if (!string.IsNullOrWhiteSpace(returnUrl))
return Redirect(returnUrl);

return RedirectToAction("show", "dashboard");
}

var model = new LoginModel {
ReturnUrl = returnUrl
};

return View(model);
}

[HttpPost]
public ActionResult Login(LoginModel input) {
// validation does password hash check
// you could do it more explicitly
if (ModelState.IsValid) {
Logger.Info("successful!", input.Username);
var user = Db.Users
.FirstOrDefault(u => u.Email == input.Username);
// set cookie
Forms.SignIn(user, input.RememberMe);
return input.HasReturnUrl(Url)
? Redirect(input.ReturnUrl)
: (ActionResult) RedirectToAction("show", "dashboard");
}

Flash.Error("Please try again");

return View("login", input);
}

public ActionResult Logout() {
Forms.SignOut();
return RedirectToAction("login");
}
}

Conclusion

The parts of an authentication system are all infrastructural. It is all smooth sailing once you get over the hump of setting it up. Once the infrastructure is set up you can work on creating your own tables for Users, Profiles, or any other domain model that makes sense. All access to user's is up to you, so feel free to use any data access provider you like: SQL Server, RavenDB, MongoDB, etc. Additionally, the cookie is now yours; feel free to add or remove data from it as you see fit, but always remember the 4kb size limit.



Free ASP.NET 4.5 Cloud Hosting Spain - HostForLIFE.eu :: Count Number of Nodes in XML File in ASP.NET 4.5

clock May 6, 2014 06:00 by author Peter

Here I will explain how to count number of records in xml file in C# using ASP.NET 4.5 Cloud Hosting Spain or how to count number of nodes in xml file in asp.net using C# and VB.NET or count number of elements in xml file in C#.

In previous articles I explained insert xml data to sql table using stored procedure, Bind xml data to dropdown/gridview in asp.net, create online poll system with percentage graphs in asp.net and many articles relating to xml, Gridview, SQL, jQuery,asp.net, C#,VB.NET. Now I will explain how to count number of records in xml file in C# using ASP.NET.

To count number of nodes from xml file we need to write the code like as shown below

XmlDocument readDoc = new XmlDocument();
readDoc.Load(MapPath("Sample.xml"));
int count = readDoc.SelectNodes("CommentsInformation/Comments").Count;
lblcount.InnerHtml = "Number of Records: "+ count;

If you want to see it in complete example we need to write the code like as shown below
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td style="width: 100px">
Name:</td>
<td style="width: 100px">
<asp:TextBox ID="txtName" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td style="width: 100px">
Email:</td>
<td style="width: 100px">
<asp:TextBox ID="txtEmail" runat="server"></asp:TextBox></td>
</tr>
<tr><td></td>
<td>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" /></td>
</tr>
</table>
<br />
<label id="lblcount" runat="server" />
</div>
</form>
</body>
</html>

After that add XML file to your application and give name as "Sample.xml" then add root element in xml file otherwise it will through error. Here I added CommentInformation as root element in XML file.
<?xml version="1.0" encoding="utf-8"?>
<CommentsInformation>
 </CommentsInformation>

After that add this namespace in codebehind

C# Code
using System;
using System.Xml;

After that add below code in code behind

protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(Server.MapPath("Sample.xml"));
XmlElement parentelement = xmldoc.CreateElement("Comments");
XmlElement name = xmldoc.CreateElement("Name");
name.InnerText = txtName.Text;
XmlElement email = xmldoc.CreateElement("Email");
email.InnerText = txtEmail.Text;

parentelement.AppendChild(name);parentelement.AppendChild(email);
xmldoc.DocumentElement.AppendChild(parentelement);
xmldoc.Save(Server.MapPath("Sample.xml"));
XmlDocument readDoc = new XmlDocument();
readDoc.Load(MapPath("Sample.xml"));
int count = readDoc.SelectNodes("CommentsInformation/Comments").Count;
lblcount.InnerHtml = "Number of Records: "+ count;
}

VB.NET Code
Imports System.Xml
Partial Class vbcode
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim xmldoc As New XmlDocument()
xmldoc.Load(Server.MapPath("Sample.xml"))
Dim parentelement As XmlElement = xmldoc.CreateElement("Comments")
Dim name As XmlElement = xmldoc.CreateElement("Name")
name.InnerText = txtName.Text
Dim email As XmlElement = xmldoc.CreateElement("Email")
email.InnerText = txtEmail.Text
parentelement.AppendChild(name)
parentelement.AppendChild(email)
xmldoc.DocumentElement.AppendChild(parentelement)
xmldoc.Save(Server.MapPath("Sample.xml"))
Dim readDoc As New XmlDocument()
readDoc.Load(MapPath("Sample.xml"))
Dim count As Integer = readDoc.SelectNodes("CommentsInformation/Comments").Count
lblcount.InnerHtml = "Number of Records: " & count
End Sub
End Class



Free ASP.NET 4.5 Hosting Spain - HostForLIFE.eu :: ASP.NET Validation Controls.

clock April 29, 2014 09:01 by author Peter

Today I will discuss about the various validation control that ASP.NET Hosting provide and benefit of using it over client side validation. ASP.NET validation control provide two ways validation. i.e. both Server side and Client side. They perform client-side validation if after confirming that browser allows client side validation(i.e JavaScript is enabled), thereby reducing the overhead of round trip. If client side validation is disabled, it will perform the server side validation. All this from detection to validation is all taken care by the ASP.NET.

In total ASP.NET provide 5 + 1(ValidationSummary) validation control:

  1. RequiredFieldValidator 
  2. CompareValidator
  3. CustomValidator
  4. RangeValidator
  5. RegularExpressionValidator 
  6. ValidationSummary Control      

will discuss about all the control in detail, but before that i will elaborate the attributes that are common to all the controls. 

1. Display - This attribute is used to display the error message. It takes 3 options

  • None: This will ensure that no error message is displayed. Used when Validation summary is used.
  • Static: This will ensure that space on the  page is reserved even if validation pass. i.e. Real estate area on the page will be allocated.
  • Dynamic: This will ensure that space for error message is reserved only if validation fails.

In short static and dynamic do exactly the same thing. Difference between them is that in case of static Style for the <span> is

style="visibility: hidden; color: red;"

and in case of Dynamic Style for span is

style="display: none; color: red;"

2. ControlToValidate - This attribute is used to get the control on which validation is to applied
3. EnableClientScript - Boolean value to indicate whether client- side validation is enabled or not. Default value is true.
4. IsValid - Boolean value to indicate whether the control mention is ControlToValidate attribute is valid or not. Default value is true.
5. Enabled - Boolean valued to indicate if Validation control is enabled or not. Default value is true.
6. ErrorMessage - This is the text message that will be displayed in the validation summary.

RequiredFieldValidator Control
As the name suggest, this validation control make sure that control mention in ControlToValidate cannot be empty.
<asp:TextBox ID="txtSampleTextBox" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="reqfldValidator" runat="server" ControlToValidate="txtSampleTextBox" 
Enabled="true" Display="Dynamic" ErrorMessage="Required" ToolTip="Required">
*</asp:RequiredFieldValidator>

CompareValidator Control
This Control is used to compare the value or one control to the value of another control or to a fixed value. One catch here is that validation pass if both the fields are empty. To handle that one require to apply Required field validator along with CompareValidator.
<asp:TextBox ID="TextBox1" runat="server" />
<asp:TextBox ID="txtTextBox2" runat="server" />
<asp:CompareValidator ID="CompareValidator1" runat="server" ControlToValidate="txtTextBox1" ControlToCompare="txtTextBox2" Display="Dynamic" ValidationGroup="MyGroup" ToolTip="No Match">*</asp:CompareValidator>

ControlToCompare - This take the Id of control with which comparison is being done.
Comparison can be made on following data types: Currency, Date, Double, Integer and String

RangeValidator
As the name suggest this control is used to make sure that data entered by the user fall within the specified range. Again as for Compare validator validation will pass if input control is empty. Use RequiredFieldValidator to fix this issue.
<asp:TextBox ID="TextBox1" runat="server" ValidationGroup="MyGroup" />
<asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="txtTextBox1" MaximumValue="800"
MinimumValue="5" ValidationGroup="MyGroup" Display="Dynamic" Type="String" ToolTip="Error">*</asp:RangeValidator>

A little explanation for this validator. It has a Type attribute that signifies the datatype for Range. In above example datatype is string with MinimumValue="5" and MaximumValue="100". The validation goes like it will accept all the value that satisfy the regex ^[5-8]+$. A little confusing but will get clear after 2 3 reading.

RegularExpressionValidator
This is one of my favorite validator control. This control provide maximum level of flexibility to the developer and almost all the validator control function can be achieved using this validator control. RegularExpressionValidator control has attribute ValidationExpression that is used to specify the regular expression that is used to validate the input control.

<asp:TextBox ID="TextBox1" runat="server" ValidationGroup="MyGroup" />
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"  

ControlToValidate="txtTextBox1"
ValidationGroup="MyGroup" Display="Dynamic" ValidationExpression="^[5-8]+$" ToolTip="Error">*</asp:RegularExpressionValidator>

CustomValidator Control: Custom validator control is used to capture the validation that cannot be handled by the validator controls provided by ASP.NET. Here user is at the freedom to define his own custom method, both Client side and Server side. 
<asp:TextBox ID="TextBox1" runat="server" ValidationGroup="MyGroup" />
<asp:CustomValidator runat="server" ClientValidationFunction="YouClientValidationFunction" ControlToValidate="txtTextBox1" ID="cstmValidatorControl" OnServerValidate="ServerSideMethod" ValidateEmptyText="true" ToolTip="Error">*</asp:CustomValidator>

ValidateEmptyText  is a boolean attribute that if set to true, the input control will be validated even if it is empty.
ClientValidationFunction contains name of client validation function.
OnServerValidate contains name of server validation function.

ValidationSummary Control
This control is used to display the list of all the validation error that has occurred on the page. The error message displayed is the one set for the ErrorMessage attribute of the validation control. No error message will be displayed if this attribute is not set.  
<asp:TextBox ID="TextBox1" runat="server" ValidationGroup="MyGroup" />
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="txtTextBox1" ValidationGroup="MyGroup" Display="Dynamic" ValidationExpression="^[5-8]+$" ErrorMessage="Error" ToolTip="Error">*</asp:RegularExpressionValidator>

<asp:Button runat="server" ID="Button1" ValidationGroup="MyGroup" Text="Submit" />
<asp:ValidationSummary runat="server" ID="ValidationSummary1" ShowMessageBox="true" ValidationGroup="MyGroup" ShowSummary="true" DisplayMode="BulletList" />

DisplayMode has three options List, BulletList and SingleParagraph
ShowMessageBox when set to true will display the error as a alert popup
ShowSummary will display the error on the page. By default it is true.



Free Italy ASP.NET 4.5 Hosting - HostForLIFE.eu :: Programmatically Clearing The ASP.NET Cache For Web Forms and MVC Pages

clock April 16, 2014 06:01 by author Peter

Page level caching for ASP.NET 4.5 web forms and MVC websites is pretty awesome, because it allows you to implement something that's quite complex; multilevel caching, without having to really understand too much about caching, or even write much code. But what if you want to clear a cached ASP.net page before it's due to expire.

What page caching aims to achieve

When developers turn to caching pages in their ASP.net websites, usually it's because of one thing; the need for speed. When our code bases start to require continual requests to a data store, be it disk or database, that doesn't change too much overtime, caching is usually the first hammer we turn to to minimise fetching from slower stores. ASP.NET Web Forms and ASP.Net MVC both make this a pretty trivial thing to do by hiding the complexity of cache providers behind simple attributes to either your .aspx pages or controller actions:

WebForms page output caching example:

<%@ OutputCache Duration="300" VaryByParam="productId" %>
ASP.net MVC controller caching:
[OutputCache(Duration = 300, VaryByParam = "prodId")]
public ActionResult ProductDetails(string prodId)
{

}
}

The above is awesome because it's simplicity, but you'll notice one key thing here: I've set my cache expiry to 300 seconds. This is primarily because I want the content to pull from the source now and then just in case something has changed. I've used 300 seconds, but really the time may be inconsequential – I've just set it to an arbitrary number that I deemed would meet my needs.

This doesn't really use the cache as well as it could be used in many scenarios, the primary one being during a period where my site isn't being updated, and the content only changes once every few days/weeks/months. The .NET tooling attempts to allow for these situations by having support for providers like the SQLCacheDependency you can add to your application. But the SQL cache provider or even a CustomCacheProvider don't give you the fine grain control you really want: being able to programmatically remove page, control, action or child-action level cached pages. Like most great things: simple and elegant ASP.net does support this out of the box – you just don't hear about it much. You can tell the runtime to remove cached pages and controls simply by using a very simple recursive API that refers to it's relative URL.

// remove any webforms cached item with the wildcard default.aspx*
HttpResponse.RemoveOutputCacheItem("/default.aspx");
// just remove the webforms product page with the prodId=1234 param
HttpResponse.RemoveOutputCacheItem("/product.aspx?prodId=1234");
// remove my MVC controller action's output
HttpResponse.RemoveOutputCacheItem(Url.Action("details", "product", new { id = 1234 }));

You'll notice for the MVC page's cache reference I used the Url.Action helper, and I recommend this, as it uses the same MVC routing as the cache provider – usually taking the first route found. Using the Url.Action helper means your provided Url follows the same path in reverse to that of the cache provider. For MVC child actions there is currently no way that I know of clearing individual control's caches. MVC controller child actions are stored in the ChildActionCache. To clear the entire child action cache you can do the following:

OutputCacheAttribute.ChildActionCache = new MemoryCache("NewRandomStringNameToClearTheCache");

Obviously this is a pretty aggressive approach, but if you would like to do this in a more granular fashion, try the open source project MVC Doughnut caching instead.



FREE ASP.NET 4.5 Spain Hosting – HostForLIFE.eu :: GridView and Export to Excel

clock March 29, 2014 18:18 by author Peter

This is very simple to implement in ASP.NET 4.5 Hosting. But, there are possibilities to get problems in exporting to excel from grid view. When you bind data to gridview and write some logic to export to excel then it will not be enough. We have to check or write some additional logic which will help us to solve the problems. Below is the explanation for all problems we may get in the complete process along with detailed solution. You may encounter below errors when you try to implement the export to excel for gridview.

Control of type "GridView" must be placed inside of the form tag with runat="server"
This is very well known error to ASP.NET developers and by seeing it, we think that the control is not inside the form with runat server. But this is not correct. This error will come even if we put the GridView inside form with runat server. The reason is, in the export to excel logic we are calling RenderControl() method of GridView. So, to render it without any issues we have to override the "VerifyRenderingInServerForm" in our code.  Below is the syntax of the event. Add this to the c# code in code behind file. Remember this event is a Page event means this method you should place in ASPX page. If you are using user control to implement this export to excel logic then below are the ways to go.

1. If your user control is using by less than 3-4 pages then go to each and every page and add this event to the page.

2. If your user control is using by more than 5 pages then the best solution is to create a base page [Which inherits from System.Web.UI.Page class] and all your ASPX pages should inherit from this base page.public override void VerifyRenderingInServerForm(Control control)  

{  
    //Confirms that an HtmlForm control is rendered for the specified ASP.NET   
    //server control at run time. 
}  

Now, after we added the event to page, the error will go away for sure. Even when you add the above code/event to the page, this is not enough if you have the paging, sorting enabled on gridview. If you enable paging or sorting then you encounter the below error.

"RegisterForEventValidation can only be called during Render();"

This error is coming because we are doing paging and sorting. If no paging or sorting enabled this error will not come. To resolve this error, please follow below steps.

1. In your export to excel button click event, first disable the paging, sorting on gridview and do data bind.
2. Call export to excel logic.
3. Re-enable paging, sorting on gridview and databind.

Below is the logic we have to use in export to excel button click event.

gvReport.AllowPaging = false;  
    gvReport.AllowSorting = false;  
    gvReport.DataBind();  
    ExportToExcel();//Method to use export to excel.  
    gvReport.AllowPaging = true;  
    gvReport.AllowSorting = false;  
    gvReport.DataBind();   

Now, you are clear with all errors and the logic will export all data in gridview to excel.

FYI, I am placing a sample of ExportToExcel() functionality here.

private void ExportToExcel()  
    {  
        Response.Clear();  
        Response.AddHeader("content-disposition", string.Format("attachment;filename=excel_report.xls"));  
        Response.Charset = ""; 
        // Response.Cache.SetCacheability(HttpCacheability.NoCache);  
        Response.ContentType = "application/vnd.xls";  
        System.IO.StringWriter stringWrite = new System.IO.StringWriter();  
        System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);  
        gvReport.RenderControl(htmlWrite);  
        Response.Write(stringWrite.ToString());  
        Response.End();  
    } 

Note: gvReport is the gridview control name in my example. And there are lot of posts in internet guide you incorrect to resolve the above error. For example, they will say set EnableEventValidation="false" in the <%@ Page directive Or disable validation in web.config level to resolve the error. Please do not set it.



FREE ASP.NET 4.5 Hosting UK - HostForLIFE.eu :: How can HostForLIFE.eu Guarantee Our Windows ASP.NET 4.5 Hosting Service?

clock March 24, 2014 07:05 by author Scott

Only focusing on ASP.NET hosting service, HostForLIFE prove ourselves to be one of the best ASP.NET hosting providers that offer the most highlights, although there are thousands of ASP.NET hosting companies on the market. In below, we have listed our main features that has integrated with our 4 ASP.NET hosting plans.

Offering Many Excellent Features

- 1-Click Application Installer

In the HostForLIFE control panel, there is a 1-click web application installer for convenient installation of many popular open source web applications, including PHP apps like WordPress, Joomla, Drupal and phpBB, and ASP.NET applications like DotNetNuke, nopCommerce, BlogEngine and Orchard.

- PHP & MySQL

In the past, PHP didn't run well on a Windows server, but over the last several years, Microsoft has improved IIS and now PHP runs vey well on Windows hosting platforms, which means famous open source apps like Joomla, WordPress and Drupal can run well on HostForLIFE Windows hosting plans.

In addition, by supporting MySQL as part of their Windows hosting platform, a popular open source relational database system, HostForLIFE enables customers to use a lot of popular open source apps.

- ASP.NET 4.5.1 Hosting

We support ASP.NET 4.5.1 hosting on our Windows 2012 platform, which is compatible with Visual Studio 2013/2012, and our Windows 2008 hosting platform also fully supports ASP.NET 4.0 and is compatible with Visual Studio 2010, which enables customers' applications to be written in any language that is compatible with the common language runtime, including Visual Basic and C#.

- SQL Server

HostForLIFE always improve our technology and we always up to date with the Micorosoft technology. We offer the latest SQL 2012 version. We also support integrated full text search, stored procedures and ASP.NET SQL Session, which makes their customers get DBO right and manage SQL database remotely using SQL Management Studio or SQL Management Studio Express.

- Windows 2012 Hosting

We use Windows server 2012 – the latest Windows operating system comes with IIS8 to deliver customers with more options for their web applications including support for .NET, ASP and PHP. What's more, they support Full Trust to make customers' sites isolated from one another for greater reliability and security.

Utilizing Cutting-Edge Facilities & Infrastructures

HostForLIFE uses a state-of-the-art data enter which is featured with UPS backup power, diesel generators, firewall protection and 24×7 security. Moreover, we houses dual quad Dell servers that are 100% factory built and tested, coming with the best specification of 64 bit software, 32 GB of RAM, and RAID 10 disk arrays. All of the first-class facilities and infrastructures enable HostForLIFE to provide satisfying uptime and fast hosting speed for our customers to run websites smoothly and stably.

Providing Quality Technical Support

As one of the most reliable hosting companies, HostForLIFE offers quality technical support powered by a group of support staffs through email, all of who are professional, knowledgeable, experienced and on-site 24×7, so that we are able to give quick response and effective assistance to troubled customers to resolve problems.

In addition, in our online knowledgebase and blog, HostForLIFE technicians and engineers have worked out a lot of in-depth articles to teach customers how to deal with common issues independently.



European FREE ASP.NET 4.5 Hosting Germany - HostForLIFE.eu :: ASP.NET 4.5 Hosting With Full Trust Level

clock March 17, 2014 10:59 by author Scott

There are many different levels of web hosting services for us to choose nowadays, the common web hosting types are ASP.NET shared hosting, Windows VPS and Windows dedicated server. To most of individuals and small businesses, I think the price should be the first thing we’ve to care about, so the ASP.NET shared hosting service should be the most popular type.

What’s ASP.NET 4.5 shared hosting trust level?

You need to check many aspects before choosing a .Net hosting provider, those aspects should include .Net MVC framework, SQL Server, disk space, monthly bandwidth, hosting prices, but there’s one thing you may ignore really – “IIS Security Trust Level”.

If you’re not familiar with what’s asp.net 4.5 shared hosting trust level, here I’d like to bring you a short introduction. The trust level is real important that could affect with your site secure and performance, and a full trust level means higher risk for hackers sneak into server to make destroy. Most of small .Net hosts only can give medium trust level on their servers. If your applications need to be run a full trust mode, then you’ve to look for a web host which can give full permission to you.

<system.web>
<securityPolicy>
<trustLevel name="High" policyFile="web_hightrust.config"/>
<trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
<trustLevel name="Low" policyFile="web_lowtrust.config"/>
<trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
</securityPolicy>
</system.web>

You can see there are 4 trust levels for web hosts to pre-set by default – Minimal trust, Low trust, Medium trust and High / Full trust. High trust means higher risk for hackers to sneak into server, most of Windows hosting companies doesn’t allow their customers to run full trust level by default.

- Full Trust allows the users to do everything of application pool on one Windows web server. Some of applications cannot work properly under a medium trust web server, full trust means more flexible and you’re also able to change to medium trust once your application don’t need full trust.
- Medium Trust level websites are limited to access the file system and not so flexible as full trust level web server.
- Low Trust & Minimal Trust level are 2 options to restrict the users heavily, it won’t allow users to connect to server actively. At present, there’s no Windows hosts offering such asp.net shared hosting plan yet.

Who’s best ASP.NET 4.5 full trust web hosting?

I’ve to say that’s not easy to choose a best asp.net web hosting provider, since you’ve to check many aspects before making a decision, such as you should check:

1. How’s their server performance and reliability?
2. How much disk space and bandwidth can you receive?
3. How many MsSQL databases can you create?
4. Does it support IIS url-rewrite and isolated application pool?
5. How’s their technical support team?

and more..

Why you should choose HostForLIFE.eu for full trust ASP.NET hosting?

The reason is simple, HostForLIFE.eu web solutions started business since 2008 and we’ve been focusing on providing quality Microsoft Windows platform server over 6 years. We always the first web host to offer newest Microsoft technologies to their users. Whatever you need for your website, you can trust your site with us



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in