Nesting apps within apps 2sxc 13.12.0 - 2sxc

I have been working with 2sxc alongside DNN (Dot Net Nuke) for some time now.
In previous versions of 2sxc I have been able to use the following code to nest a 'Content Block' item within the text editor field of another app.
So essentially nesting an app within an app!
Using this code as an example:
#ToSic.Sxc.Blocks.Render.All(modal, field: "Apps", merge: modal.Body)
Also with creating the 'Apps' as a separate field in the 2sxc app directly below the field I would like to nest the apps inside of.
However, this seems to create an error in the new recommended version of 2sxc.
Error code:
Error: System.NullReferenceException: Object reference not set to an instance of an object. at ToSic.Sxc.Edit.EditService.EditService.ConnectToRoot(IDynamicCodeRoot codeRoot) in C:\Projects\2sxc\2sxc\Src\Sxc\ToSic.Sxc\Edit\EditService\EditService.cs:line 26 at ToSic.Sxc.Blocks.RenderService.GetEdit(DynamicEntity parent) in C:\Projects\2sxc\2sxc\Src\Sxc\ToSic.Sxc\Blocks\Renderers\RenderService.cs:line 112 at ToSic.Sxc.Blocks.RenderService.All(DynamicEntity parent, String noParamOrder, String field, String apps, Int32 max, String merge) in C:\Projects\2sxc\2sxc\Src\Sxc\ToSic.Sxc\Blocks\Renderers\RenderService.cs:line 93 at ToSic.Sxc.Blocks.Render.All(DynamicEntity parent, String noParamOrder, String field, String apps, Int32 max, String merge) in C:\Projects\2sxc\2sxc\Src\Dnn\ToSic.Sxc.Dnn.Core\Compatibility\Sxc\ToSic.Sxc.Blocks.Render.cs:line 73 at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3) at ASP._Page_Portals_0_2sxc_LayoutApp__LayoutApp_cshtml.Execute() in c:\inetpub\wwwroot\little-seed-dnn\Portals\0\2sxc\LayoutApp_LayoutApp.cshtml:line 44 at System.Web.WebPages.WebPageBase.ExecutePageHierarchy() at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) at ToSic.Sxc.Engines.RazorEngine.Render(TextWriter writer) in C:\Projects\2sxc\2sxc\Src\Dnn\ToSic.Sxc.Dnn.Razor\Engines\Razor\RazorEngine.cs:line 117 at ToSic.Sxc.Engines.RazorEngine.RenderTemplate() in C:\Projects\2sxc\2sxc\Src\Dnn\ToSic.Sxc.Dnn.Razor\Engines\Razor\RazorEngine.cs:line 128 at ToSic.Sxc.Engines.EngineBase.Render() in C:\Projects\2sxc\2sxc\Src\Sxc\ToSic.Sxc\Engines\EngineBase.cs:line 135 at ToSic.Sxc.Blocks.BlockBuilder.RenderInternal() in C:\Projects\2sxc\2sxc\Src\Sxc\ToSic.Sxc\Blocks\BlockBuilder_Render.cs:line 186
Any help would be greatly appreciated, I may be simply missing a using statement.
Thanks in advance.

The code is different now, instead of Blocks or Factory the new way is IRenderService. There is an example of simply rendering the whole output of a module in to the theme (ascx user control) here.
I think a lot of what you need to convert or adapt is covered here:
Fix Breaking Change in static Render in v13
Important note: if you spot code examples with GetService() it is now final as GetScopedService() and you should use the latter.

Please also make sure you don't confuse the One(...) with the All(...) render methods.
One(...) will expect to get a specific thing to render
All(...) will take an entity which has Inner Content
So I'm just guessing, but you probably want One. All is basically for WYSIWYG setups, where the editor manually adds any app they want into a WYSIWYG field.
Check the blog app to see it in action.

Related

Can I change a (Netflix) Hollow model schema's field inlining once it's in use?

