I started experimenting with MVC 3. And I'm stuck with applying the style of an input-button.
Is it possible to apply Css in the View? The code I gave is located in the View.
<input id="newSubItem" type="button" onclick="location.href='javascript:void(0);'" value='New Subitem' /><br/>
Did you try
<input id="newSubItem" class="myCSSClass" type="button" onclick="location.href='javascript:void(0);'" value='New Subitem' />
You have to put link in the view to your css page :
<link href="#Url.Content("~/CSSPAGE.css")" rel="stylesheet" type="text/css" />
And then you can apply any class you want,for example
<input id="newSubItem" class="CSSClass1" type="buttononclick="location.href='javascript:void(0);'" value='New Subitem' />
Related
I know this topic is already uploaded but I don't think it's fully answered The name 'isPost' does not exist in the current context (ASP.NET with Razor)
So, I am trying to add a map to my ASP.NET MVC web page and I am using this documentation - Displaying Maps in an ASP.NET Web Pages (Razor) Site. I don't know if it's only me but when it gets to reading & understanding documentation I kinda suck.
I am using a temp .cshtml file to try and make it work but right now I am stuck and don't really know how to move forward.
here is the code:
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Map an Address</title>
<script src="~/Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
</head>
<body>
<h1>Map an Address</h1>
<form method="post">
<fieldset>
<div>
<label for="address">Address:</label>
<input style="width: 300px" type="text" name="address" value="#Request["address"]" />
<input type="submit" value="Map It!" />
</div>
</fieldset>
</form>
#if (IsPost)
{
#Maps.GetGoogleHtml(Request.Form["address"],
width: "400",
height: "400")
}
</body>
</html>
Right now I have two main problems:
The name 'Request' does not exist in the current context
The name 'IsPost' does not exist in the current context
The name 'Maps' does not exist in the current context
How do I define them so that I can display the map properly?
Can we render a Blazor component as an independent DOM fragment, or somehow else consume it as a standard Web Component within a vanilla HTML/JS page?
This might be a naive question from the Blazor architectural standpoints. I am not a Blazor expert by far, but I think it can be a useful technique for incremental "brownfield" modernization of legacy web applications. I'm surprised this doesn't appear to be officially supported.
To illustrate, consider this simple web component example, which renders a custom element <date-info>:
// define a custom web component
customElements.define("date-info", class DateInfo extends HTMLElement {
constructor() {
super();
// create an "open" (vs "closed") shadow DOM,
// i.e., accessible to the outside JavaScript
this.attachShadow({ mode: "open" });
}
async connectedCallback() {
console.log(`${this.constructor.name}.${this.connectedCallback.name} called`);
// get the content from the server,
// this could be a Blazor component markup
try {
const response = await fetch("https://worldtimeapi.org/api/ip");
const data = await response.json();
const content = new Date(data.utc_datetime).toString();
this.shadowRoot.innerHTML = `<span>${content}</span>`;
}
catch(e) {
console.error(e);
const info = document.createTextNode(e.message);
this.shadowRoot.appendChild(info);
}
}
});
<!-- use the web component -->
<p>Current time: <date-info/></p>
Now, instead of fetching https://worldtimeapi.org/api/ip, I'd like to fetch and render a detached markup for a Blazor/Server component, e.g.:
#* this is a Blazor component *#
<p>#(DateTime.Now)</p>
Moreover, I'd expect this markup to remain functional and dynamic, i.e., the client-side DOM events and the server-side updates for this Blazor component to further propagate both ways, through the life cycle of the wrapping web component.
It's surely possible to make it a Blazor #page and load it into an iframe, but I'm rather looking to render it as a part of the outer page's DOM.
So far, I've come across this:
Apparently, that wasn't one of Blazor design goals back in 2018:
https://github.com/dotnet/aspnetcore/issues/16033.
Later Steve Sanderson created an (unofficial) library to test Blazor components in isolation, which in theory can be used to get a standalone Blazor component markup: https://stackoverflow.com/a/60457390/1768303.
Is it the best approach to tackle this problem, so far?
MS has addressed this limitation, but the solution requires .Net 6.
https://github.com/aspnet/AspLabs/tree/main/src/BlazorCustomElements
This was done by the man himself, Steve Sanderson.
In the meantime you can mix the old cshtml with razor components.
I use this approach to maintain the same graphic layout between the two systems.
An example, the following file is _Layout.cshtml used by Identity.
I've used various Blazor components via static rendering:
#using Microsoft.AspNetCore.Hosting
#using Microsoft.AspNetCore.Mvc.ViewEngines
#inject IWebHostEnvironment Environment
#inject ICompositeViewEngine Engine
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#using Project.Server.Shared
<!DOCTYPE html>
<html>
<head>
<component type="typeof(MainLayoutHead)" render-mode="Static" />
</head>
<body>
<app>
<div class="container main">
<component type="typeof(MainLayoutTopImages)" render-mode="Static" />
<div class="row navmenu-row">
<div class="col-md-12 bg-dark navmenu-col">
<component type="typeof(NavMenu)" render-mode="Static" />
</div>
</div>
<div class="row content pt-4 pb-0 mt-0">
<div class="col-md-12">
<div class="row">
<div class="col-md-12">
#*Required for GDPR.*#
<partial name="_CookieConsentPartial" />
</div>
</div>
<div class="row body-row">
<div class="col-md-12 body-col">
#RenderBody()
</div>
</div>
</div>
</div>
<component type="typeof(MainLayoutFooter)" render-mode="Static" />
</div>
</app>
<script src="~/Identity/lib/jquery/dist/jquery.min.js"></script>
<script src="~/Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/Identity/js/site.js" asp-append-version="true"></script>
#RenderSection("Scripts", required: false)
</body>
</html>
The MainLayoutHead, MainLayoutFooter and NavMenu are regular Blazor components.
Not sure if this helps but you can definitely do it from a server side page (I'll delete this answer if it doesn't). Here's a test page that renders all three standard "pages" inside a cshtml page with server side content. You need to actually forget the "page" concept in Blazor. EVERYTHING is a Component. Pages are just components with a Page custom attribute.
The problem with this setup is that as soon as you refresh the page you restart the three components and you lose any scoped data.
#page "/test"
#namespace StackOverflow.Answers.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>StackOverflow.Answers</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="StackOverflow.Answers.styles.css" rel="stylesheet" />
</head>
<body>
<div class="m-2 p-s bg-light">
<h3>A Normal Razor Page</h3>
<p>
Lots of server side rendered junk
</p>
<component type="typeof(StackOverflow.Answers.Shared.SurveyPrompt)" render-mode="ServerPrerendered" />
</div>
<div class="m-2 p-s bg-info">
<h3>A Normal Header</h3>
<p>
Lots More server side rendered junk
</p>
<component type="typeof(StackOverflow.Answers.Pages.Counter)" render-mode="ServerPrerendered" />
</div>
<div class="m-2 p-s bg-light">
<h3>A Normal Header</h3>
<p>
Lots More server side rendered junk
</p>
<component type="typeof(StackOverflow.Answers.Pages.Counter)" render-mode="ServerPrerendered" />
</div>
<div class="m-2 p-s bg-light">
<h3>Yet Another Normal Header</h3>
<p>
Lots More server side rendered junk
</p>
<component type="typeof(StackOverflow.Answers.Pages.FetchData)" render-mode="ServerPrerendered" />
</div>
<div class="m-2 p-s bg-light">
<h3>Yet Another Normal Header</h3>
<p>
Lots More server side rendered junk
</p>
<component type="typeof(StackOverflow.Answers.Pages.FetchData)" render-mode="ServerPrerendered" />
</div>
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
Reload
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
For my application, i want to have a hidden iframe with a form inside, which has some input fields. The value to the fields will be added based on the response i get from backend and then submit the form. The problem is on the browser the content inside iframe is commented out like below
form tag in browser
My html code is like below
<html>
<head>
</head>
<body>
<div class="ddc-iframe-3ds">
<iframe height="1" width="1" style="display: none;" >
<form id="collectionForm" method="POST" action="https://secure-test.worldpay.com/shopper/3ds/ddc.html">
<input type="hidden" id="ddcBin" name="Bin" value="" />
<input type="hidden" id="ddcJWT" name="JWT" value="" />
</form>
</iframe>
</div>
</body>
</html>
in the below link, to integrate with payments, it is suggested to use hidden iframe with a form inside
3DS payment integration
What i'm trying to do is change the theme of the application using a check box that is populated as dark or light from the server's session.
I know the theme (Style Sheet) can be changed with JavaScript but that leads to loading the default Bootstrap Style Sheet then the dark one which causes the screen to flicker.
What I need to do is return the css from the server thought a post method like below.
<div>
<form id="theme-switcher" method="post">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" asp-for="IsDark" id="theme" />
<label class="custom-control-label" for="theme">Theme</label>
</div>
<button id="change" type="submit" class="btn btn-primary">Change</button>
</form>
</div>
The code above can be in a view component or a partial view but I can not seem to find a way to post the from.
_Layout.cshtml
#{
bool isDark = HttpContext.HttpContext.Session.GetBoolean("IsDark");
}
<!-- Custom styles -->
#if (CultureInfo.CurrentUICulture.Name == "ar-LB")
{
if (isDark)
{
<link rel="stylesheet" type="text/css" href="~/css/site-dark-rtl.css">
}
else
{
<link rel="stylesheet" type="text/css" href="~/css/site-rtl.css">
}
}
else
{
if (isDark)
{
<link rel="stylesheet" type="text/css" href="~/css/site-dark.css">
}
else
{
<link rel="stylesheet" type="text/css" href="~/css/site.css">
}
}
What I've tied so far is partial views and view components but as far as I've found partial views can not have code behind with OnPost (when adding #page to the partial view I get view data can not be null although the model and the view data are set) and view components can not call methods.
What approach should I use ?
You can post to different routes, regardless of where you currently are. So assuming you have a Razor page SwitchTheme.cshtml with a code-behind that switches the theme on POST, then you can adjust your <form> tag to post to that page:
<form asp-page="/SwitchTheme" method="post">
<!-- … -->
</form>
Note the use of the asp-page tag helper to generate the action attribute with a link to the page.
For changing things like the design, which doesn’t directly have some page content you want to display, you could also use a simple controller that makes the change and then redirects back. Then, you would use the asp-action and asp-controller tag helpers instead:
<form asp-controller="Utility" asp-action="SwitchTheme" asp-route-returnUrl="#Context.Request.Path" method="post">
<!-- … -->
</form>
public class UtilityController : ControllerBase
{
[HttpPost]
public IActionResult SwitchTheme([FromForm] bool isDark, string returnUrl)
{
// switch the theme
// redirect back to where it came from
return LocalRedirect(returnUrl);
}
}
When Im publish my .core mvc app no matter if I lunch it by .exe or in IIS my custom partial views doesnt render. This is how it should look (when Im debbugin it localy or publish to .exe and change environment to development):
And this is how it looks after publishing on production environment:
I've noticed that after triger event that make this partial view appear in working example url doesnt change(this is what I want) and looks like this https://localhost:5002/CharacterAndItems/Index but in secound one it changes https://localhost:5002/CharacterAndItems/GetCharacter
I have no idea what causes this this problem. Here is my controller code:
[HttpPost]
public async Task<IActionResult> GetCharacter([FromForm] CharacterFindViewModel characterFindModel)
{
var character = await _characterSerivce.GetCharacterByNameAsync(characterFindModel.CharacterName);
var item = await _itemSerivce.GetItemNameReturnItem(characterFindModel.ItemName, character);
model = new CharacterWithItemViewModel { character = character, item = item };
return PartialView("_CharacterPartial", model);
}
Partial view code:
#model App.ViewModels.CharacterWithItemViewModel
<div class="row form-group" style="margin-top:15px">
<div class="col-md-6">
<div class="text-right">
<div>
<div class="text-left align-top">
Name: #Model.character.CharName CharacterId: #Model.character.ObjId ItemId: #Model.item.ItemId
<div id="Test">
Count: #Model.item.Count
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 text-right">
<form asp-controller="CharacterAndItems" asp-action="AddItems"
data-ajax="true" data-ajax-method="post"
data-ajax-mode="replace" data-ajax-update="#Test">
<input type="hidden" name="characterId" value="#Model.character.ObjId" />
<input type="hidden" name="itemId" value="#Model.item.ItemId" />
<input class="form" placeholder="Item quantity" name="count" style="text-align:center" />
<input type="submit" value="Add items" name="add" class="btn btn-primary" />
<input type="submit" value="Delete items" name="delete" class="btn btn-danger" />
</form>
</div>
</div>
#section Scripts {
<script>
$.ajax({
url: '/CharacterAndItems/AddItems',
type = 'POST',
data: JSON.stringify(#Model)
})
var results = $("#Results");
</script>
}
The fact that it even shows up means your partial view IS in fact being served. From the screenshots you've shown, it looks like you are missing your css files.
Open you prod site in chrome developer tools and inspect if the CSS files you are expecting are there, further check that they are accessible.
In Core, go to your layout page and in the header, you will see something like below. It is telling it where and what to load based upon its operating environment. Dev vs Prod. Make sure those are valid. Alos make sure that your org is not blocking a CDN if you are using one as some have rules around their network.
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
crossorigin="anonymous"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"/>
</environment>
Based on your screenshots, it doesn't look like styling is being applied when in production, which would also suggest you're facing a similar problem with necessary JavaScript files. However, we don't have your layout to see what the problem might be.
My best guess is that you have something like:
<environment include="Development>
<script src="~/js/script.js"></script>
</environment>
<environment exclude="Development>
<script src="~/js/script.min.js"></script>
</environment>
I'm just using an example of a JS file here, but the same probably applies to your CSS as well, i.e. the production reference includes a .min.js/.min.css extension, instead of just .js/.css.
By default, there's nothing that will take your JS/CSS files and minify them into .min.js/.min.css versions, so those files likely just don't even exist in production. Since all your JS/CSS file references are 404s, the style and functionality you expect don't exist either.
To have these files created, you either need to include a bundleconfig.json, or set up build tasks with something like Gulp or Grunt.
Also, FWIW, you cannot include sections in a partial, so that #section block isn't doing anything.