Click here to Skip to main content
15,887,175 members
Articles / Web Development / HTML

Signum Framework Tutorials Part 3 - Southwind Load

Rate me:
Please Sign up or sign in to vote.
4.62/5 (7 votes)
21 Nov 2012CPOL23 min read 24.4K   319   10  
In this part we'll write the loading application to move data from Northwind to Southwind.
#region usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using Signum.Utilities;
using Signum.Engine;
using Signum.Entities;
using Signum.Engine.Maps;
using Signum.Web.Properties;
using Signum.Engine.DynamicQuery;
using Signum.Entities.Reflection;
using Signum.Entities.DynamicQuery;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using System.Web.Script.Serialization;
using System.Text;
using System.IO;
#endregion

namespace Signum.Web.Controllers
{
    public class SignumController : Controller
    {
        [ValidateInput(false)]  //this is needed since a return content(View...) from an action that doesn't validate will throw here an exception. We suppose that validation has already been performed before getting here
        public ViewResult View(string webTypeName, int? id)
        {
            Type t = Navigator.ResolveType(webTypeName);

            if (id.HasValue && id.Value > 0)
                return Navigator.View(this, Database.Retrieve(t, id.Value), true); //Always admin

            IdentifiableEntity entity = null;
            object result = Constructor.Construct(t);
            if (typeof(IdentifiableEntity).IsAssignableFrom(result.GetType()))
                entity = (IdentifiableEntity)result;
            else
                throw new InvalidOperationException("Invalid result type for a Constructor");
             
            return Navigator.View(this, entity, true); //Always admin
        }

        public ActionResult Create(string runtimeType, string prefix)
        {
            Type type = Navigator.ResolveType(runtimeType);

            return Constructor.VisualConstruct(this, type, prefix, VisualConstructStyle.Navigate);
        }

        public PartialViewResult PopupCreate(string runtimeType, string prefix, string url)
        {
            Type type = Navigator.ResolveType(runtimeType);

            ViewData[ViewDataKeys.WriteSFInfo] = true;

            object result = Constructor.VisualConstruct(this, type, prefix, VisualConstructStyle.PopupView);
            if (result.GetType() == typeof(PartialViewResult))
                return (PartialViewResult)result;

            if (result.GetType().IsEmbeddedEntity())
                throw new InvalidOperationException("PopupCreate cannot be called for EmbeddedEntity {0}".Formato(result.GetType()));

            if (!typeof(IdentifiableEntity).IsAssignableFrom(result.GetType()))
                throw new InvalidOperationException("Invalid result type for a Constructor");

            IdentifiableEntity entity = (IdentifiableEntity)result;

            return Navigator.PopupView(this, entity, prefix, url);
        }

        public PartialViewResult PopupView(string runtimeType, int? id, string prefix, bool? readOnly, string url)
        {
            Type type = Navigator.ResolveType(runtimeType);
            
            IdentifiableEntity entity = null;
            if (id.HasValue)
                entity = Database.Retrieve(type, id.Value);
            else
            {
                ActionResult result = Constructor.VisualConstruct(this, type, prefix, VisualConstructStyle.PopupView);
                if (result is PartialViewResult)
                    return (PartialViewResult)result;
                else
                    throw new InvalidOperationException("Invalid result type for a Constructor");
            }
            
            TypeContext tc = TypeContextUtilities.UntypedNew((IdentifiableEntity)entity, prefix);

            if (readOnly.HasValue)
                tc.ReadOnly = true;

            return Navigator.PopupView(this, tc, url);
        }

        [HttpPost]
        public PartialViewResult PartialView(string runtimeType, int? id, string prefix, bool? readOnly, string url)
        {
            Type type = Navigator.ResolveType(runtimeType);
            
            IdentifiableEntity entity = null;
            if (id.HasValue)
                entity = Database.Retrieve(type, id.Value);
            else
            {
                object result = Constructor.VisualConstruct(this, type, prefix, VisualConstructStyle.PartialView);
                if (result is PartialViewResult)
                    return (PartialViewResult)result;
                else
                    throw new InvalidOperationException("Invalid result type for a Constructor");
            }
            
            TypeContext tc = TypeContextUtilities.UntypedNew((IdentifiableEntity)entity, prefix);

            if (readOnly.HasValue)
                tc.ReadOnly = true;

            return Navigator.PartialView(this, tc, url);
        }

