quarta-feira, 18 de junho de 2014

CheckBoxList no MVC

Criei uma classe e um HTML para fazer um CheckBoxList no MVC. Coloquei na minha biblioteca, a Ak, que está no bitbucket.

A classe:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Ak.MVC.Forms
{
    /// <summary>
    /// To create a CheckBoxList in Form
    /// </summary>
    public class CheckBoxList
    {
        /// <summary>
        /// Items of CheckBoxList
        /// </summary>
        public IEnumerable<CheckBoxItem> Items { get; set; }

        /// <summary>
        /// Constructor for MVC build
        /// </summary>
        public CheckBoxList()
        {
            Items = new List<CheckBoxItem>();
        }

        /// <summary>
        /// Constructor to use in your code
        /// </summary>
        /// <param name="all">All the items to show</param>
        /// <param name="chosen">Just the chosen items IDs</param>
        public CheckBoxList(IEnumerable<IListable> all, IEnumerable<Int32> chosen)
            : this()
        {
            Items = all.Select(e => add(e, chosen));
        }

        private static CheckBoxItem add(IListable item, IEnumerable<Int32> chosen)
        {
            return new CheckBoxItem
            {
                ID = item.ID,
                Name = item.Name,
                Chosen = chosen.Contains(item.ID),
            };
        }

        /// <summary>
        /// Get the chosen ids
        /// </summary>
        public IEnumerable<Int32> GetChosen()
        {
            return Items.Where(cbi => cbi.Chosen).Select(cbi => cbi.ID);
        }


        /// <summary>
        /// Item for CheckBoxList
        /// </summary>
        public class CheckBoxItem
        {
            // ReSharper disable CSharpWarnings::CS1591
            public Int32 ID { get; set; }
            public String Name { get; set; }
            public Boolean Chosen { get; set; }
            // ReSharper restore CSharpWarnings::CS1591
        }

    }
}


O HTML (colar em Views/Shared/EditorTemplates/CheckboxList.cshtml)
@model Ak.MVC.Forms.CheckBoxList

<ul>
    @for (var e = 0; e < Model.Items.Count; e++)
    {
        <li>
            @Html.CheckBoxFor(m => m.Items[e].Chosen)
            @Html.HiddenFor(m => m.Items[e].ID)
            @Html.LabelFor(m => m.Items[e].Chosen, Model.Items[e].Name)
        </li>
    }
</ul>




quinta-feira, 5 de junho de 2014

Connection Refused: tentando ver seu site em outros computadores da rede

Eu estava tentando acessar meu site pela rede. É um site local, configurado no IIS, e eu estava tentando acessar o site pelo IP dele. O motivo do post é porque eu já tinha tido esse problema diversas vezes e, todas elas, desistido de descobrir como resolver.

Pelo browser do celular, ele retornava como se o site não estivesse no ar. Porém, tentando fazer uma chamada pelo android, eu obtia a resposta Connection Refused.

A solução na verdade é bem simples:
Control Panel > Windows Firewall > Advanced Settings (menu lateral) > Inbound Rules

Ali, no final da lista (se estiver ordenada por nome), você encontra dois itens World Wide Web Services. Não fique brigando por mais meia hora como eu e habilite o item certo: um é para HTTP, o outro para HTTPS -- a coluna Name, se você não esticá-la, pode cortar essa informação.



Licença do app android

Recentemente eu coloquei um app na Google Play. Quando fui implementar a licença nele, tive um problema: eu não conseguia, de forma nenhuma, ter a resposta de licença que configurava no Google Play (é possível configurar, para contas de teste).

Fiquei horas mexendo nisso e acabei desistindo. No dia seguinte, alguém que conhecia android me respondeu: o problema é que, para eu ter essa resposta, mesmo que o app esteja em Alpha ou Beta, é necessário que ele esteja publicado.

A resposta que eu recebia, ao invés da que estava configurada, era ERROR_NOT_MARKET_MANAGED. Isso ocorre na classe que você implementou a partir de LicenseCheckerCallback, o método applicationError é chamado e errorCode vem com o valor 3.

quarta-feira, 4 de junho de 2014

Webform com referência a código buildado

Hoje eu fiquei umas 2 ou 3 horas tentando descobrir porque minha página simplesmente se recusava a aceitar que uma classe que eu criei existia. O erro que dava era no arquivo designer:

The type or namespace name MyClass does not exist in the namespace MyProject (are you missing an assembly reference?)

No web.config:
    <system.web>
        <pages>
            <controls>
                <add tagPrefix="tag" namespace="MyProject" />
            </controls>
        </pages>
    </system.web>

Na página:
         <tag:MyClass ID="MyControl" runat="Server" />

No designer (gerado pelo Visual Studio):
         /// <summary>
        /// controle MyControl.
        /// </summary>
        /// <remarks>
        /// Auto-generated field.
        /// To modify move field declaration from designer file to code-behind file.
        /// </remarks>
        protected global::MyProject:MyClass MyControl;

A classe:
        public class MyClass : Control
        {
                (código fonte)
        }

Tudo no lugar, certo? Foi o que pensei. Então pedi ajuda para alguém que realmente conhece WebForms. Descobri que eu tinha, por acidente, deixado o arquivo MyClass como Content no projeto, quando deveria estar como Compile.

Clique na class, aperte F4, na tela de Properties vá em Build Action e coloque Compile. Pronto. Agora funciona.