I'm working on software that propagates, to a fleet of servers, a medium-sized data set that doesn't change very often. I'm using Netflix's Hollow library to do it.
I've been thinking of the lifecycle of my application, and how it will grow and change over time. I've looked at the notes on backwards compatibility in the Hollow docs, and I don't think my question is addressed there.
When tuning my model for speed and memory efficiency, I can foresee deciding that a field I was referencing by id would be better off inlined, or vice versa.
Is inlining backwards compatible? That is, if I have inlined a field:
#HollowInline String title;
and I determine that I'd be better served by making the field a reference instead, can I just remove the inline annotation?
String title;
Or, as seems more likely, will that break my clients?
My hypothesis is that the only safe way to change inlining status is to add a new field with the desired inlining status, migrate my producer and consumers to use it, and then remove the old one.
It is a backwards incompatible change as you surmise. Given this schema:
java
class A {
int a1;
#HollowInline Integer a2;
}
Changing int a1 to Integer a1 and removing the #HollowInline annotation are equivalent. Changing an existing field from inline to reference or reference to inline is a breaking schema change.
A couple strategies can work around this:
Strategy 1
introduce a new field name; in your example you could call it String titleRef or String titleV2
populate title and titleV2 with the same value
release a new client API
once all consuming apps/services have upgraded and switched to call getTitleV2() you can remove title from the schema and begin publishing data without it
Strategy 2
Given: you use a namespace or naming scheme (such as naming the path to your blobs a certain way and announcing your versions under a topic name)
make the breaking change to your schema
change or rev your namespace
stand up a new producer publishing and announcing to the new namespace running in parallel to the old producer
release a new client; consumers picking up this new client should be configured to use the new namespace (it could be baked in to a wrapper you release with the client, for instance)
once all consuming app/services are using new client with new namespace, retire old producer

How do I specify an asp.net mvc 5 resource file in a VB Class Data Annotation?

VS 2013, MVC 5, VB, Entity Framework
This is part of my Class:
Public Class Order
....
Private mFirstName As String
<Required(ErrorMessage:="First name required - hard coded")>
Public Property FirstName() As String
Get
Return mFirstName
End Get
Set(ByVal value As String)
mFirstName = value
End Set
End Property
....
I want to setup a resource file to allow error messages to change with different countries. What would I write to have the error message pulled from a resource file named ErrorMessages.resx?
The examples for doing this are mostly in C#, and finding the VB equivalent was difficult, at least for me, and I thought other VB programmers might appreciate the proper syntax.
The C# answer is:
[Required(ErrorMessageResourceType=typeof(ErrorMessages),ErrorMessageResourceName="FirstNameRequired")]
What was difficult was to find the proper VB operator to apply for the C# "typeof" operator. In VB the line above is:
<Required(ErrorMessageResourceName:="FirstNameRequired", ErrorMessageResourceType:=GetType(Resources.ErrorMessages))>
in the lines above, the Name/Value pairs are stored in ErrorMessages.resx (see how to create below), and "FirstNameRequired" is the Name of the string that will hold the actual text to be displayed.
Just to cover the bases:
What's pretty neat is that VS2013 automatically creates the Class and type definitions for the resource file and they show up in Intellisense, as in the VB line above 'Resources.ErrorMessages'.
It's also important to note the Data Annotation operators can have only one or the other of the two error message string properties, so the property "ErrorMessage" had to be removed as seen in the code lines in this answer post.
To use a Global Resource file (local files are possible), on the project node do an Add > Add ASP.NET Folder > Add App_GlobalResources. Then inside that folder Add > New Item > Resources File. After that the Name-Value pairs can be added, and then later additional country-culture resource files can be added, and online documentation for this process is fairly plentiful. ASP.NET, and MSDN for the country-culture.
The MSDN page that lists all of the data annotations is here; But I didn't find enough code samples to readily explain how to take advantage of the properties listed.
Hope this is helpful for someone else.
Best Regards,
Alan

Adding and removing items dynamically in one View with Entity Framework and MVC

