Have master page label display last edit date of child page being displayed - master-pages

i'm building an asp.net site with master pages. When visitors views a page, I'd like to show the date and time the child page was last updated. I'd also like to do this all at the master page level so no code for getting this information needs to be added to each child page.
Is this possible? what would be the best way to do it?
Thank you in advanced!

Page.Request.PhysicalPath will give you the physical path of the page.
And the FileInfo class can be used to get its last update date.
There are caveats if you are redirecting using Server.Execute or Server.Transfer, in which case there are several alternative ways of doing this, including the one described in the Remarks section of the MSDN documentation for HttpRequest.PhysicalPath.

Typically, this is what I put in my *_master.vb code-behind files. And I use a base MainMaster.vb class with the Public LastUpdate As DateTimeproperty.
Protected Overrides Sub OnLoad(e As System.EventArgs)
MyBase.OnLoad(e)
Dim fi As System.IO.FileInfo = New System.IO.FileInfo(Page.Request.PhysicalPath)
LastUpdate = fi.LastWriteTime
label_lastUpdate.Text = String.Format("{0} à {1}", LastUpdate.ToLongDateString(), LastUpdate.ToLongTimeString())
End Sub

Related

connect two gsp screens to three domains in grails

so I am working on a web app when the users click on create on the list screen, it takes them to a page where they have to enter some information and then they click on "next" and it will take them to another gsp page where they have to enter data for two domains but none of the data are stored yet in the tables but when they click on "create" button, everything get stored in the database
I was looking for examples but couldnt find any.
I know how to call the record and edit it since all the domains or the tables share id number so I can use it to retrive data. but my problem is when I transfer from the first gsp screen to another I want to save the instance and then when the users click on create, data goes to the three tables
any idea how to do that? I am still beginner and trying to learn
thank you
It sounds kind confusing what you wanna do and I am not sure I completely understood. Because you want to change the whole page, and yet, not to lose those previous answers, right?. Is there a specific reason why you want to do this?
I believe you could sent all the information from the first gsp to a controller and save everything in the "session" (e.g session.name = params.name, session.age = params.age), redirect/render the other gsp and later on, you get the info back from the session plus the info that just came and save everything. This is probably not a very good solution, but this is the only way I figured this out.
:)
Just an idea, I haven't used it until now, but I will some day in the future to modify the dialog-flow in my current application...:
Wouldn't that be a good example for the webflow-plugin?
This is what command objects are used for. Any time you have a collection of data that you want to collect in a form and then "generate" multiple domain objects from, then this is the way.
The idea is to create a single class that has all the information that you want to collect on the form. You post the filled form data back to the controller save action which then validates that the data is complete using the command object constraints. Once you are happy with everything, you then use the data in the command object to create/update your domain objects.
We consider the use of command objects a Grails best practice. You can provide custom validation support in the command object that looks for and validates relationships in the data that are difficult to do with the domain objects. We often write factory methods in the command class that produce a new or updated domain object, making it very convenient for unit testing.
See the "Command Objects" section of the "Web Layer" in the manual for details. In Grails 2, command objects are classes with the #Validateable annotation and in Grails 3 they implement the Validateable trait. If you declare your command class as an inner class in the controller, then it is automatically validateable. We've found that we prefer to declare them in src/groovy rather than as inner classes because they are easier for someone unfamiliar with the code to find.
So amongst all of these answers you have your answer but in all honesty I think it is well beyond your own comprehension at this point.
Assuming you have this example as a form
http://code.runnable.com/UevQr3zfd_oaAAGn/jquery-ui-tabs
On tab 1 you have
Name
Age
On tab 2 you have
Address
Postcode
Then you have two domain class
Class User {
String name
String age
Address address
}
Class Address {
String address1
String postcode
}
So a user has name age and also binded to address, whilst address has address1 and postcode
now your controller action
def save(MyBean bean) {
Address address = new Address(bean.loadAddress()).save()
User user = new User()
def userMap = bean.loadUser()
user.age=userMap.age
user.name=userMap.name
//The above object that got saved first
user.addresss=address
user.save()
render "hopefully this should have saved it as expected"
}
In src/main/groovy/yourPackage/MyBean.groovy
package yourPackage
import grails.validation.Validateable
Class MyBean implements Validateable{
String name
String age
Address address
String address1
String postcode
//Now declare your constraints like your domainClass add validator where required to add additional verification/validation to your objects sent back
//This will return all the objects required as a map to save address domain class
protected Map loadAddress() {
Map results=[:]
results.with {
address1=address1
postcode=postcode
}
return results
}
//this will return the user object
protected Map loadUser() {
Map results=[:]
results.with {
name=name
age=age
}
}
}
Other fairly complex validation bean examples:
PhotosBean CustomerChatBean ScheduleBaseBean
Other points of reference:
As I say I think as a beginner this may take you a while to get your head around but hoping with what is provided it will become a lot clearer now
E2A
It is really complicated!! can I have two gsp screens instead of jquery tabs
That doesn't make much sense.
You can have two actions which one just passes params onto 2nd gsp ?
So
def TestController {
def index() {
render view: page1
}
//where page 1 is the first form and submits to action2
//action2 picks up parmas from page1
def action2() {
render view: page2, model:[params:params]
}
}
in page2.gsp you have
<g:form action="action3">
<g:hiddenField name="originalName" value="${params.originalValue}"/>
<g:hiddenField name="originalName2" value="${params.originalValue2}"/>
<g:hiddenField name="originalName3" value="${params.originalValue3}"/>
Then your actual form content
The problem with doing this this way, is does action2 need to verify params received from page1 ? if so it needs to either render original page or page2 depending.
Once submitted to page2 the hiddenFields can be tampered with by end user so what was validated may be invalid now. You will need some form of a way of revalidating all those again.
Using validation methods above you could just call the validate() functions or maybe build some md5 check of initial values vs what is now sent from page2.
Either way if you don't care about validation and just want to see it work then above is the simplest way.
can I have two gsp screens instead of jquery tabs
in page1 you can just do <g:include action="page2"> and include a 2nd gsp within first but in all honesty page 1 could have just contained both actions in 1 page. which is why it don't make sense

