Blazor databinding to a javascript web component with complex object from C# - interop

I've got a Blazor app that is referencing a custom web component (<omnibar-navigation>).
This component has an items property that should be a json object that looks something like this:
[{'title':'Home','icon':'places-home-1','url':'/','metadata':null,'items':null}, ...]
I'm wondering how to bind a C# complex object to that items property.
var options = new List<Nav> { new Nav { Title = "Home", Icon = "places-home-1", Url = "/" } };
Then the binding would be something like this (doesn't work):
<omnibar-navigation items="#options">...</omnibar-navigation>
A code repo for this problem is here: https://github.com/dahlsailrunner/blazor-oidc.
The page with the exact problem is here: https://github.com/dahlsailrunner/blazor-oidc/blob/master/Sample.Blazor/Pages/Stencil.razor
The component is imported on the Pages/_Host.cshtml file.

Great question. I noticed also some issues with binding a web component directly via Blazor data binding, especially with the connectedCallback of the web component which is a kwown issue.
But the great thing is:
If something in Blazor doesn't work, you can always use JavaScript Interop to make it work!
I've created here a blog post for you that shows how to integrate a web component via JS Interop that has such a property/attribute that takes a complex object: https://www.thomasclaudiushuber.com/2020/02/14/initializing-web-components-in-blazor-via-js-interop/
It also shows how to wrap the web component with a native Blazor component, so that you can bind it just with C#. :-)
Here is a git repo with all the code: https://github.com/thomasclaudiushuber/Blazor-Using-Custom-Web-Component
Happy coding,
Thomas

You're going to build a component with a Parameter property that receives an IEnumerable of your Nav type. You just need to deserialize your JSON and bind it to that collection.
Check this gist for how you can deserialize the JSON and bind to the collection in the index.razor file
https://gist.github.com/csharpfritz/c4dcfcc731826822e0764728bbd9d88c

Related

Xamarin.Forms How to switch pages using MVVMLight

I'm currently working on a Xamarin.forms project using .NET Standard as code sharing strategy. I try to use the MVVM pattern by using the MvvmLightLibsStd10 library. I already successfully setup the MVVM structure by using this tutorial:
https://www.linkedin.com/pulse/build-xamarinforms-net-standard-mvvm-light-app-rafael-carvalho
I can't use Navigation.PushAsync(new Page()); because it only works in code behind and not in the ViewModel.
I already tried to Pass Navigation trough the VM constructor, like describe over here:
Xamarin.form Page Navigation in mvvm
But when I try this method, an error occurred at "LoadApplication(new DemoMVVM2.App());" in MainPage.
How can I switch pages using MVVM Xamarin.Forms with MVVMLight (based on the code from my first url)?
but I have no Idea how I can switch Pages via the ViewModel and keeping the header with back button.
Generally when working with MVVMLight you'll be using a NavigationService.
This class can be constructor injected in your VM, thanks to the build in IOC in MVVMLight.
With it you can do Navigate and GoBack in your VM, triggering a real navigation on the current stack.
Only thing that you maybe missed, is the fact that you need to write one yourself for Xamarin forms.
But Laurent Bugnion ( the owner of MVVMLight ) supplied an example available here:
https://github.com/lbugnion/sample-2016-vslive-crossplatform/blob/master/Flowers/Flowers.Forms/Flowers.Forms/Helpers/NavigationService.cs
You can pass a callback to your ViewModel(VM) and on Command or whatever action call your navigation code which is in your page (View). this way you can keep your navigation code in your page and your binding logic in your ViewModel.
interface NavHandler{
void navigateToSomeView();
}
public class MyPage : ContentPage,NavHandler{
public MyPage(){
BindingContext = new MyViewModel(this);
}
void navigateToSomeView(){
Navigation.PushAsync(new Page2());
}
}
public class MyViewModel{
NavHandler handler;
public MyViewModel(NavHandler handler){
this.handler = handler
}
//Your action
this.btnClicked = new Command(async()=>{
handler.navigateToSomeView()
}
}

What is the best practice to implement custom Javascript code and where should I start working with Ember first?

I'm using Ember 2.7.0 of course with ember-cli.
I come from Rails, I used to put in "assets/application.js" all my javascript like, for example:
var ready = function () {
myFunction('test');
$('#btn-fluid').on('click', function () {
$('#myPage').toggleClass('container')
});
}
document.addEventListener("turbolinks:load", function () {
ready()
})
Now with Ember where I have to put this code in my application?
I read on the web the use of:
Ember.Application.create({
ready: function () {
});
but I don't know how to put this code: in app.js maybe, but I already have:
App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
and if I create another file in the root, like for example "mycode.js" like this:
import {Ember} from 'ember';
let myCode;
myCode = Ember.Application.create({
ready: function () {
console.log('Test!');
}
});
export default myCode;
and import it in application using ember-cli-build.js here:
...
app.import('mycode.js');
it compile the big js with my code, but it doesn't work at all my ready function.
How to do?
I have to use Components? Maybe an application component?
Which is the best Ember way for top performances?
To start working with Ember is a must to know Ember's structure and the way Ember works, Simply you need to use Ember guideline to get the best performance. I will explain you some steps and example and I hope it will help you to understand more.
First of all check this image
1. Review Ember Guides and API Docs
In addition, it's a good to review this repository on Github as well. https://github.com/emberjs/guides/ which will help developers to get used to Ember.
2. Install Ember-CLI
Ember-CLI is a command line interface which has been designed for creating Ember apps that strongly favor convention over configuration.
3. Install the Ember Inspector Extension
The Ember Inspector Extension is super-useful for debugging your Ember app.You may also find Chrome app on Google play.
4. Read “From Rails To Ember”
Since you know Ruby on Rails and you are a developer of that, it is essential that you read the tips compiled in From Rails To Ember.
5. Get to Know Ember.Component
A simple way to think of an Ember component is that it is a combination of controller and view, isolated and reusable:
You should pass in the state you need to the component.
Components should communicate with their parent scope (e.g, controller
or another component) by sending actions.
Parent scope (e.g., controller or another component) communicates with
the component by changing the data state that it has passed to the
component.
As an example I am going to explain some part of your code.
You have this
$('#btn-fluid').on('click', function () {
$('#myPage').toggleClass('container')
});
and probably this is your HTML code
<a id="btn-fluid">Whatever for CLICK </a>
<div id="myPage" class="">dummy text </div>
However, in Ember what would be the best practice to use Actions in your Route or Controller to define your action function for example your code in Ember will be something like this :
myPage: null,
actions: {
clickOnbtnFliud() {
this.set('myPage', 'container');
}
}
and HTML in the same template for the controller would be like
<a {{action 'clickOnbtnFliud'}}>Whatever for CLICK </a>
<div class="{{myPage}}">dummy text </div>
In Summary,
You may use Components as you need which is the best practice for your Ember Application but you need to understand where you have to create that.
You rarely need to edit Ember-Cli-Build.js unless you want to insert extra plugins library or ... but I don't recommend you to insert your internal JS files as you can simply convert it to Ember Native codes. For instance you don't need to do this app.import('mycode.js'); but you can simply create your Route and add your custom code like I said as an example before to your Route or Controller or Components.
What I can assure you is if you user Ember in the way that you can find in Guidelines in Ember website, You don't need to worry about performance.Just try to user Ember Native way to implement your code.
Last word, As much as possible keep yourself motivated to use EmberAddons rather than thirdparty plugins and always choose the best updated addons not all of them. Search for best Addons and popular ones and use it.
Hope this guide help you.

How to access session from a view in ASP .NET Core MVC 1.0

I am trying to access session data from inside a view.
Use Case: I'm storing status messages in the session that will be displayed at the top of the page. Currently I implemented this by using a DisplayMessages() function that sets some ViewData[....] properties and calling it at the beginning of every controller action.
Goal: I want to only set the status message once without needing additional code in the controller to display the messages on the next page load.
So I'm trying to access the messages that are stored in the session directly from the view.
So far I have tried the following:
Dependency Injection of an IHttpContextAccessor (doesn't seem to work anymore with ASP .NET Core MVC 1.0.0
Creating a static class to access the session, including the change from next() to next.invoke() suggested in the comment
This didn't work. I could access the HttpContext and Session.IsAvailable was true, but there was no data in the session.
The following should work in the view: Context.Session.TryGetValue
If you are using the SessionExtensions then Context.Session.GetString will work.
Injecting IHttpContextAccessor does work, but starting with ASP.NET Core 1.0.0 RC2, the IHttpContextAcessor is not registered by default, because it has significant performance overhead per request. See this GitHub announcement for more information.
Tratcher posted:
IHttpContextAccessor can be used to access the HttpContext for the current thread. However, maintaining this state has non-trivial performance costs so it has been removed from the default set of services.
Developers that depend on it can add it back as needed:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
But in your use case, I would suggest using a ViewComponent, which is a reusable piece of View with logic, that do not depend on a controller.
The documentation can be found here.
In your Views you would simply embed it with
#await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
or
#Component.Invoke("PriorityList", new { maxPriority = 2, isDone = false })
for synchronous calls.

Call a server side MVC action on the click of a Kendo UI button

I just download a trial version of v2013.3.1119.440 of the Kendo UI wrappers for ASP.NET MVC. I see a new Kendo.Mvc.UI.Fluent.ButtonBuilder wrapper in this version that wasn't in the version I had downloaded just 20 days ago on another PC.
The said wrapper represents a button.
I can't see a way to directly wire this Kendo.Mvc.UI.Fluent.ButtonBuilder wrapper with a server side MVC action. How do I do that?
I do see the Events method on the ButtonBuilder class, which accepts a Action<ButtonEventBuilder> events. In the ButtonEventBuilder, I see another method called Click, which has two overloads, but both are for wiring client side event handlers of the button.
I don't see a way to directly wire up a server side call-back/post-back with the button click.
Am I missing something? Is the only way to do it the manual way of firing the server side post back or call back from a JavaScript function?
The Button is new in the latest release of Kendo UI (last week). It doesn't directly support what you're looking for, but something similar could be accomplished like this:
#(Html.Kendo().Button()
.Name("textButton")
.Content("Text button")
.HtmlAttributes( new {type = "button"} )
.Events(ev => ev.Click("onClick")))
Then a JS function similar to this:
function onClick(){
$.ajax({
url: '/controller/action'
data: { // data here }
}).done(function(result){
// do something with the result
}).fail(function() { // handle failure });
}
More info can be found in their demo site: http://demos.kendoui.com/web/button/events.html

How can I view the request body in ASP.NET Web API from Visual Studio?

How can I view the request body in ASP.NET Web API from Visual Studio? In ASP.NET MVC, you can use QuickWatch to inspect the Request object and view the content of the body and any posted form data. From what I read, ASP.NET Web API doesn't allow you to read the body more than once.
This is very annoying to deal with when trying to figure out why a specific value wasn't bound correctly. Is there a quick way to do this without setting up tracing/logging?
The easiest it to install Fiddler. Then you will see everything that gets sent over the wire and inspect not only the request payload but the HTTP headers as well. And if you are consuming the API from javascript, things like FireBug, Chrome Developer Toolbar and IE Developer Tools will show you all network requests made by the website.
If you absolutely must inspect the traffic on the server then if you are hosting your Web API inside an ASP.NET application you could put the following line in your immediate window:
new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd()
if you need body >> Form-data
Post localhost:53356/api/carparksapi/GetRecod
key=jsonRequest and value=[{"abcd":"zxxx"}]
// API -Controller Method ::
var httpContext = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
var foo = httpContext.Request.Form["jsonRequest"];
return foo; //This is value passed in request
For ASP.NET Core use this in the immediate window:
new System.IO.StreamReader(Request.Body).ReadToEnd()
For me #DarinDimitrov answer gave
error CS0246: The type or namespace name 'StreamReader' could not be found (are you missing a using directive or an assembly reference?)
Adding namespace did it
new System.IO.StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd()
Hope this saves you some time
For me #Matas Vaitkevicius answer gave
error CS1061: 'HttpContextBase' does not contain a definition for
'Current' and no extension method 'Current' accepting a first argument
of type 'HttpContextBase' could be found (are you missing a using
directive or an assembly reference?)
Replacing HttpContext.Current with System.Web.HttpContext.Current did it for me
new System.IO.StreamReader(System.Web.HttpContext.Current.Request.InputStream).ReadToEnd()
Hope this saves you some time
Any of these answers could work if the position of the steam is at position 0.
HttpContext.Current.Request.InputStream.Position = 0;
var body = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();

Resources