        [HttpPost, ValidateAntiForgeryToken]
        public ActionResult TrySave()
        {
            MappingContext context = this.UntypedExtractEntity().UntypedApplyChanges(ControllerContext, null, true).UntypedValidateGlobal();

            if (context.GlobalErrors.Any())
            {
                this.ModelState.FromContext(context);
                return JsonAction.ModelState(ModelState);
            }

            IdentifiableEntity ident = context.UntypedValue as IdentifiableEntity;
            if (ident == null)
                throw new ArgumentNullException("No IdentifiableEntity to save");

            Database.Save(ident);

            string newUrl = Navigator.ViewRoute(ident.GetType(), ident.Id);
            if (HttpContext.Request.UrlReferrer.AbsolutePath.Contains(newUrl))
                return Navigator.View(this, ident, true);
            else
                return JsonAction.Redirect(newUrl);
        }

        [HttpPost]
        public JsonResult Validate()
        {
            MappingContext context = this.UntypedExtractEntity().UntypedApplyChanges(ControllerContext, null, true).UntypedValidateGlobal();

            this.ModelState.FromContext(context);
            return JsonAction.ModelState(ModelState);
        }

        [HttpPost, ValidateAntiForgeryToken]
        public JsonResult TrySavePartial(string prefix)
        {
            MappingContext context = this.UntypedExtractEntity(prefix).UntypedApplyChanges(ControllerContext, prefix, true).UntypedValidateGlobal();

            this.ModelState.FromContext(context);

            IdentifiableEntity ident = context.UntypedValue as IdentifiableEntity;
            if (ident != null && !context.GlobalErrors.Any())
                Database.Save(ident);

            string newLink = Navigator.ViewRoute(context.UntypedValue.GetType(), ident.TryCS(e => e.IdOrNull));

            return JsonAction.ModelState(ModelState, context.UntypedValue.ToString(), newLink);
        }

        [HttpPost]
        public JsonResult ValidatePartial(string prefix)
        {
            ModifiableEntity mod = this.UntypedExtractEntity(prefix);
            MappingContext context = null;
            bool isEmbedded = mod as EmbeddedEntity != null && !(mod is ModelEntity);
            if (isEmbedded)
            {
                mod = this.UntypedExtractEntity(); //apply changes to the parent entity
                context = mod.UntypedApplyChanges(ControllerContext, "", true).UntypedValidateGlobal();
            }
            else
            {
                context = mod.UntypedApplyChanges(ControllerContext, prefix, true).UntypedValidateGlobal();
            }

            this.ModelState.FromContext(context);

            string newLink = "";
            string newToStr = "";
            IIdentifiable ident = context.UntypedValue as IIdentifiable;
            if (isEmbedded)
            {
                newToStr = MappingContext.FindSubEntity((IdentifiableEntity)context.UntypedValue, prefix).ToString();
            }
            else if (context.UntypedValue == null)
            {
                RuntimeInfo ei = RuntimeInfo.FromFormValue(Request.Form[TypeContextUtilities.Compose(prefix, EntityBaseKeys.RuntimeInfo)]);
                newLink = Navigator.ViewRoute(ei.RuntimeType, ident.TryCS(e => e.IdOrNull));
                newToStr = context.UntypedValue.ToString();
            }
            else
            {
                newLink = Navigator.ViewRoute(context.UntypedValue.GetType(), ident.TryCS(e => e.IdOrNull));
                newToStr = context.UntypedValue.ToString();
            }
            
            return JsonAction.ModelState(ModelState, newToStr, newLink);
        }

