All About ASP.NET and ASP.NET Core 2 Hosting BLOG

Tutorial and Articles about ASP.NET and the latest ASP.NET Core

ASP.NET Core Hosting :: How to Handle Multipart Request with JSON and File Uploads in ASP.NET Core

clock May 15, 2019 09:29 by author Jervis

Suppose we’re writing an API for a blog. Our "create post" endpoint should receive the title, body, tags and an image to display at the top of the post. This raises a question: how do we send the image? There are at least 3 options:

Embed the image bytes as base64 in the JSON payload, e.g.

{
    "title": "My first blog post",
    "body": "This is going to be the best blog EVER!!!!",
    "tags": [ "first post", "hello" ],
    "image": "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
}

This works fine, but it’s probably not a very good idea to embed an arbitrarily long blob in JSON, because it could use a lot of memory if the image is very large.

Send the JSON and image as separate requests. Easy, but what if we want the image to be mandatory? There’s no guarantee that the client will send the image in a second request, so our post object will be in an invalid state.

Send the JSON and image as a multipart request.

The last approach seems the most appropriate; unfortunately it’s also the most difficult to support… There is no built-in support for this scenario in ASP.NET Core. There is some support for the multipart/form-data content type, though; for instance, we can bind a model to a multipart request body, like this:

public class MyRequestModel
{
    [Required]
    public string Title { get; set; }
    [Required]
    public string Body { get; set; }
    [Required]
    public IFormFile Image { get; set; }


public IActionResult Post([FromForm] MyRequestModel request)
{
    ...
}

But if we do this, it means that each property maps to a different part of the request; we’re completely giving up on JSON.

There’s also a MultipartReader class that we can use to manually decode the request, but it means we have to give up model binding and automatic model validation entirely.

Custom model binder

Ideally, we’d like to have a request model like this:

public class CreatePostRequestModel
{
    [Required]
    public string Title { get; set; }
    [Required]
    public string Body { get; set; }
    public string[] Tags { get; set; }
    [Required]
    public IFormFile Image { get; set; }
}

Where the TitleBody and Tags properties come from a form field containing JSON and the Image property comes from the uploaded file. In other words, the request would look like this:

POST /api/blog/post HTTP/1.1
Content-Type: multipart/form-data; boundary=AaB03x  

--AaB03x
Content-Disposition: form-data; name="json"
Content-Type: application/json  

{
    "title": "My first blog post",
    "body": "This is going to be the best blog EVER!!!!",
    "tags": [ "first post", "hello" ]
}
--AaB03x
Content-Disposition: form-data; name="image"; filename="image.jpg"
Content-Type: image/jpeg  

(... content of the image.jpg file ...)
--AaB03x

Fortunately, ASP.NET Core is very flexible, and we can actually make this work, by writing a custom model binder.

Here it is:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json; 

namespace TestMultipart.ModelBinding
{
    public class JsonWithFilesFormDataModelBinder : IModelBinder
    {
        private readonly IOptions<MvcJsonOptions> _jsonOptions;
        private readonly FormFileModelBinder _formFileModelBinder; 

        public JsonWithFilesFormDataModelBinder(IOptions<MvcJsonOptions> jsonOptions, ILoggerFactory loggerFactory)
        {
            _jsonOptions = jsonOptions;
            _formFileModelBinder = new FormFileModelBinder(loggerFactory);
        } 

        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext)); 

            // Retrieve the form part containing the JSON
            var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);
            if (valueResult == ValueProviderResult.None)
            {
                // The JSON was not found
                var message = bindingContext.ModelMetadata.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(bindingContext.FieldName);
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, message);
                return;
            } 

            var rawValue = valueResult.FirstValue; 

            // Deserialize the JSON
            var model = JsonConvert.DeserializeObject(rawValue, bindingContext.ModelType, _jsonOptions.Value.SerializerSettings); 

            // Now, bind each of the IFormFile properties from the other form parts
            foreach (var property in bindingContext.ModelMetadata.Properties)
            {
                if (property.ModelType != typeof(IFormFile))
                    continue; 

                var fieldName = property.BinderModelName ?? property.PropertyName;
                var modelName = fieldName;
                var propertyModel = property.PropertyGetter(bindingContext.Model);
                ModelBindingResult propertyResult;
                using (bindingContext.EnterNestedScope(property, fieldName, modelName, propertyModel))
                {
                    await _formFileModelBinder.BindModelAsync(bindingContext);
                    propertyResult = bindingContext.Result;
                } 

                if (propertyResult.IsModelSet)
                {
                    // The IFormFile was sucessfully bound, assign it to the corresponding property of the model
                    property.PropertySetter(model, propertyResult.Model);
                }
                else if (property.IsBindingRequired)
                {
                    var message = property.ModelBindingMessageProvider.MissingBindRequiredValueAccessor(fieldName);
                    bindingContext.ModelState.TryAddModelError(modelName, message);
                }
            } 

            // Set the successfully constructed model as the result of the model binding
            bindingContext.Result = ModelBindingResult.Success(model);
        }


    }
}

To use it, just apply this attribute to the CreatePostRequestModel class above:

[ModelBinder(typeof(JsonWithFilesFormDataModelBinder), Name = "json")]}
public class CreatePostRequestModel

This tells ASP.NET Core to use our custom model binder to bind this class. The Name = "json" part tells our binder from which field of the multipart request it should read the JSON (this is the bindingContext.FieldName in the binder code).

Now we just need to pass a CreatePostRequestModel to our controller action, and we’re done:

[HttpPost]
public ActionResult<Post> CreatePost(CreatePostRequestModel post)
{
    ...
}

This approach enables us to have a clean controller code and keep the benefits of model binding and validation. It messes up the Swagger/OpenAPI model though, but hey, you can’t have everything!



ASP.NET Core Hosting :: How to Send and Receive Email in ASP.NET Core Using Mailkit

clock February 18, 2019 07:36 by author Jervis

Creating An Email Service

It’s always good practice that when you add in a new library, that you build an abstraction on top of it. If we take MailKit as an example, what if MailKit is later superceded by a better emailing library? Will we have to change references all over our code to reference this new library? Or maybe MailKit has to make a breaking change between versions, will we then have to go through our code fixing all the now broken changes?

Another added bonus to creating an abstraction is that it allows us to map out how we want our service to look before we worry about implementation details. We can take a very high level view of sending an email for instance without having to worry about exactly how MailKit works. Because there is a lot of code to get through, I won’t do too much explaining at this point, we will just run through it. Let’s go!

First, let’s go ahead and create an EmailAddress class. This will have only two properties that describe an EmailAddress.

public class EmailAddress
{
                public string Name { get; set; }
                public string Address { get; set; }
}

Now we will need something to describe a simple EmailMessage. There are a tonne of properties on an email, for example attachments, CC, BCC, headers etc but we will break it down to the basics for now. Containing all of this within a class means that we can add extra properties as we need them later on.

public class EmailMessage
{
                public EmailMessage()
                {
                                ToAddresses = new List<EmailAddress>();
                                FromAddresses = new List<EmailAddress>();
               

                public List<EmailAddress> ToAddresses { get; set; }
                public List<EmailAddress> FromAddresses { get; set; }
                public string Subject { get; set; }
                public string Content { get; set; }
}

Now we need to setup our email configuration. That’s our SMTP servers, ports, credentials etc. For this we will make a simple settings class to hold all of this. Since we are good programmers we will use an interface too!

public interface IEmailConfiguration
{
                string SmtpServer { get; }
                int SmtpPort { get; }
                string SmtpUsername { get; set; }
                string SmtpPassword { get; set; } 

                string PopServer { get; }
                int PopPort { get; }
                string PopUsername { get; }
                string PopPassword { get; }


public class EmailConfiguration : IEmailConfiguration
{
                public string SmtpServer { get; set; }
                public int SmtpPort  { get; set; }
                public string SmtpUsername { get; set; }
                public string SmtpPassword { get; set; } 

                public string PopServer { get; set; }
                public int PopPort { get; set; }
                public string PopUsername { get; set; }
                public string PopPassword { get; set; }
}

Now we actually need to load this configuration into our app. In your appsettings.json, you need to add a section at the root for email settings. It should look something like this :

{
  "EmailConfiguration": {
    "SmtpServer": "smtp.myserver.com",
    "SmtpPort": 465,
    "SmtpUsername": "smtpusername",
    "SmtpPassword": "smtppassword", 

    "PopServer": "popserver",
    "PopPort": 995,
    "PopUsername": "popusername",
    "PopPassword" :  "poppassword"
  }
  ....Other settings here...
}

In the ConfigureServices method or your startup.cs, we can now pull out this configuration and load it into our app with a single line.

public void ConfigureServices(IServiceCollection services)
{
                services.AddMvc();

services.AddSingleton<IEmailConfiguration>(Configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>());
}

This allows us to inject our configuration class anywhere in our app.

The final piece of the puzzle is a simple email service that can be used to send and receive email. Let’s create an interface and an implementation that’s empty for now. The implementation should accept our settings object as a constructor.

public interface IEmailService
{
                void Send(EmailMessage emailMessage);
                List<EmailMessage> ReceiveEmail(int maxCount = 10);


public class EmailService : IEmailService
{
                private readonly IEmailConfiguration _emailConfiguration;