I've been at this same question in different forms now for a while (see e.g. Entity Framework and MVC 3: The relationship could not be changed because one or more of the foreign-key properties is non-nullable ), and it's still bugging me, so I thought I'd put it a little more generically:
I feel this can't be a very unusual problem:
You have an entity object (using Entity Framework), say User. The User has some simple properties such as FirstName, LastName, etc. But it also has some object property lists, take the proverbial example Emails, to make this simple. Email is often designed as a list of objects so that you can add to that object properties like Address and Type (Home, Work, etc). I'm using this as an example to keep it generic, but it could be anything, the point is, you want the user to be able to add an arbitrary number of these items. You should also be able to delete items (old address, or whatever).
Now, in a normal web page you would expect to be able to add these items in the same View. But MVC as it seems designed only makes it easy to do this if you call up an entirely new View just to add the address. (In the template for an Index View you get the "Create New" link e.g.).
I've come across a couple of examples that do something close to what I mean here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
and
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
The problem is, although the sample projects on these sites work fine, with mock model objects, and simply lists (not an object with a child list), it's a different thing if you actually want to do something with the posted information - in my case save to database through the Entity Framework model. To adapt these cases to that, all of a sudden I'm in a maze of intricate and definitely not DRY code... Juggling objects with AutoMapper and whatnot, and the Entity Framework won't let you save and so on (see above link if you're interested in the details).
What I want to get at is, is it really possible that this is such an uncommon thing to want to do? Update a child collection in the same View as the parent object (such as the email addresses in this case)? It seems to me it can't be uncommon at all, and there must be a standard way of handling this sort of scenario, and I'm just missing it (and no one here so far has been able to point me to a straighforward solution, perhaps because I made it too abstract with my own application examples).
So if there is a simple solution to what should in my view be a simple problem (since the design is so common), please tell me.
Have you tried updating the project at your link to Steven Anderson's blog to bind to a complex object? Create a class in models called Sack and give it a single property and see if you can get it to work.
public class Sack
{
public IEnumberable<Gift> Gifts { get; set; }
}
It only took me a minute to get it up and running as I think you intend. The improvement I would have made next would be to add an HtmlHelper extension that is essentially the same as Html.EditorFor(m => m.SomeProperty), only call it something more meaningful and have it interface with the prefix scope extensions provided in the project.
public static class HtmlExtensions
{
public static IHtmlString CollectionEditorFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
{
if (/* type of expression value is not a collection */) throw new FailureToFollowTheRulesException("id10t");
// your implementation
}
}

Accessing resource strings with CultureInfo in .NET

Another simple questions.
I have website with different languages. If I want to access a string from the resource file I would use it like this
Resources.MyResourceFile.MyStringIdentifier
Very easy. That way I know during compile time, that the resource string exists.
Now, this works only if I want to use the current Culture. Sometimes I need to specify a specific culture (let's say that the current user uses German as a language, but his action triggers messages to be sent to other users which will be in the recipient's language). Now, I see two options:
Resources.MyResourceFile.ResourceManager.GetString("MyStringIdentifier", neededCulturInfo)
The other would be to change the current thread's culture info which I would need to do several times.
Is there a third way? Something which tells me at compile time that the resources exist but without the need to change the thread's culture all the time?
(For your scenario) the idea of the ResourceManager is to provide culture specific informations at runtime not at compile time (aka side-by-side with fallback).
So the answer is "NO", there isn't a buildin way to determinate the existance of those resource files at compile time - to do so you would require a kind of "hard coding" for all strings in every single langauge and also code to access to those. The side by side idea is exactly the opposite of hardcoding ;)
What you could do, is writng a unit test for the resources, that itterates your langauges and checks if the default or a localized value was used. Further if you are using a source control system that provides check-in policies (e.g. TFS) you could this unit test as part of the check-in policy.
Have you tryied :
public static Object GetLocalResourceObject (
string virtualPath,
string resourceKey,
CultureInfo culture)
Try this link Click here
You can also try:
public static Object GetGlobalResourceObject (
string classKey,
string resourceKey,
CultureInfo culture)
Try this link Click here
ResourceSet has a method
public virtual IDictionaryEnumerator GetEnumerator()
that gives access to key-value pairs of the resource file.
E.g. (assuming we deal only with strings - N.B. the key-value pairs are of type object):
while (set.MoveNext())
{
string key = (string)set.Key;
// string value = (string)set.Value;
string value = ResourceManager.GetString(key, neededCulturInfo);
}
This is not what you should do, because things become complicated - just to point it out.
You could create different resource files for different cultures and use a switch code block in a method that has a CultureInfo as parameter.
You construct a class that looks inside the resource or use the Enumerator solution,look for the value and if it does not exist, make it use the value in the default language.
But in compile time, it cannot be verified.
The easiest option is a try-catch and return the value in the general language in the catch.
Nevertheless, if we are using resources, all the keys must always be present in all the related files, even if you copy them with the general language values.
My solution is what it should be, all the resources should be consistent, if not we are using this great tool badly.
The generated Resources.MyResourceFile class has a static Culture property, which you can set to neededCultureInfo to override the current thread's CurrentUICulture.
1) At the start maybe could be useful to store the UICulture into a session, in order to change it when you want, at the begin you can change it from there.
2) You can override the UICulture in preRender and set it from there and than storing it into session.
You can store it in a cookie as well but is not the best solution for it.
You can use WorkItems to send the messages asynchronously. Since you're now running on a different Thread, you should be able to modify the CurrentUICulture as needed.
P.S.: this is a good example why static dependencies are bad and everything should be interfaces & instances.