        [HttpPost]
        public JsonResult Autocomplete(string types, string q, int l)
        {
            Type[] typeArray = StaticInfo.ParseTypes(types);
            if (typeArray == StaticInfo.ImplementedByAll)
                throw new ArgumentException("ImplementedBy not allowed in Autocomplete");

            List<Lite> lites  = AutoCompleteUtils.FindLiteLike(typeof(IdentifiableEntity), typeArray, q, l);

            var result = lites.Select(o => new
            {
                id = o.Id,
                text = o.ToStr,
                type = Navigator.ResolveWebTypeName(o.RuntimeType)
            }).ToList();

            return Json(result);
        }

        public ActionResult Find(FindOptions findOptions)
        {
            return Navigator.Find(this, findOptions);
        }

        [HttpPost]
        public PartialViewResult PartialFind(FindOptions findOptions, string prefix)
        {
            return Navigator.PartialFind(this, findOptions, prefix);
        }

        [HttpPost]
        public PartialViewResult Search(FindOptions findOptions, int? top, string prefix)
        {
            return Navigator.Search(this, findOptions, top, prefix);
        }

        [HttpPost]
        public ContentResult AddFilter(string webQueryName, string tokenName, int index, string prefix)
        {
            object queryName = Navigator.ResolveQueryName(webQueryName);

            FilterOption fo = new FilterOption(tokenName, null);
            if (fo.Token == null)
            {
                QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);
                fo.Token = QueryUtils.Parse(tokenName, qd);
            }
            fo.Operation = QueryUtils.GetFilterOperations(QueryUtils.GetFilterType(fo.Token.Type)).First();

            return Content(SearchControlHelper.NewFilter(CreateHtmlHelper(this), queryName, fo, new Context(null, prefix), index).ToHtmlString());
        }