                public EmailService(IEmailConfiguration emailConfiguration)
                {
                                _emailConfiguration = emailConfiguration;
               

                public List<EmailMessage> ReceiveEmail(int maxCount = 10)
                {
                                throw new NotImplementedException();
               

                public void Send(EmailMessage emailMessage)
                {
                                throw new NotImplementedException();
                }
}

Head back to our ConfigureServices method of our startup.cs to add in a final line to inject in our EmailService everywhere.

public void ConfigureServices(IServiceCollection services)
{
                services.AddMvc();
services.AddSingleton<IEmailConfiguration>(Configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>());
                services.AddTransient<IEmailService, EmailService>();
}

Phew! And we are done. If at this point we decided MailKit isn’t for us, we still have an email service that can swap in and out libraries as it needs to, and our calling application doesn’t need to worry about what’s going on under the hood. That’s the beauty of abstracting a library away!

Getting Started With MailKit

Getting started with MailKit is as easy as installing a Nuget package. Simply run the following from your Package Manager Console :

Install-Package MailKit

And hey presto! You now have access to MailKit in your application

Sending Email via SMTP With MailKit

Let’s head back to our email service class and fill out the “Send” method with the actual code to send an email via MailKit. The code to do this is below :

public void Send(EmailMessage emailMessage)
{
                var message = new MimeMessage();
                message.To.AddRange(emailMessage.ToAddresses.Select(x => new MailboxAddress(x.Name, x.Address)));
                message.From.AddRange(emailMessage.FromAddresses.Select(x => new MailboxAddress(x.Name, x.Address))); 

                message.Subject = emailMessage.Subject;
                //We will say we are sending HTML. But there are options for plaintext etc.
                message.Body = new TextPart(TextFormat.Html)
                {
                                Text = emailMessage.Content
                }; 

                //Be careful that the SmtpClient class is the one from Mailkit not the framework!
                using (var emailClient = new SmtpClient())
                {
                                //The last parameter here is to use SSL (Which you should!)
                                emailClient.Connect(_emailConfiguration.SmtpServer, _emailConfiguration.SmtpPort, true); 

                                //Remove any OAuth functionality as we won't be using it.
                                emailClient.AuthenticationMechanisms.Remove("XOAUTH2"); 

                                emailClient.Authenticate(_emailConfiguration.SmtpUsername, _emailConfiguration.SmtpPassword); 

                                emailClient.Send(message);
                                emailClient.Disconnect(true);
                }                             

}

The comments should be pretty self explanatory, but let’s quickly run through it.

  • You can send clear text or HTML emails depending on the “TextFormat” you use when creating your message body
  • MailKit has named it’s Smtp class “SmtpClient” which is the same as the framework class. Be careful if you are using Resharper and the like that when you click “Add Reference” you are adding the correct reference.
  • You should choose to use SSL whenever available when connecting to the SMTP Server

Because we built out our EmailService, EmailMessage and EmailConfiguration classes earlier, they are all ready to be used immediately!

Receiving Email via POP With MailKit

And now the code to receive email via POP.

public List<EmailMessage> ReceiveEmail(int maxCount = 10)
{
                using (var emailClient = new Pop3Client())
                {
                                emailClient.Connect(_emailConfiguration.PopServer, _emailConfiguration.PopPort, true); 

                                emailClient.AuthenticationMechanisms.Remove("XOAUTH2"); 

                                emailClient.Authenticate(_emailConfiguration.PopUsername, _emailConfiguration.PopPassword); 

                                List<EmailMessage> emails = new List<EmailMessage>();
                                for(int i=0; i < emailClient.Count && i < maxCount; i++)
                                {
                                                var message = emailClient.GetMessage(i);
                                                var emailMessage = new EmailMessage
                                                {
                                                                Content = !string.IsNullOrEmpty(message.HtmlBody) ? message.HtmlBody : message.TextBody,
                                                                Subject = message.Subject
                                                };
                                                emailMessage.ToAddresses.AddRange(message.To.Select(x => (MailboxAddress)x).Select(x => new EmailAddress { Address = x.Address, Name = x.Name }));
                                                emailMessage.FromAddresses.AddRange(message.From.Select(x => (MailboxAddress)x).Select(x => new EmailAddress { Address = x.Address, Name = x.Name }));
                               

                                return emails;
                }
}

Again, all rather straight forward.

While we only retrieve a few basic details about the email message, the actual MailKit email object has a tonne of data you can inspect including headers, CC addresses, etc. Extend as you need to!



ASP.NET Hosting :: Alternative Localization for Asp.Net Core Applications

clock January 16, 2019 10:41 by author Jervis

Asp.Net Core Built-In Support

This is code fragment from official documentation how to localize content using built-in functionality.

App Content Localization

[Route("api/[controller]")]
public class AboutController : Controller
{
    private readonly IStringLocalizer<AboutController> _localizer;

    public AboutController(IStringLocalizer<AboutController> localizer)
    {
        _localizer = localizer;
    }

    [HttpGet]
    public string Get()
    {
        return _localizer["About Title"];
    }
}

And if you are working with Html content that shouldn't be escaped during rendering - you are using IHtmlLocalizerimplementation that returns LocalizedHtmlString instance.

public class BookController : Controller
{
    private readonly IHtmlLocalizer<BookController> _localizer;

    public BookController(IHtmlLocalizer<BookController> localizer)
    {
        _localizer = localizer;
    }

    public IActionResult Hello(string name)
    {
        ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];

        return View();
    }
}

View Localization

For the view localization - there is another injectable interface IViewLocalizer.

@inject IViewLocalizer Localizer

@{
    ViewData["Title"] = Localizer["About"];
}

Alternative: Strongly-Typed DbLocalizationProvider

Where is my problem with built-in providers? They all are "stringly-typed". You have to provide string as either key or translation of the resource. I'm somehow more confident strongly-typed approach where I can use "Find All Usages", "Rename" or do any other static code operation that's would not be entirely possible in built-in approach.

Over the time I've been busy developing alternative localization provider for Asp.Net and Episerver (it's brilliant content management system) platforms specifically.

Thought getting that over to Asp.Net Core should not be hard. And it wasn't. So here we are - DbLocalizationProviderfor Asp.Net Core.

Getting Started

There are couple of things to setup first, before you will be able to start using strongly-typed localization provider.

First, you need to install the package (it will pull down other dependencies also).

PM> Install-Package LocalizationProvider.AspNetCore

Second you need to setup/configure services.
In your Startup.cs class you need to stuff related to Mvc localization (to get required services into DI container - service collection).

And then services.AddDbLocalizationProvider(). You can pass in configuration settings class and setup provider's behavior.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization();

        services.AddMvc()
                .AddViewLocalization()
                .AddDataAnnotationsLocalization();

        services.AddDbLocalizationProvider(cfg =>
        {
            cfg...
        });
    }
}

After then you will need to make sure that you start using the provider:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        ...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ...

        app.UseDbLocalizationProvider();
    }
}

