Tuesday, 22 April 2014

Prevent displaying Log In page in partial view on ajax request after session expired in ASP.NET MVC

If you are using partial views with many ajax request, there might be a situation in which user session expires and if you will try to submit form asynchronously via ajax  Log in page will be displayed in partial view(this will occur if you are using authorize attribute on the method you are calling).

Add this method to global.asax.cs file.

 // To use for ajax request when user session expired

protected void Application_EndRequest()
        {
            var context = new HttpContextWrapper(Context);
            // If we're an ajax request, and doing a 302, then we actually need to do a 401
            if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
            {
                Context.Response.Clear();
                Context.Response.StatusCode = 401;
            }
        }
In main.js file or script section on your main view(cshtml file if using Razor) add this:
var  $document = $(document);

handleAjaxError = function (XMLHttpRequest, textStatus, errorThrown) {
    if (XMLHttpRequest.status == 401) {
        //refresh the page, as we are not longer authorized
        location.reload();
    }
    };
 
Since we already lost session, we want to refresh the page and user will be redirect automatically to Log in page, rather than displaying Log in page in small partial view.

    $document.ajaxComplete(function(event, XMLHttpRequest, AjaxOptions){
        handleAjaxError(XMLHttpRequest);
    }); 

http://api.jquery.com/ajaxComplete/ - More on ajax Complete method

http://stackoverflow.com/questions/3431343/asp-net-mvc-forces-an-ajax-request-be-redirected-to-the-login-page-when-the-form - Inspired by this post

Tuesday, 1 April 2014

Google adsense April Fools joke

After I logged in today to see if google made any April fools joke I discovered one on Ad sense earning page. Regions have been replaced by planets and moons. It might be quite funny at the moment, but in next 30-100 years it might be real.

Saturday, 15 March 2014

Submitting form with partial view in ASP.NET MVC

In this tutorial we want to submit form with partial model.

Download full project here

We are going to have ClientVM that will have partial view with Address model. 
Create new MVC 4 project, choose internet project and Razor.

Create models that we will use in this project.

Models
public class Client
    {
        public Client()
        { 
        }

        public Client(string firstName, string lastName, Guid addressId)
        {
            this.address = new Address();
            this.clientId = Guid.NewGuid();
            this.firstName = firstName;
            this.lastName = lastName;
            this.addressId = addressId;
        }

        public Guid clientId { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
        public Guid addressId { get; set; }
        public virtual Address address { get; set; }
    }

public class Address
{
    public Address()
    { 

    }

    public Address(string houseNumber, string streetName)
    {
    this.addressId = Guid.NewGuid();
    this.houseNumber = houseNumber;
    this.streetName = streetName;
    }

    public Guid addressId { get; set; }
    public string houseNumber { get; set; }
    public string streetName { get; set; }
}

View Models

 public class ClientVM
    {
        public ClientVM()
        { 
            
        }

        public ClientVM(Client client, Address address)
        {
            this.clientId = Guid.NewGuid();
            this.firstName = client.firstName;
            this.lastName = client.lastName;
            this.addressId = client.addressId;
            this.addressPartial = address;
        }

        public Guid clientId { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
        public Guid addressId { get; set; }
        public Address addressPartial { get; set; }

    }


In Home controller we will create ActionResult ClientInfo

public ActionResult ClientInfo()
        {
            // Normally we would get Client from database. For test we use constructors to define new     entries.

            Address address = new Address("25 A", "London street");
            Client client = new Client("Adam", "Bielecki", address.addressId);

            ClientVM viewModel = new ClientVM(client, address);

            return View(viewModel);
        }

and the same method to submit the form:

[HttpPost]
        public ActionResult ClientInfo(ClientVM viewModel)
        {
            return View(viewModel);
        }

In _Layout_cs change 2nd link for menu.

<li>@Html.ActionLink("Submit Partial Model", "ClientInfo", "Home")</li>

so menu tabs should look like that:

<ul id="menu">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("Submit Partial Model", "ClientInfo", "Home")</li>
                            <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                        </ul>

Now we have to create 1 view for ClientInfo and 1 partial view for Address.
Compile your project (Shift+Ctrl+B), right click ClientInfo in Home Controller and Add View.

Check Create a strongly-type view, choose ClientVM and scaffold template : Edit.





Right click on shared folder add view and call it _Address. Use the same setting as before, but this time select Address as your model class and check box "Create as a partial view".

Remove form from _Address partial view so it should like that:



@model PartialViewModelSubmission.Models.Address

<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

<h2>Address</h2>

    <fieldset>
        <legend>Address</legend>

        @Html.HiddenFor(model => model.addressId)

        <div class="editor-label">
            @Html.LabelFor(model => model.houseNumber)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.houseNumber)
            @Html.ValidationMessageFor(model => model.houseNumber)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.streetName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.streetName)
            @Html.ValidationMessageFor(model => model.streetName)
        </div>

      
    </fieldset>