        [HttpPost]
        public ContentResult GetColumnName(string webQueryName, string tokenName)
        {
            object queryName = Navigator.ResolveQueryName(webQueryName);
            QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);
            QueryToken token = QueryUtils.Parse(tokenName, qd);
            return Content(token.NiceName());
        }

        [HttpPost]
        public ContentResult GetContextualPanel(string lite, string webQueryName, string prefix)
        {
            string[] liteParts = lite.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

            object queryName = Navigator.ResolveQueryName(webQueryName);
            
            string result = ContextualItemsHelper.GetContextualItemListForLite(this.ControllerContext, Lite.Create(Navigator.ResolveType(liteParts[0]), int.Parse(liteParts[1])) , queryName, prefix).ToString("");

            if (string.IsNullOrEmpty(result))
                result = new HtmlTag("li").Class("sf-search-ctxitem sf-search-ctxitem-no-results").InnerHtml(Resources.NoResults.EncodeHtml()).ToHtml().ToString();

            return Content(result);
        }

        [HttpPost]
        public ContentResult QuickFilter(string webQueryName, string tokenName, int index, string prefix, string value)
        {
            object queryName = Navigator.ResolveQueryName(webQueryName);

            FilterOption fo = new FilterOption(tokenName, null);
            if (fo.Token == null)
            {
                QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);
                fo.Token = QueryUtils.Parse(tokenName, qd); 
            }
            fo.Operation = QueryUtils.GetFilterOperations(QueryUtils.GetFilterType(fo.Token.Type)).First();
            
            try
            {
                fo.Value = FindOptionsModelBinder.Convert(value, fo.Token.Type);
            }
            catch (Exception) 
            { 
                //Cell Value must be custom and cannot be parsed automatically: Leave value to null
            }

            return Content(SearchControlHelper.NewFilter(CreateHtmlHelper(this), queryName, fo, new Context(null, prefix), index).ToHtmlString());
        }

        [HttpPost]
        public ContentResult NewSubTokensCombo(string webQueryName, string tokenName, string prefix, int index)
        {
            object queryName = Navigator.ResolveQueryName(webQueryName);
            QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);
            QueryToken[] subtokens = QueryUtils.Parse(tokenName, t => QueryUtils.SubTokens(t, qd.Columns)).SubTokens();
            if (subtokens == null)
                return Content("");

            //var items = subtokens.Select(t => new SelectListItem
            //{
            //    Text = t.ToString(),
            //    Value = t.Key,
            //    Selected = false
            //}).ToList();
            //items.Insert(0, new SelectListItem { Text = "-", Selected = true, Value = "" });

            var items = new HtmlStringBuilder();
            items.AddLine(new HtmlTag("option").Attr("value", "").SetInnerText("-").ToHtml());
            foreach (var t in subtokens)
            {
                var option = new HtmlTag("option")
                    .Attr("value", t.Key)
                    .SetInnerText(t.ToString());

                string canColumn = QueryUtils.CanColumn(t);
                if (canColumn.HasText())
                    option.Attr("data-column", canColumn);

                string canFilter = QueryUtils.CanFilter(t);
                if (canFilter.HasText())
                    option.Attr("data-filter", canFilter);

                items.AddLine(option.ToHtml());
            }

            return Content(SearchControlHelper.TokensCombo(CreateHtmlHelper(this), queryName, items, new Context(null, prefix), index + 1, true).ToHtmlString());
        }

        [HttpPost]
        public PartialViewResult GetTypeChooser(string types, string prefix)
        {
            Type[] typeArray = StaticInfo.ParseTypes(types);

            if (typeArray == StaticInfo.ImplementedByAll)
                throw new ArgumentException("ImplementedByAll is not allowed in GetTypeChooser");

            if (typeArray.Length == 1)
                throw new ArgumentException("GetTypeChooser must recieve at least 2 types to chose from");

            HtmlStringBuilder sb = new HtmlStringBuilder();
            foreach (Type t in typeArray)
            {
                string webTypeName = Navigator.ResolveWebTypeName(t);

                sb.Add(new HtmlTag("input")
                    .IdName(webTypeName)
                    .Attrs(new { type = "button", value = t.NiceName(), @class = "sf-chooser-button" })
                    .ToHtmlSelf());
                sb.Add(new HtmlTag("br").ToHtmlSelf());
            }

            ViewData.Model = new Context(null, prefix);
            ViewData[ViewDataKeys.CustomHtml] = sb.ToHtml();
            ViewData[ViewDataKeys.Title] = Resources.ChooseAType;

            return PartialView(Navigator.Manager.ChooserPopupView);
        }

        [HttpPost]
        public PartialViewResult GetChooser(List<string> buttons, List<string> ids, string prefix, string title)
        {
            if (buttons == null || buttons.Count == 0)
                throw new InvalidOperationException("GetChooser needs a list of options");

            HtmlStringBuilder sb = new HtmlStringBuilder();
            int i = 0;
            foreach (string button in buttons) 
            {
                string id = ids != null ? ids[i] : button.Replace(" ", "");
                sb.Add(new HtmlTag("input")
                    .IdName("option_" + id)
                    .Attrs(new Dictionary<string, string> { { "data-id", id }, { "type", "button" }, { "value", button }, { "class", "sf-chooser-button" } })
                    .ToHtmlSelf());
                sb.Add(new HtmlTag("br").ToHtmlSelf());
                i++;
            }

            ViewData.Model = new Context(null, prefix);
            ViewData[ViewDataKeys.CustomHtml] = sb.ToHtml();
            if (title.HasText())
                ViewData[ViewDataKeys.Title] = title;

            return PartialView(Navigator.Manager.ChooserPopupView);
        }

        public static HtmlHelper CreateHtmlHelper(Controller c)
        {
            var viewContext = new ViewContext(c.ControllerContext, new FakeView(), c.ViewData, c.TempData, TextWriter.Null);
            return new HtmlHelper(viewContext, new ViewPage());
        }

        class FakeView : System.Web.Mvc.IView
        {
            public void Render(ViewContext viewContext, TextWriter writer)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Signum Software
Spain Spain
I'm Computer Scientist, one of the founders of Signum Software, and the lead developer behind Signum Framework.

www.signumframework.com

I love programming in C#, Linq, Compilers, Algorithms, Functional Programming, Computer Graphics, Maths...

Comments and Discussions