Using localization provider will make sure that resources are discovered and registered in the database (if this process will not be disabled via AddDbLocalizationProvider() method).

App Content Localization

Localizing application content via IStringLocalizer<T> is similar as that would be done for regular Asp.Net applications.

You have to define resource container type:

[LocalizedResource]
public class SampleResources
{
    public string PageHeader => "This is page header";
}

Then you can demand IStringLocalizer<T> is any place you need that one (f.ex. in controller):

public class HomeController : Controller
{
    private readonly IStringLocalizer<SampleResources> _localizer;

    public HomeController(IStringLocalizer<SampleResources> localizer)
    {
        _localizer = localizer;
    }

    public IActionResult Index()
    {
        var smth = _localizer.GetString(r => r.PageHeader);
        return View();
    }
}

As you can see - you are able to use nice strongly-typed access to the resource type: _localizer.GetString(r => r.PageHeader);.

Even if you demanded strongly-typed localizer with specified container type T, it's possible to use also general/shared static resources:

[LocalizedResource]
public class SampleResources
{
    public static string SomeCommonText => "Hello World!";
    public string PageHeader => "This is page header";
}

public class HomeController : Controller
{
    private readonly IStringLocalizer<SampleResources> _localizer;

    public HomeController(IStringLocalizer<SampleResources> localizer)
    {
        _localizer = localizer;
    }

    public IActionResult Index()
    {
        var smth = _localizer.GetString(() => SampleResources.SomeCommonText);
        return View();
    }
}

View Localization

Regarding the views, story here is exactly the same - all built-in approach is supported:

@model UserViewModel
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SampleResources> HtmlLocalizer

@Localizer.GetString(() => SampleResources.SomeCommonText)
@HtmlLocalizer.GetString(r => r.PageHeader)

Data Annotations

Supported. Sample:

[LocalizedModel]
public class UserViewModel
{
    [Display(Name = "User name:")]
    [Required(ErrorMessage = "Name of the user is required!")]
    public string UserName { get; set; }

    [Display(Name = "Password:")]
    [Required(ErrorMessage = "Password is kinda required :)")]
    public string Password { get; set; }
}

View.cshtml:

@model UserViewModel

<form asp-controller="Home" asp-action="Index" method="post">
    <div>
        <label asp-for="UserName"></label>
        <input asp-for="UserName"/>
        <span asp-validation-for="UserName"></span>
    </div>
    <div>
        <label asp-for="Password"></label>
        <input asp-for="Password" type="password"/>
        <span asp-validation-for="Password"></span>
    </div>
    ...
</form>

Localization in Libraries

You can either rely on IStringLocalizer implementation that's coming from Microsoft.Extensions.Localizationnamespace and demand that one in your injections:

using Microsoft.Extensions.Localization;
public class MyService
{
    public MyService(IStringLocalizer localizer)
    {
       ...
    }
}

Or you can also depend on LocalizationProvider class defined in DbLocalizationProvider namespace:

using DbLocalizationProvider;
public class MyService
{
    public MyService(LocalizationProvider provider)
    {
       ...
    }
}

Both of these types provide similar functionality in terms how to retrieve localized content.

Changing Culture

Sometimes you need to get translation for other language and not primary UI one.
This is possible either via built-in method:

@inject IHtmlLocalizer<SampleResources> Localizer

Localizer.WithCulture(new CultureInfo("no"))
         .GetString(() => SampleResources.SomeCommonText)

Or via additional extension method:

@inject IHtmlLocalizer<SampleResources> Localizer
Localizer.GetStringByCulture(() => SampleResources.SomeCommonText, new Culture("no"))

Stringly-Typed Localization

For backward compatibility or even if you wanna go hardcore and supply resource keys manually (for reasons) stingly-typed interface is also supported:

using Microsoft.Extensions.Localization;

public class MyService
{
    public MyService(IStringLocalizer localizer)
    {
       var header = localizer["MyProject.Resources.Header"];
    }
}

 



ASP.NET Hosting :: How to Setup URL Redirection

clock November 15, 2018 07:07 by author Jervis

We have so many clients asking about this issue. So, we decide to write this tutorial and hope this information can help other people too. In this review, we will write simple tutorial about how to setup http/https redirection in IIS.

There are lots of routing options accessible in ASP.NET but still it comes a time when you need to manipulate a URL and manipulating it outside a code comes handy. When this happens, the best you can do id to use IIS Rewrite Module. Transforming various URL’s out of code enables you to do various things including performing redirections for archive or transferred content without interfering with the code, you can easily implement SEO optimizations and tweaks quickly and easily without code and many more. Below is a collection of useful IIS rewrite rules that will help you understand IIS rewrites.

Useful IIS Rewrite Rules

Adding www Prefix

This is a basic rule that adds prefix “www” to any URL you need. This is a requirement for SEO.

Redirection from Domain 1 to Domain 2

This rule comes handy when you change the name of your site or may be when you need to catch and alias and direct it to your main site. If the new and the old URLs share some elements, then you could just use this rule to have the matching pattern together with the redirect target being.

HTTPS/HTTP Redirection

Redirecting users from HTTP to HTTPS is one of the reasons that you need to apply useful IIS rewrite rules. It can lead to conditional statements while looking for dev/test mode in your code. This rules allows you to handle the redirection without much statements which is tidier.

There is a pair of rules in this case each for one of the two ways. In both the rules, a check is performed to verify that the protocol used is http/https. The rules work on the same URL patterns or the similar lists of pages to match. For the redirect to HTTP, it is not about matching the pages; it is a reverse of the first rule and usually have a number of .NET/site paths that are excluded.

