I am new to C# and Razor v3.
I have a php web app that I am trying to convert to ASP.NET. I decided, mainly due to ease, to use Razor. What I am making is a Single Page App.
The way I have it laid out in PHP is via 3 php files, 1 of which essentially passes the variable values to the main index.php like so, for example
vars.php
if (isset($_GET["lang"])) {
$lang = mb_strtolower($_GET["lang"]);
} else {
$lang = "el";
}
and this is how my index.php uses that variable
<html lang=<?php echo "\"".$lang."\"";if($page2go===1) {echo " itemscope itemtype=\"http://schema.org/Article\"";}?>>
Now, everytime index.php is called, I call on vars.php by using
<?php require_once('./scripts/vars.php');?>
This is how my values are passed into my index.php.
I have found I can do the similar by including my if statements and variable delcarations at the top of my index.cshtml. Like so
#{
var lang = "";
if (!String.IsNullOrEmpty(Request.QueryString["lang"]))
{
var interior = Request.QueryString["lang"];
interior.ToLower();
lang = interior;
}
else
{
lang = "el";
}
}
Now I perform a LOT of if operations like that, making my index.cshtml an absolute mess.
Is there a way to pass the variable values, like I do in php by including vars.php?
Thanks a lot for your time.
You should recreate your one-page application to an MVC application.
All the request processing (and other complex logic) will take place in the controller action.
The controller action will in turn pass all variables that you need to the view that you have created.
Related
I have an aspx code behind file that has method that is trying to redirect to an MVC route in the same project. The MVC and Webforms live side by side in the same web project and I have no problems there, but when I try to redirect to an MVC area/controller/action from an ASPX page code behind it cant find the area im looking for. It throws an error that is using the wrong area.
In my case I have a Utilities area and its trying to use that instead of the one I want. Does anyone know why this would be failing like that? Even though I specified the area in the route parameters?
Heres an example of what im trying to do.
Response.RedirectToRoute(new
{
area = "Billing",
controller = "BhpReport",
action = "CreateReport",
startDate,
salesLocation
});
But I end up with this error
The controller for path '/Utilities/BhpReport/CreateReport' was not found or does not implement IController.
As you can see, im not trying to go to Utilities im trying to go to Billing.
Are you trying to access Utilities anywhere else in the code? Doesn't seem like the code you have posted would impose that error.
Also Reponse.Redirect excepts a string or string and a bool as parameters. So try:
Response.Redirect("/BhpReport/CreateReport")
or
return RedirectToAction("CreateReport", "BhpReport")
Update
If the purpose is to send startDate and salesLocation to the CreateReport action, you could try:
return RedirectToAction("CreateReport", "BhpReport", new { sd = startDate, sl = salesLocation })
And in the CreateReport action you do:
public ActionResult CreateReport(string startDate, string salesLocation) {
// do stuff
}
I ended up figuring out how to use the RedirectToRoute method correctly.
Response.RedirectToRoute("Billing", new
{
controller = "BhpReport",
action = "CreateReport",
startDate,
salesLocation
});
This was the solution, I needed to separate out the area into a "route" variable, then add a new object for route values.
I have problem with this:
var id=5;
var el = $("MainPhotoHolder");
el.attr("src", '#Url.Content("~/Page/GetImage/" + id)');
id is a local javascript variable, but it gives me an error saying that is not in the context. My question is how do i point out that it should be a javascript variable and not a c# one ...?
You cannot mix JavaScript and Razor in this way. Razor does not have any reference to it so it cannot use it to generate your link. Try this:
el.attr("src", '#Url.Content("~/Page/GetImage/")' + id);
You might have to use "Url.Action" if you're serving the images from a controller rather than a static repository.
I am pretty sure I am doing something wrong here. I have been developing a web app using MVC and Razor and I never thought of using the form element. Now so much has already been done with master pages and sub pages that it means restructuring most of our code in order to use form element and the would result in multiple form elements on a page.
That aside, in Asp.Net if I wanted to access any control in the C# code behind I could just give it an ID="SomeID" and a RUNAT="SERVER". Then in my code behind I could set its value and properties.
When I do this in Razor, I use lines like:
<input id="hiddenPostBack" runat="server" type="hidden" />
Why can't I access this in the controller? I want to detect a postback and set the value to false if it is the first time the page loads, and if not, then set the value to true. Then based on this, I will read it either server side or client side and do something.
My real question is, how do I "do something" both server side and client side given that I don't have a form element. I was under the impression that if I wanted to pass values from client to server and back, the easiest way to do this is with a hidden input. But I am just not getting how to accomplish this with MVC3 and razor.
A move from WebForms to MVC requires a complete sea-change in logic and brain processes. You're no longer interacting with the 'form' both server-side and client-side (and in fact even with WebForms you weren't interacting client-side). You've probably just mixed up a bit of thinking there, in that with WebForms and RUNAT="SERVER" you were merely interacting with the building of the Web page.
MVC is somewhat similar in that you have server-side code in constructing the model (the data you need to build what your user will see), but once you have built the HTML you need to appreciate that the link between the server and the user no longer exists. They have a page of HTML, that's it.
So the HTML you are building is read-only. You pass the model through to the Razor page, which will build HTML appropriate to that model.
If you want to have a hidden element which sets true or false depending on whether this is the first view or not you need a bool in your model, and set it to True in the Action if it's in response to a follow up. This could be done by having different actions depending on whether the request is [HttpGet] or [HttpPost] (if that's appropriate for how you set up your form: a GET request for the first visit and a POST request if submitting a form).
Alternatively the model could be set to True when it's created (which will be the first time you visit the page), but after you check the value as being True or False (since a bool defaults to False when it's instantiated). Then using:
#Html.HiddenFor(x => x.HiddenPostBack)
in your form, which will put a hidden True. When the form is posted back to your server the model will now have that value set to True.
It's hard to give much more advice than that as your question isn't specific as to why you want to do this. It's perhaps vital that you read a good book on moving to MVC from WebForms, such as Steve Sanderson's Pro ASP.NET MVC.
If you are using Razor, you cannot access the field directly, but you can manage its value.
The idea is that the first Microsoft approach drive the developers away from Web Development and make it easy for Desktop programmers (for example) to make web applications.
Meanwhile, the web developers, did not understand this tricky strange way of ASP.NET.
Actually this hidden input is rendered on client-side, and the ASP has no access to it (it never had). However, in time you will see its a piratical way and you may rely on it, when you get use with it. The web development differs from the Desktop or Mobile.
The model is your logical unit, and the hidden field (and the whole view page) is just a representative view of the data. So you can dedicate your work on the application or domain logic and the view simply just serves it to the consumer - which means you need no detailed access and "brainstorming" functionality in the view.
The controller actually does work you need for manage the hidden or general setup. The model serves specific logical unit properties and functionality and the view just renders it to the end user, simply said. Read more about MVC.
Model
public class MyClassModel
{
public int Id { get; set; }
public string Name { get; set; }
public string MyPropertyForHidden { get; set; }
}
This is the controller aciton
public ActionResult MyPageView()
{
MyClassModel model = new MyClassModel(); // Single entity, strongly-typed
// IList model = new List<MyClassModel>(); // or List, strongly-typed
// ViewBag.MyHiddenInputValue = "Something to pass"; // ...or using ViewBag
return View(model);
}
The view is below
//This will make a Model property of the View to be of MyClassModel
#model MyNamespace.Models.MyClassModel // strongly-typed view
// #model IList<MyNamespace.Models.MyClassModel> // list, strongly-typed view
// ... Some Other Code ...
#using(Html.BeginForm()) // Creates <form>
{
// Renders hidden field for your model property (strongly-typed)
// The field rendered to server your model property (Address, Phone, etc.)
Html.HiddenFor(model => Model.MyPropertyForHidden);
// For list you may use foreach on Model
// foreach(var item in Model) or foreach(MyClassModel item in Model)
}
// ... Some Other Code ...
The view with ViewBag:
// ... Some Other Code ...
#using(Html.BeginForm()) // Creates <form>
{
Html.Hidden(
"HiddenName",
ViewBag.MyHiddenInputValue,
new { #class = "hiddencss", maxlength = 255 /*, etc... */ }
);
}
// ... Some Other Code ...
We are using Html Helper to render the Hidden field or we could write it by hand - <input name=".." id=".." value="ViewBag.MyHiddenInputValue"> also.
The ViewBag is some sort of data carrier to the view. It does not restrict you with model - you can place whatever you like.
As you may have already figured, Asp.Net MVC is a different paradigm than Asp.Net (webforms). Accessing form elements between the server and client take a different approach in Asp.Net MVC.
You can google more reading material on this on the web. For now, I would suggest using Ajax to get or post data to the server. You can still employ input type="hidden", but initialize it with a value from the ViewData or for Razor, ViewBag.
For example, your controller may look like this:
public ActionResult Index()
{
ViewBag.MyInitialValue = true;
return View();
}
In your view, you can have an input elemet that is initialized by the value in your ViewBag:
<input type="hidden" name="myHiddenInput" id="myHiddenInput" value="#ViewBag.MyInitialValue" />
Then you can pass data between the client and server via ajax. For example, using jQuery:
$.get('GetMyNewValue?oldValue=' + $('#myHiddenInput').val(), function (e) {
// blah
});
You can alternatively use $.ajax, $.getJSON, $.post depending on your requirement.
First of all ASP.NET MVC does not work the same way WebForms does. You don't have the whole runat="server" thing. MVC does not offer the abstraction layer that WebForms offered. Probabaly you should try to understand what controllers and actions are and then you should look at model binding. Any beginner level tutorial about MVC shows how you can pass data between the client and the server.
You are doing it wrong since you try to map WebForms in the MVC application.
There are no server side controlls in MVC. Only the View and the
Controller on the back-end. You send the data from server to the client by
means of initialization of the View with your model.
This is happening on the HTTP GET request to your resource.
[HttpGet]
public ActionResult Home()
{
var model = new HomeModel { Greeatings = "Hi" };
return View(model);
}
You send data from client to server by means of posting data to
server. To make that happen, you create a form inside your view and
[HttpPost] handler in your controller.
// View
#using (Html.BeginForm()) {
#Html.TextBoxFor(m => m.Name)
#Html.TextBoxFor(m => m.Password)
}
// Controller
[HttpPost]
public ActionResult Home(LoginModel model)
{
// do auth.. and stuff
return Redirect();
}
When a user comes to my site, there may be a template=foo passed in the query string. This value is being verified and stored in the Session.
My file layout looks like this:
- Views/
- Templates/
- test1/
- Home
- Index.cshtml
- test2/
- Home
- List.cshtml
- Home/
- Index.cshtml
Basically, if a user requests Index with template=test1, I want to use Views/Templates/test1/Index.cshtml. If they have template=test2, I want to use Views/Home/Index.cshtml (because /Views/Templates/test2/Home/Index.cshtml doesn't exist). And if they do not pass a template, then it should go directly to Views/Home.
I'm new to MVC and .NET in general, so I'm not sure where to start looking. I'm using MVC3 and Razor for the view engine.
You can do this by creating a custom RazorViewEngine and setting the ViewLocationFormats property. There's a sample here that does it by overriding the WebFormViewEngine, but using the RazorViewEngine should work just as well:
public class CustomViewEngine : WebFormViewEngine
{
public CustomViewEngine()
{
var viewLocations = new[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx",
"~/AnotherPath/Views/{0}.ascx"
// etc
};
this.PartialViewLocationFormats = viewLocations;
this.ViewLocationFormats = viewLocations;
}
}
You could modify Scott Hanselman's Mobile Device demo to fit your needs. Instead of checking the user agent or if it's a mobile device, you could put your logic in to check the query string or your Session vars.
Are their any feature exist something like data template. i have a js file for my project who linked in all page using i linked them in master page.
I want to define their some constant who are define in a c# class called Globals. how i can configure or access them in my js file i used in my project.
i need a thing that when code is load on client system that some variable on the js file set from class c#.
suppose i define them in the code i write in Razor
var name #glboals.appName;
but if i define them in the file that they never render them as they render in the views.
so are their any way to applied constant in js file when file is standalone and not embedded in views.
so any sollution for this problem
Like this?
<html>
<!-- blah blah bla -->
<script>
var myFirstGlobalVar = '#Namespace.Class.Variable';
</script>
</html>
...
BTW, if you say MasterPage and then you show code with # we just don't know what are you talking about, it's a good thing to mention the version as a tag.
MasterPages are for WebForms and MVC 1 and 2, LayoutViews are for MVC 3
If you want to have this in a static file ... well, it's a static file, it does not get processed, so all you will see is the exact code you wrote.
To handle such things you need to process this file dynamically, so, lets add a Controller called DynamicScripts and an Action called JsVariables and add a normal return View();
use that view as a plain Javascript file that you set up variables, and you can pass any Model
Now, in your global.asaxcreate a new rule:
routes.MapRoute(
"CustomJs", // Route name
"Js/Variables", // URL with parameters
new { controller = "DynamicScripts", action = "JsVariables", id = UrlParameter.Optional } // Parameter defaults
);
and in your html jus add the line:
<link href="#Url.Content("~/Js/Variables")" type="text/javascript" />
There are more ways to do this, like using the RegisterStartUpScript, but the trick above (though I use it for CSS and not JavaScript) is what I use the most.
You can define script like this in views master, and use config in each view:
<script type="text/javascript">
var Config = {};
Config.appName = '<%= glboals.appName %>';
</script>
It's mvc2 example, you can do the same in razor.