How to sucessfully link to another cms page in Umbraco

I am growing increasingly frustrated with Umbraco. I've been working on an Umbraco project for a little while now and I have been unable to figure out how to solve my problem (one of many).
Scenario - I have a content managed page and on this page users can search for things (these things come from an entirely different database to Umbraco). This is fine, I've created a child action which loads the form for search and created the controller method which returns the results. However, each result I need to link to another content managed page (the same content managed page for each result) that takes an ID so I can inject some dynamic data into the content managed page.
Great, I've got a method for handling this request in my surface controller and I can create an Html.ActionLink for each result that when clicked hits my controller action with the id parameter.
Problem - When each link is clicked the url that gets hit is
http://localhost:5645/umbraco/surface/{controllername}/{actionname}/?id={id}
However this request is outside the Umbraco context, so when I try to return any page with the following controller code, I get the following error:
[ActionName("ShowDetials")]
public ActionResult GetProperty(int propertyId)
{
return View("~/Views/TestView.cshtml");
}
Cannot render a macro when UmbracoContext.PageId is null.
So my initial thoughts were to have a separate controller which inherits from Umbraco.Web.Mvc.RenderMvcController and try to handle the request in there, but then this raises other issues like being unable to use #Html.ActionLink to link to a RenderMvcController, I also don't want to have two controllers to handle content from the same section.
The other issues I have is passing custom models to the view.
If anyone can help me, I would be eternally grateful.
For any developer having this same issue the only way I have been able to solve it is by having two controllers. A surface controller to handle the initial rendering of the search form and page and to display the results of the search, then a separate rendermvccontroller to handle clicking on an individual result and displaying a 'details' page.
However, this in my opinion isn't great and I would still greatly appreciate it if anyone has another solution.

Editing Master Detail Records using Linq-2-Sql