Setup Redirection Using IIS

Above steps is to setup URL redirection via your code. But, if you manage your own server, you can also setup redirection via IIS. The following is the steps

1. Download and install the “URL Rewrite” module.

2. Open the “IIS Manager” console and select the website you would like to apply the redirection to in the left-side menu:



3. Double-click on the “URL Rewrite” icon.

4. Click “Add Rule(s)” in the right-side menu.

5. Select “Blank Rule” in the “Inbound” section, then press “OK”:

6. Enter any rule name you wish.

7. In the “Match URL” section:

- Select “Matches the Pattern” in the “Requested URL” drop-down menu 
- Select “Regular Expressions” in the “Using” drop-down menu 
- Enter the following pattern in the “Match URL” section: “(.*)” 
- Check the “Ignore case” box

 

 

8. In the “Conditions” section, select “Match all” under the “Logical Grouping” drop-down menu and press “Add”.

9. In the prompted window:

- Enter “{HTTPS}” as a condition input 
- Select “Matches the Pattern” from the drop-down menu 
- Enter “^OFF$” as a pattern 
- Press “OK”

10. In the “Action” section, select “Redirect” as the action type and specify the following for “Redirect URL”:

https://{HTTP_HOST}/{R:1}

11. Check the “Append query string” box.

12.Select the Redirection Type of your choice. The whole “Action” section should look like this:

 

NOTE: There are 4 redirect types of the redirect rule that can be selected in that menu: 

- Permanent (301) – preferable type in this case, which tells clients that the content of the site is permanently moved to the HTTPS version. Good for SEO, as it brings all the traffic to your HTTPS website making a positive effect on its ranking in search engines. 
- Found (302) – should be used only if you moved the content of certain pages to a new place *temporarily*. This way the SEO traffic goes in favour of the previous content’s location. This option is generally not recommended for a HTTP/HTTPS redirect. 
- See Other (303) – specific redirect type for GET requests. Not recommended for HTTP/HTTPS. 
- Temporary (307) – HTTP/1.1 successor of 302 redirect type. Not recommended for HTTP/HTTPS.

13. Click on “Apply” on the right side of the “Actions” menu.

The redirect can be checked by accessing your site via http:// specified in the URL. To make sure that your browser displays not the cached version of your site, you can use anonymous mode of the browser.

The rule is created in IIS, but the site is still not redirected to https://

Normally, the redirection rule gets written into the web.config file located in the document root directory of your website. If the redirection does not work for some reason, make sure that web.config exists and check if it contains the appropriate rule.

To do this, follow these steps:

1. In the sites list of IIS, right-click on your site. Choose the “Explore” option:

 

2. “Explore” will open the document root directory of the site. Check if the web.config file is there.

3. The web.config file must have the following code block:

<configuration> 
<system.webServer> 
<rewrite> 
<rules> 
<rule name="HTTPS force" enabled="true" stopProcessing="true"> 
<match url="(.*)" /> 
<conditions> 
<add input="{HTTPS}" pattern="^OFF$" /> 
</conditions> 
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> 
</rule> 
</rules> 
</rewrite> 
</system.webServer> 
</configuration>

4. If the web.config file is missing, you can create a new .txt file, put the aforementioned code there, save and then rename the file to web.config.

 

 



ASP.NET 5 Hosting - ASPHostPortal :: SEO For ASP.NET Web Sites

clock December 16, 2015 00:36 by author Kenny

SEO For ASP.NET Web Sites

One of the main sources of audience for these internet applications are the Search Engines like Google, Bing, Yahoo etc. Hence, the end application should not only handle your business problems efficiently but also follow some simple rules so that it yields good results in internet arena. This article, will list some of the simple guidelines which you need to consider if your Asp.Net application is an internet site.

1.    Add descriptive and unique Page Title for every page

Every page in your website should have a unique and descriptive page title that can describe what the page offers. You can set the Page Title either declaratively or in the code behind file. Refer below,

In ASPX,

<%@ Page Language="C#" AutoEventWireup="true" Title="My Home Page"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

In code behind,

Page.Title = "My Home Page";

2.    Links should be hyperlinks, no linkbutton or javascript navigation for crawlable links

Make sure all your links in your page are hyperlinks. Search engines can crawl a page only if it is linked through a hyper link (anchor tag). Javascript navigations are not search engine friendly since search engines will not understand it.

3.    Use javascript navigation for site related pages that have no search values

Page rank is distributed across the links on your page. Some of the internal website pages like About us, disclaimer, Registration, login, contact us, user profile pages can be navigated through javascript so that the page rank are not distributed to them. Doing like this will make rest of the crawlable content links benefited.

4.    Add Meta Keyword and Description tag for every page

Add Meta keyword and Meta description tag with relevant contents. Search engines will use these tags to understand what the page offers. You can dynamically set the meta tags from codebehind file using the below code,

HtmlHead head = (HtmlHead)Page.Header;

 HtmlMeta metasearch1 = new HtmlMeta();

 HtmlMeta metasearch2 = new HtmlMeta();  

 metasearch1.Name = "descriptions";

 metasearch1.Content = "my personal site";

 head.Controls.Add(metasearch1);

 metasearch2.Name = "keywords";

 metasearch2.Content = "ASP.Net,C#,SQL";

 head.Controls.Add(metasearch2);

The above code will add the below Meta tags to output html.

<meta name="descriptions" content="my personal site" />