TinyMCE Spellchecker in ASP .NET MVC

I followed the tutorial described here, in order to make the TinyMCE Spellchecker work on a Webforms application. But I tried to do the very same thing on a MVC project and keep getting errors every time I try to use the spellchecker.
I'd like to know what changes or adjustments I need to make in order to make this word on an ASP .NET MVC project.
The error I'm getting is the following:
[HttpException]: The controller for path '/TinyMCE.ashx' could not be found or it does not implement
IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String
controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext)
at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute
()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Well its a bit hard to know what the problem is without knowing what the error you're getting is, but I'm guessing that its because you need to ignore the route to the spell checker in your MVC. Do this by adding something like this to your MVC route definitions:
//ignore just the TinyMCE spell checker service:
routes.IgnoreRoute("TinyMCE.ashx");
//or if you want to be more general & ignore all ashx's:
routes.IgnoreRoute("{resource}.ashx{*pathInfo}");
Without the above it would be interpreting the spellcheck request url (TinyMCE.ashx...) as an MVC route & try to find a matching Controller (& obviously fail).
If that's not the issue, I'd suggest posting some more info about the specific error you're seeing.
I'm pretty new to MVC (a little over a year) and was pretty interested in spell check for a specific page in my solution. The above options may work for some folks, but didn't work for me (I'm not very patient, and in all honesty didn't want to ignore any routes, or modify my the system.web section of my config for something that only 5% of my solution consumers are going to use, so I didn't spend a whole lot of time on those options).
So:
I copied the Moxiecode.TinyMCE.dll file to a directory in my project so future contributors will have the dll without having to search google.
I added a reference to the above dll to my project.
I created a new controller called SpellCheckController.cs that contains the following:
public void CheckSpelling()
{
SpellCheckerModule spellChecker = new SpellCheckerModule();
spellChecker.ProcessRequest(System.Web.HttpContext.Current);
}
(don't forget the using Moxiecode.TinyMCE.SpellChecker;)
and just referenced the controller like this in the setup options for TinyMCE in my view:
spellchecker_rpc_url: "#Url.Action("CheckSpelling","SpellCheck")/?module=SpellChecker"
I haven't ignored any routes. I haven't added another httphandler to the what I am assuming is a pretty long list of handlers for .net, and spell check works for me now.
I also have the ability to go with something different without changing too much (assuming I figure out what TinyMCE's spellchecker is doing with the http context.
P.S.
Stack Overflow's rich text editor doesn't seem to have a spell check feature, so there are no guaranties on the above spelling :)

Resources