I'm using Linq-2-Sql as ORM in asp.net mvc-3 application. First have a look at the form:
This is a master-detail form for editing batch info. Master part (Batch table) includes BatchNo, SKUTitle, StageID and Date field. Detail part (BatchDetail) contains fields PackingInstruction, ExpectedYield, Units and TargetDate. I have managed to save this information on single page in create scenario like
public ActionResult CreateBatch(Batch batch, BatchDetail detail)
{
batch.BatchDetails.AddRange(detail.ToList());
ctx.Batches.InsertOnSubmit(batch);
ctx.SubmitChanges();
}
but edit scenario is quite tricky. in this form as shown in figure above, user can add new records in detail portion, delete and edit existing records and by the time data is posted to controller we have no way of knowing which records are newly added, which are modified and which are deleted. So, as a consequence I have to do something like
public ActionResult EditBatch(int id, BatchDetail detail)
{
var batch = ctx.Batches.SingleOrDefault(x=>x.BatchID == id);
ctx.BatchDetails.DeleteAllOnSubmit(ctx.BatchDetails.ToList());
UpdateModel(batch);
batch.BatchDetails.AddRange(detail);
ctx.SubmitChanges();
}
I hate that part of deleting detail records in this scenario. is there a way in Linq-2-Sql that I can get around deleting all records in similar scenarios? If not can I accomplish this in EF without unnecessary deletion?
Edit
I have been studying Attach method of System.Data.Linq.Table but can't seem to figure out anything.
In the MVC Music Store Demo there is a small part that covers deleting items from the shopping cart by using JQuery AJAX to call the delete Controller action. The example is in part 8 of this tutorial.
The actual AJAX call explanation is about 3/4 of the way down the page. The headline for the section is "Ajax Updates with jQuery" if you want to search and find it quickly.

Providing data to Menu in my ASP.NET MVC Master Page

We are beginning the process of moving from Web Forms to MVC for all of our new applications. I am working on porting our Master Page over and am trying to satisfy the requirements that we need a single master page to be used by all applications. The primary navigation for the application needs to be in a menu within the master page. Accomplishing this was easy, the hard part is that each application may need to determine what to display in the menu using a unique set of rules. Some apps can simply say, here's the menu structure to use via something like a SiteMap. Others need to determine what is displayed in the menu based on what roles the user has, this can also be handled easily with a SiteMap. The situation that I'm struggling with is that some apps need to generate the menus based on the roles the user has, but also on the data on which they are working. i.e. The same user may have different option in the menu for a page if they are working on object 'foo' than they do if working on object 'bar'.
What I've done at this point, is I've created an HtmlHelper that is called by the master page view and takes a list of objects of a custom type and returns an unordered list that is styled by a jQuery plugin to display the menu. The list of objects the helper method takes are passed to the view using the ViewData dictionary. Currently, the value of this ViewData node is set within the constructor of each controller. This allows each page, and potentially each method, to set a different menu without having to set the value in each action method, unless its needed. I have also created a class that parses a SiteMap and returns the list of items needed to build the menu. This class is what I'm using to set the ViewData value in the controller. The idea being that if an application needed more control of how the menu data was generated, they could create their own class to generate the data as long as it returns a list of the correct type of objects.
This solution seems to work fine so far, it just doesn't 'feel' right for some reason. I'm hoping that I can either get some ideas of better way to do this or some reassurance that this is a valid approach to solving this problem.
If it is something that will be on every page, do something like this:
Create a base controller:
public class MyBaseController : Controller
Have this controller get the data it needs and send that data in the ViewData["menu"] to the View. Then have all your controllers inherit from this one:
public class HomeController : MyBaseController
In the Master Page, loop through your ViewData and create your menu.
(I did something like this for my sub-menu which displayed a list of categories.)
In the book I am reading (Pro ASP.NET MVC Framework by Apress) they use Html.RenderAction for the menu in the masterpage. I am a Asp.net MVC novice so maybe somebody else can give more info about this.
You can download the sourcecode at apress.com though so maybe that could help.

Is there a way to have OutputCache ignore the master page in asp.net mvc?

I have an action that returns a view with a master page with a logon user control at the top. When I set outputcache, it caches the entire output including the current user, so everybody would see whoever was the last person to hit the page to refresh the cache as the current user. Is there a way to prevent the master page from being included in the cache?
I am using the following code:
[OutputCache(Duration=3000, VaryByParam={params})]
public ActionResult {actionName}({params})
{
{codeGoesHere}
}
There was a concept of "donut caching" (excluding parts of a page from the output cache) but it didn't made it in asp.net MVC 1. For solution to your problem you can try this workaround.
Output cache is associated with the controller, not the view. A controller may return different views, based on the passed parameters. Caching may also be done by parameters (like you have in your example). When the result of a controller is cached, that cached value is the view's generated html (including the master page if any). So, the short answer is, no, you can't exclude the master page from the cache.

Resources