<meta name="keywords" content="ASP.Net,C#,SQL" />

In ASP.Net 4.0, Microsoft added 2 new properties on the Page directive (Page object) that lets you to define the Meta keywords and Description declaratively and dynamically from codebehind.

In ASPX,

<%@ Page Language="C#" AutoEventWireup="true" MetaKeywords="asp.net,C#" MetaDescription="This is an asp.net site that hosts asp.net tutorials" CodeFile="Default.aspx.cs" Inherits="_Default" %>

In codebehind,

protected void Page_Load(object sender, EventArgs e)

    {

        Page.MetaKeywords = "asp.net,C#";

        Page.MetaDescription = "This is an asp.net site that hosts asp.net tutorials.";

    }

The similar can thing can be achieved in previous versions of .Net Framework by using a custom BasePage class.

5.    Make descriptive urls

Make your website URL descriptive. URL’s that has lots of query string values, numeric ids are not descriptive. It will provide enough information what the page offers. For example, http://www.example.com/products.aspx?catid=C91E9918-BEC3-4DAA-A54B-0EC7E874245E is not descriptive as http://www.example.com/Windows-Hosting

Apart from other parameters, search engines will also consider the website url to match your page for a searched keyword.



ASP.NET SignalR Hosting - ASPHostPortal.com :: How to Send Notification using ASP.NET SignalR

clock September 4, 2014 12:00 by author Jervis

What is SignalR?

ASP.NET SignalR is a library for developing applications needing real-time communication. In such applications as soon as data is generated on the server or some interesting event happens on the server the client needs to be updated with the latest data. The traditional approach to achieve this functionality is to make Ajax calls to the server periodically. However, this approach has its own pitfalls. Another way is to use HTML5 Web Sockets or Server Sent Events (SSE) to perform real-time communication. However, both of these techniques work only on the browsers supporting HTML5. SignalR uses HTML5 Web Sockets if the target browser supports them, otherwise it falls back to other techniques. The best part is that - as a developer you need not know these internal implementation details. Additionally, SignalR makes connection management, grouping and authorization easy. You can work with the high level API exposed by SignalR in your web applications without worrying too much about the internals of the communication technique used.

You can use SignalR in variety of situations, some of them are listed below:

  • Chat applications where two or more end users chat with each other in real-time.
  • Broadcasting notifications or messages to all or selected clients.
  • Real-time gaming applications.
  • Social networking websites.
  • Discussion boards where admins or members can communicate to other admins or members.

Example

To illustrate how SignalR can be used in an ASP.NET application you will develop a web form application as shown below:

The web application consists of two simple web forms, viz. AdminForm.aspx and ClientForm.aspx. The former web form is supposed to be used by an administrator to send notifications to all the clients connected at a given point of time. The later web form displays the notifications sent from the administrator to the end user. The notifications are displayed in a balloon that disappears after 5 seconds.

Getting SignalR

In order to develop the above application you should first install the SignalR library. You can get SignalR in couple of ways. Firstly you can install it as a NuGet package. To do so, open Tools > Library Package Manager > Package Manager Console and then issue the following command:

install-package Microsoft.AspNet.SignalR

Not only easier, but the recommended way is to install Microsoft ASP.NET and Web Tools 2012.2. Doing so will add certain project item templates in the Add New Item dialog as shown below:

You can use these templates (more on that later) instead of manually creating the respective project items.

Developing the Admin Web Form

Now let's develop the admin web form first. Begin by creating a new blank ASP.NET web forms application. Then right click on the project in the Solution Explorer and select Add New Item. Then add a new SignalR Hub Class to the project. This creates a new class that inherits from Hub base class.

namespace SignalRDemo
{
    public class MyHub1 : Hub
    {
        public void Hello()
        {
            Clients.All.hello();
        }
    }
}

The Hub class resides in the Microsoft.AspNet.SignalR namespace. A hub class can have any number of developer defined methods. These methods can then be called from a client side script. SignalR hubs provide a higher level RPC framework for your application. Additionally, you will find certain script files under the Scripts folder.

In this example you need a method - SendNotifications() - inside the hub class as shown below:

public void SendNotifications(string message)
{
    Clients.All.receiveNotification(message);
}

As you can see, the SendNotifications() method accepts a string parameter. Inside, it uses the Clients.All property to access all of the clients currently connected with the server. The receiveNotification() is a client side callback function that you will write in your jQuery code later. This way a notification is broadcast to all the connected clients. How the clients make use of the message is governed by the receiveNotification() client side function.

Next, add a Global.asax file to your web application and write the following code in the Application_Start event handler.

protected void Application_Start(object sender, EventArgs e)
{
    RouteTable.Routes.MapHubs();
}

The MapHubs() method registers default routes for SignalR hubs.

Now, add a web form to the project and name it as AdminForm.aspx. Add the following markup in the web form:

<!DOCTYPE html>
<html>
<head>
    <title>Admin Form Sending Notifications</title> 

    <script src="/Scripts/jquery-1.8.2.min.js" ></script>
    <script src="/Scripts/jquery.signalR-1.0.0.js"></script>
    <script src="/signalr/hubs"></script> 

    <script type="text/javascript">
        $(function () {
            var proxy = $.connection.notificationHub;

            $("#button1").click(function () {
                proxy.server.sendNotifications($("#text1").val());
            });

            $.connection.hub.start();
        });
    </script> 

</head>
<body>
    <input id="text1" type="text" />
    <input id="button1" type="button" value="Send" />
</body>
</html>

