Как просматривать страницы списка в Razor

Разработка на C# под linux
 
Мне в репозитории https://github.com/ernado-x/X.PagedList понравился пример UnobtrusiveAjaxController.

Хотелось бы разобраться как он работает.

Во-первых, есть класс-контроллер:

    public class UnobtrusiveAjaxController : BaseController
    {
        // Unobtrusive Ajax
        public ActionResult Index(int? page)
        {
            var listPaged = GetPagedNames(page); // GetPagedNames is found in BaseController
            if (listPaged == null)
                return HttpNotFound();

            ViewBag.Names = listPaged;
            return Request.IsAjaxRequest()
                ? (ActionResult)PartialView("UnobtrusiveAjax_Partial")
                : View();
        }
    }

Тут есть переменная типа Dynamic, с которыми я раньше дела не имел.

[Dynamic]
public dynamic ViewBag {
    [return: Dynamic]
    get;
}

она из библиотеки Mvc, класса ControllerBase:
abstract class BaseController : Controller
abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer

https://msdn.microsoft.com/en-us/library/system.web.mvc.controllerbase.viewbag(v=vs.118).aspx
Gets the dynamic view data dictionary.
Type: System.Object
The dynamic view data dictionary.

Тут интересно почитать про использованный синтаксис с ключевым словом Dynamic
Про определение dynamic в спецификации языка, в каком году оно там появлось, что означает
и описание атрибута DynamicAttribute
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.dynamicattribute(v=vs.110).aspx
DynamicAttribute indicates that the use of Object on a member is meant to be treated as a dynamically dispatched type.
Namespace: System.Runtime.CompilerServices
Assembly: System.Core (in System.Core.dll)
.NET Framework: Available since 4.0

http://stackoverflow.com/questions/20150687/c-sharp-dlr-datatype-inference-with-dynamic-keyword
When you use dynamic, the entire expression is treated at compile time as a dynamic expression, which causes the compiler to treat everything as dynamic and get run-time binding.
This is explained in 7.2 of the C# Language specification:
When no dynamic expressions are involved, C# defaults to static binding, which means that the compile-time types of constituent expressions are used in the selection process. However, when one of the constituent expressions in the operations listed above is a dynamic expression, the operation is instead dynamically bound.
This basically means that most operations (the types are listed in section 7.2 of the spec) which have any element that is declared as dynamic will be evaluated as dynamic, and the result will be a dynamic.

неплохо бы выяснить, где сама спецификация, и что написано в пункте 7.2, вот как раз фраза из текста есть для поиска в гугле.

http://stackoverflow.com/questions/13467103/where-can-i-find-the-c-sharp-5-language-specification

.Names

То есть, Names - это переменная-член какого-то типа, который был положен во ViewBag

everthing that you put into a ViewBag will be reflected in the ViewData of the same Controller, so you can check ViewData (ie ViewData.Keys)

dynamics are internally dictionaries

https://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject(v=vs.110).aspx

In C#, to enable dynamic behavior for instances of classes derived from the DynamicObject class, you must use the dynamic keyword.

https://msdn.microsoft.com/en-us/library/dd264736(v=vs.110).aspx

https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Actions/DynamicObject.cs#L37

ViewData is a dictionary object that you put data into, which then becomes available to the view. ViewData is a derivative of the ViewDataDictionary class, so you can access by the familiar "key/value" syntax.
ViewBag object is a wrapper around the ViewData object that allows you to create dynamic properties for the ViewBag.

dynamic ViewBag = new System.Dynamic.ExpandoObject();
http://stackoverflow.com/questions/14896013/how-viewbag-in-asp-net-mvc-works/14985891#14985891
http://www.codeguru.com/csharp/article.php/c19053/Using-DynamicObject-and-ExpandoObject.htm

It implements "DynamicObject", so it can be used as a "dynamic" properly. Then in the lower it overrides the three dynamic object methods, in each they use the data from the provided ViewData.
They use a Func<ViewDataDictionary>, to always access the dictionary datad that is currently assigned to the property in the other class.
If they pass the VIewDataDictionary directly, then always that instance will be used, even when another instance was assigned to the ViewData property (not wanted)

return View();

Как работает return View(); ?

MVC tries to look for a view named "SomeControllerMethod.cshtml". It uses the name of the method as a guide for looking for a view file.

http://stackoverflow.com/questions/13883306/how-does-asp-net-mvc-determine-the-view-to-use-from-a-controller

RenderSection

http://www.dotnetcurry.com/showarticle.aspx?ID=636
это 2010-я студия, значит 5 лет назад

By default, ASP.NET will not serve pages beginning with an underscore.

Client certificates

https://github.com/NancyFx/Nancy/wiki/Accessing-the-client-certificate-when-using-SSL

covariance, сontravariance, invariance

Что такое covariance и сontravariance ? invariance
https://msdn.microsoft.com/en-us/library/ee207183.aspx

// Covariance.
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;

// Contravariance.
Action<object> actObject = SetObject;
Action<string> actString = actObject;

In .NET Framework 4, C# support covariance and contravariance in generic interfaces and delegates and allow for implicit conversion of generic type parameters.
You can declare variant generic interfaces by using the in and out keywords for generic type parameters.
If you have a contravariant generic delegate as a method parameter, you can use the type as a generic type parameter for the delegate.
It is also possible to support both covariance and contravariance in the same interface, but for different type parameters.
interface IMyInterface<out R, in A>

Classes that implement variant interfaces are invariant.
// The interface is covariant.
ICovariant<Button> ibutton = new SampleImplementation<Button>();
ICovariant<Object> iobj = ibutton;
// The class is invariant.
SampleImplementation<Button> button = new SampleImplementation<Button>();
// The following statement generates a compiler error
// because classes are invariant.
// SampleImplementation<Object> obj = button;
https://msdn.microsoft.com/en-us/library/dd997386.aspx

Где без этой ковариантности не обойтись и где она полезна, мне пока не ясно. То есть, я пишу мало кода на шаблонах, и не сталкивался с этим.