JAVIER MARTINEZ

Web Developer

Etiqueta: DotNet

Projection y Query (Orchard CMS)

El módulo Projector de Orchard CMS nos permite crear instancias de Query y Projection, consultas de datos y páginas que muestran el resultado de estas.

En este artículo crearemos una consulta que devuelva todos nuestros productos y una página que muestre el listado de estos. Suponemos que inicialmente en nuestro proyecto ya existen diferentes Content Types que tienen asociado un ProductPart.

public class ProductPart : ContentPart<ProductPartRecord>
{
  public string SerialNumber
  {
    get { return Retrieve(r => r.SerialNumber); }
    set { Store(r => r.SerialNumber, value); }
  }

  public decimal Price
  {
    get { return Retrieve(r => r.Price); }
    set { Store(r => r.Price, value); }
  }
}

public class ProductPartRecord : ContentPartRecord
{
  public virtual string SerialNumber { get; set; }
  public virtual decimal Price { get; set; }
}

Query

Necesitamos una Query que devuelva todos los elementos cuyo tipo de contenido contenga un ProductPart adjunto. En el framework no tenemos un filtro que permita esta funcionalidad, así que creamos una nueva clase que herede de IFilterProvider:

public class ProductPartFilter : IFilterProvider
{
  public void Describe(DescribeFilterContext describe)
  {
    describe.For("Content","Content","Content")
        .Element("ProductPartFilter", "ProductPartFilter", "ProductPartFilter", ApplyFilter, DisplayFilter);
  }

  private void ApplyFilter(FilterContext context)
  {
    context.Query = context.Query.Join(x => x.ContentPartRecord(typeof(ProductPartRecord)));
  }
}

Ahora ya podemos añadir la nueva Query desde la interfaz web de administración asignándole el título “Productos”. La editamos y hacemos clic en “Add a new Filter” para seleccionar el filtro que hemos creado anteriormente.

Es posible que por alguna razón específica de nuestro proyecto necesitemos realizar lo mismo programando directamente, en este caso podemos utilizar el siguiente código:

string name = "Productos";
string type = "ProductPartFilter";

QueryPart query = _queryService.CreateQuery(name);

var form = new Form { ContentTypes = type };
var serializer = new XmlSerializer(form.GetType());
StringWriter sw = new StringWriter();
XmlWriter writer = XmlWriter.Create(sw);
serializer.Serialize(writer, form);
var state = sw.ToString();

query.FilterGroups[0].Filters.Add(new FilterRecord
{
  Category = "Content",
  Description = "ProductPartFilter",
  Position = 0,
  State = state,
  Type = type
});

_contentManager.Publish(query.ContentItem);

[Serializable]
public class Form
{
  public string Description { get; set; }
  public string ContentTypes { get; set; }
}

Projection

Por último, para crear la página que muestra el listado de productos, hacemos clic en New Projection. Asignamos el título “Listado Productos”, la url “productos” y seleccionamos en el desplegable la Query “Productos”.

Una vez más, si necesitamos crear la instancia de Projection por código, tenemos las sentencias equivalentes:

var projection = _contentManager.New("ProjectionPage");
projection.As<TitlePart>().Title = "Listado Productos";
projection.As<AutoroutePart>().DisplayAlias = "productos";
projection.As<ProjectionPart>().Record.QueryPartRecord = query.Record;

string ownerName = _siteService.GetSiteSettings().SuperUser;
var owner = _membershipService.GetUser(ownerName);
projection.As<ICommonPart>().Owner = owner;

_contentManager.Create(projection, VersionOptions.Published);

Projection – Orchard Documentation

ASP.NET client side validation

Display validation errors using Page_ClientValidate. When a control causes a validation error, besides display an error message, we can add a red border around the control to catch user’s attention.

    <div>
        <asp:TextBox ID="TextBoxName" maxlength="100" runat="server" />
        <asp:RequiredFieldValidator runat="server" controltovalidate="TextBoxName" SetFocusOnError="true"></asp:RequiredFieldValidator>
    </div>    
    <div>
        <asp:TextBox ID="TextBoxEmail" maxlength="100" runat="server" />
        <asp:RequiredFieldValidator runat="server" controltovalidate="TextBoxEmail" SetFocusOnError="true"></asp:RequiredFieldValidator>
        <asp:RegularExpressionValidator runat="server" ControlToValidate="TextBoxEmail" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"></asp:RegularExpressionValidator>
    </div>

<asp:LinkButton ID="ButtonSubmit" runat="server" Text="Submit" OnClientClick="webPartInputs()" onClick="ButtonSubmit_Click" /> 

<script type="text/javascript">
    function validateControls() {
        if (Page_ClientValidate()) {
            return true;
        }
        else {
            var ids = [];
            $.each(Page_Validators, function () {
                var validator = $(this)[0];
                if (validator != null) {
                    var controltovalidate = validator.controltovalidate;
                    if (controltovalidate != null) {
                        ValidatorValidate(validator);

                        if (ids[controltovalidate] == null || ids[controltovalidate] == true) {
                            ids[controltovalidate] = validator.isvalid;
                        }
                    }
                }
            });
            for (var key in ids) {
                if (ids[key] == true) {
                    $('#' + key).removeClass('error');
                }
                else {
                    $('#' + key).addClass('error');
                }
            }
            return false;
        }
    }
</script>

File upload with ASP.NET

Perform a multipart post with file upload using HttpClient:

            string user = "test@test.com";
            string password = "a0999ca0902";
            string baseUrl = "http://test.com/test/api/";
            string fileName = "info.xml";
            string filePath = System.Web.Hosting.HostingEnvironment.MapPath("~/Content/" + fileName);

            using (var client = new HttpClient())
            {
                string basicAuth = Convert.ToBase64String(Encoding.ASCII.GetBytes(user  + ":" + password ));

                client.BaseAddress = new Uri(baseUrl);
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicAuth);

                using (var content = new MultipartFormDataContent())
                {
                    //var values = new[]
                    //{
                    //    new KeyValuePair<string, string>("Param1", "Value1"),
                    //    new KeyValuePair<string, string>("Param2", "Value2"),
                    //};

                    //foreach (var keyValuePair in values)
                    //{
                    //    content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
                    //}

                    var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filePath));
                    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                    {
                        Name = "uploadedfile",
                        FileName = fileName,
                    };
                    content.Add(fileContent);

                    var requestUri = "files/upload";
                    var result = client.PostAsync(requestUri, content).Result;
                }
            }

© 2017 JAVIER MARTINEZ

Tema por Anders NorenArriba ↑