The AdminForm.aspx refers SignalR script files in the head section. Notice the code marked in the bold letters. First a variable named proxy is declared to hold a reference to a proxy of the remote hub class (NotificationHub). Make sure that the client side code uses camel casing in naming conventions. For example, NotificationHub is referred as notificationHub in the client code.

Next, the click event handler of the button is wired to a function. The client event handler calls the sendNotifications() method on the proxy object and passes the notification message entered in the textbox (see earlier figure to know what the admin form looks like).

Finally, the start() method of the hub is called to start the connection.

Developing the Client Web Form

Now that you have completed AdminForm.aspx let's develop the client web form. Add another web form to the project and name it ClientForm.aspx. Key-in the following markup in the web form:

<!DOCTYPE html>
<html>
<head>
    <title>Client Form Receiving Notifications</title>
    <script src="/Scripts/jquery-1.8.2.min.js" ></script>
    <script src="/Scripts/jquery.signalR-1.0.0.js"></script>
    <script src="/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            var proxy = $.connection.notificationHub;

            proxy.client.receiveNotification = function (message) {
                $("#container").html(message);
                $("#container").slideDown(2000);
                setTimeout('$("#container").slideUp(2000);', 5000);
            };

            $.connection.hub.start();
        });
    </script>
</head>
<body>
    <div class="notificationBalloon" id="container">
    </div>
</body>
</html>

The client code also declares a variable to hold a reference to the proxy hub object. It then wires a callback function receiveNotification (recollect that you used this name in the server side NotificationHub class). The receiveNotification() function receives the notification message sent by the server and displays it to the user after animating it using slideDown() and slideUp() jQuery functions. The notification message is automatically discarded after 5 seconds using the setTimeout() JavaScript function.

Finally, a connection is started by calling the start() method on the hub.

That's it! Run the AdminForm.aspx and load ClientForm.aspx in two or three browser windows or tabs. Now enter some message in the textbox from AdminForm.aspx and click on the Send button. All the browser windows showing ClientForm.aspx should show the notification message.

Summary

SignalR is a library that allows ASP.NET applications to perform real-time communication. If the target browser supports HTML5 SignalR uses Web Sockets otherwise fallback techniques are used. Additionally, SignalR provides an easy way for connection management, connection grouping and security for the communication. This article demonstrated a basic use of SignalR to send notifications to all the connected clients in real-time.



ASP.NET 4.5.1 Hosting:: How to Integrate Your ASP.NET Apps in Facebook

clock May 12, 2014 11:27 by author Ben

In this article I’m going to explain how to integrate ASP.NET applications in facebook.
Facebook has provided functionality that extends the Facebook Platform to any website that wants to integrate Facebook APIs for user authentication, sharing website content with friends, and publishing feed stories to generate traffic.
Here I’ll show you how to integrate ASP.NET Apps in Facebook.  Please follow the steps given below.

Setting up Facebook App

  • To create facebook app click on Developer section
  • Click on Set up New App button.
  • Agree Facebook terms and click on Create App
  • Put Security Check keywords.
  • Click on Submit.
  • Fill basic information about app



  • Click on Facebook Integration tab.
  • Put Name of Canvas page.
  • Before putting URL of webpage of your website, I want to show how your page can get callback from facebook app. So first we create webpage in our website:
  • Create asp.net website in Visual studio.
  • Add reference of Facebook.dll from “C:\Program Files\Coding4Fun\Facebook\Binaries”. This dll will be placed after installing Facebook Developer kit on your machine.
  • Create instance of FacebookService object. you can copy facebook app api key and secret key from application page on facebook in source code.



put above values in FACEBOOK_API_KEY and FACEBOOK_SECRET constants respectively.
you can get user_id of facebook who requested this application by calling
string userId = Session["Facebook_userId"] as String;

you can also get many information about user like name, sex, location,friends etc.
User usr=_fbService.GetUserInfo();



Source Code:

using System;
using Facebook;
public partial class Facebook_ConnectFacebook : System.Web.UI.Page
{
    Facebook.Components.FacebookService _fbService = new Facebook.Components.FacebookService();
    private const string FACEBOOK_API_KEY = "191856207506775";
    private const string FACEBOOK_SECRET = "820c0b05b14a09365e072c8d37a8c49f";