Run the application, click Submit Partial Model and submit the form. 
As you can see we get error as Address have not been submitted.



 The reason why it is happening is due to binding issue. Let's fix it.

We will have to create partial class for Address. In Address.cs add this partial class:


public partial class AddressBase
{
   public virtual Address partialAddress { get; set; } 
}

Using virtual type we are going to lazy load Address.

 Modify ClientVM so it looks like that:




public class ClientVM : AddressBase
    {
        public ClientVM()
        { 
            
        }

        public ClientVM(Client client, Address address)
        {
            this.clientId = Guid.NewGuid();
            this.firstName = client.firstName;
            this.lastName = client.lastName;
            //this.addressId = client.addressId;
            //this.addressPartial = address;
            this.partialAddress = address;
            
        }

        public Guid clientId { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
        // public Guid addressId { get; set; }
        // public Address addressPartial { get; set; }
    
}

ClientVM inherit from AddressBase partial class so we can assign address to base.
            this.partialAddress = address;

This is all you have to do for classes, we have to amend views a bit as well.

In ClientInfo we are going to pass ClientVM model to address so change it to :
@Html.Partial("_Address", Model)

In _Address view change model to AddressBase and update scaffolding so it should look like that:

@model PartialViewModelSubmission.Models.AddressBase

<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

<h2>Address</h2>

    <fieldset>
        <legend>Address</legend>

        @Html.HiddenFor(model => model.partialAddress.addressId)

        <div class="editor-label">
            @Html.LabelFor(model => model.partialAddress.houseNumber)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.partialAddress.houseNumber)
            @Html.ValidationMessageFor(model => model.partialAddress.houseNumber)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.partialAddress.streetName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.partialAddress.streetName)
            @Html.ValidationMessageFor(model => model.partialAddress.streetName)
        </div>

      
    </fieldset>
Now run the application again and if you followed everything correctly you should be able to see Address model when you debug.








Sunday, 9 March 2014

How to hide querystring parameter name from an URL generated with Html.ActionLink in ASP.NET MVC

 In View we are going to create link using Html helper :
@Html.ActionLink("Address", "ViewAddress", new { addressId = Guid.NewGuid() })
that will give us :

http://localhost:100/Home/ViewAddress?addressId=5f89a656-e98c-4680-b98f-6a3cf4ede7aa

We want to hide query string addressId and have only :

 http://localhost:100/Home/ViewAddress/5f89a656-e98c-4680-b98f-6a3cf4ede7aa

The solution is to add new map route.

Open RouteConfig.cs file from App_Start folder and add new Map Route:
routes.MapRoute("ListingPreview", "Home/ViewAddress/{addressId}",
                new
                {
                    controller = "Home",
                    action = "ViewAddress",
                    addressId= UrlParameter.Optional
                }
                );

Sunday, 23 February 2014

Setting up Unity3d webplayer on ASP.NET hosting

So I have some issues when I tried to upload web player version of one of my projects to ASP.NET server - arvixe.
After I uploaded webplayer version (html file and unity3d file) I was able to see unity 3d webplayer but nothing was loading. The solution is to add mime type(in my case I was able to do it via cpanel, if you do not have an access it is good to ask admin to do it for you).


The MIME type for Unity webplayer is:
    1. application/vnd.unity
And the file extension for unity webplayer files is:
    1. .unity3d

That fixed the issue for me and I was able to load my project on web.

Monday, 10 February 2014

Project Solar System in Unity 3d - update #1

I have been working recently on project Solar System. The idea is to allow user to view every planet in our solar system, zoom in out, rotate find the distance between planets, difference in mass etc.
I found maps from all the planets and unwrap it on sphere so it represents exact surface of each planet, at least solid once. Jupiter which is gas planet have correct map as well, however Uranus and Neptun won't have detailed map as they are vague. First screenshot - please ignore logic around how the planets are placed, it is just first showcase. In next release I will make sure good ratio is provided.
Any feedback, comments and suggestions are really appreciated.

Available now on Unity 3d store : UNITY 3D