    protected void Page_Load(object sender, EventArgs e)
    {
        _fbService.ApplicationKey = FACEBOOK_API_KEY; _fbService.Secret = FACEBOOK_SECRET;
        _fbService.IsDesktopApplication = false;
        string sessionKey = Session["Facebook_session_key"] as String;
        string userId = Session["Facebook_userId"] as String;
       
    // When the user uses the Facebook login page, the redirect back here
    // will will have the auth_token in the query params
       
    string authToken = Request.QueryString["auth_token"];
       
    // We have already established a session on behalf of this user
        if (!String.IsNullOrEmpty(sessionKey))
        {
            _fbService.SessionKey = sessionKey; _fbService.UserId = userId;
        }
        // This will be executed when Facebook login redirects to our page        
        else if (!String.IsNullOrEmpty(authToken))
        {
            _fbService.CreateSession(authToken);
            Session["Facebook_session_key"] = _fbService.SessionKey;
            Session["Facebook_userId"] = _fbService.UserId;
            Session["Facebook_session_expires"] = _fbService.SessionExpires;
        }
        // Need to login        
        else
        {
            Response.Redirect(@"http://www.Facebook.com/login.php?api_key=" + _fbService.ApplicationKey + @"&v=1.0\");
        }

        User usr = _fbService.GetUserInfo();
        string t = string.Format("User Name:{0}, Sex:{1}, Location: {2}", usr.Name, usr.Sex, usr.CurrentLocation.City);
        Response.Write(t);
    }
}


Best and Recommended ASP.NET 4.5.1 Hosting Solution

The next version of the .NET Framework is .NET 4.5.1. It has been published as Preview version as announced yesterday during the BUILD conference. The new update builds on top of .NET 4.5 and includes new features such as async-aware debugging, ADO.NET idle connection resiliency, and ASP.NET app suspension. ASPHostPortal.com, a leading innovator in Windows Server hosting, announces a Free Trial ASP.NET 4.5.1 hosting on Windows Server 2012 R2 for the developer community.




ASP.NET Hosting Singapore (ASIA) - ASPHostPortal.com :: How to use Bootstrap is ASP.NET?

clock April 30, 2014 05:58 by author Ben

Designers need a solid foundation that gives us almost everything a typical website would require but is flexible enough for customization. Thanks to hundreds of hours spent by some developers and companies, we now have dozens of CSS Frameworks to choose from. Among all the available CSS frameworks out there, Bootstrap is my favorite and also one of the most widely used.

Bootstrap is the new technology that is integrated with the ASP.NET web project templates. It is builtin with the projects that provides responsive design and theming capabilities. Bootstrap is a sleek and powerful front-end framework for faster web development. The project templates based on bootstrap technology provides attractive themes for the web development. Bootstrap is front-end framework for easy and faster web development. This post explains how to use Bootstrap in  ASP.NET applications and outlines some of the features of this framework. Create a new ASP.NET project in Visual Studio 2013 and execute it then you will see the look and feel of the page as below.



If you want to get the above look without using Bootstrap then you have to write lot of custom CSS. Now all ASP.NET default templates like MVC, Web forms, Single Page applications and Web API are using Bootstrap framework. Bootstrap version 3 is integrated in Visual Studio 2013. The above screen scales well on different devices. If you look at the CSS code to achieve is very few lines as shown below



In order to get the Bootstrap into your project, go to Manage NuGet packages window and type Bootstrap in search box then you will find the package


Once you install the package then it brings the following files into your project, All the CSS and JavaScript files related Bootstrap framework are bundled for you to get you better performance.



Another integration feature for Bootstrap is Bootswatch, which helps you to theme your site. To apply theme to your site go to Bootswatch site and choose the theme which you like and download and copy the CSS and overwrite the  Bootstrap.css in your project. After applying one of the sample free theme then the site looks as below, In matter of seconds you can quickly change the theme of your site.

Another key feature of Bootstrap is dealing with the images, it makes the image experience as responsive without writing any code! just use the class name img-responsive.


It adds the responsive behaviour to the image and it make sure to render nicely in your site.

Reasons to trust your ASP.NET website to us

  • Server and performance - We're proud to host all of our sites in Amsterdams, USA and Singapore. We use special server technology on our web servers to offer the fastest loading time for your websites. Stable, Secure and Reliable ASP.NET hosting service.
  • 24/7-based Support - We never fall asleep and we run a service that is operating 24/7 a year. Even everyone is on holiday during Easter or Christmas/New Year, we are always behind our desk serving our customers.
  • Excellent Uptime Rate - Our key strength in delivering the service to you is to maintain our server uptime rate. We never ever happy to see your site goes down and we truly understand that it will hurt your onlines business. If your service is down, it will certainly become our pain and we will certainly look for the right pill to kill the pain ASAP.
  • High Performance and Reliable Server - We never ever overload our server with tons of clients. We always load balance our server to make sure we can deliver an excellent service, coupling with the high performance and reliable server.
  • Experts in ASP.NET Hosting - Given the scale of our environment, we have recruited and developed some of the best talent in the hosting technology that you are using. Our team is strong because of the experience and talents of the individuals who make up ASPHostPortal.com.
  • Daily Backup Service - We realise that your website is very important to your business and hence, we never ever forget to create a daily backup. Your database and website are backup every night into a permanent remote tape drive to ensure that they are always safe and secure. The backup is always ready and available anytime you need it.

About ASPHostPortal.com:

ASPHostPortal.com is a hosting company that best support in Windows and ASP.NET-based hosting. Services include shared hosting, reseller hosting, and sharepoint hosting, with specialty in ASP.NET, SQL Server, and architecting highly scalable solutions. As a leading small to mid-sized business web hosting provider, ASPHostPortal.com strive to offer the most technologically advanced hosting solutions available to all customers across the world. Security, reliability, and performance are at the core of hosting operations to ensure each site and/or application hosted is highly secured and performs at optimum level.



Cheap ASP.NET 4.5 Hosting

We’re a company that works differently to most. Value is what we output and help our customers achieve, not how much money we put in the bank. It’s not because we are altruistic. It’s based on an even simpler principle. "Do good things, and good things will come to you".

Success for us is something that is continually experienced, not something that is reached. For us it is all about the experience – more than the journey. Life is a continual experience. We see the Internet as being an incredible amplifier to the experience of life for all of us. It can help humanity come together to explode in knowledge exploration and discussion. It is continual enlightenment of new ideas, experiences, and passions


Author Link

 photo ahp banner aspnet-01_zps87l92lcl.png

 

Corporate Address (Location)

ASPHostPortal
170 W 56th Street, Suite 121
New York, NY 10019
United States

Tag cloud

Sign in