I want to know, what's the best way to create a custom back button with parameters?
My example:
I have 4 pages that depend on each other and in these pages I have some actions like updating, deleting, creating and after these actions I need to go back on the last page I was before I am
So I have an ID, which I set on the first page and I have this same ID as the parameter for each page.
If I use the back button of the browser, I will have 2 problems .. 1- If I use it after an action, the browser will redirect to the same page as I am and the second time I click this button it will redirect me to the last page .. 2- will redirect me but no parameters.
And I have an obstacle, I have to clear the URL, so after all '?' I have to clean it, so I use this function:
function cleanUrl() {
urlpg = $(location).attr('href');
urllimpa = urlpg.split("?")[0]
window.history.replaceState(null, null, urllimpa);
setInterval("window.status = ''", 1);
}
Currently, I have this: #Html.ActionLink("","","",new { my parameters })
And this parameters I have an object like:
ObjPreviousPage
{
ID
Filter
Search
}
So, on all of my pages i have this:
#Html.ActionLink("","","", new { ID = x, Filter = "y", Search = "z" })
So I want to know, if have a way to better this or if this way isnt recommended
instead trying to find a hack to do this. I suggest you to rethink your concept how and when is someone redirected to a new URL.
So this could be also helpful to understand the basics
Related
Currently I have a view that has just a single form with three values. When a user submits the form with those three values, my controller checks if all three values actually have a value other than being empty, and if they do then it calls my service that fetches data.
public IActionResult Index(string clientName = "", string tableName = "", string date = "")
{
if (!string.IsNullOrEmpty(clientName) && !string.IsNullOrEmpty(tableName) && !string.IsNullOrEmpty(date))
{
// Unimportant stuff for setting temp variables for FetchData parameters removed
TheData = _fieldDataService.FetchData(tempAcr, tempID, tableName, date, numRows);
}
return View(TheData);
}
My goal is to make the view display a loading icon or something while the data is being fetched. I've looked into JQuery and Ajax but I have no experience with either and cannot figure out how to apply them to my specific task. Since I am using Asp.Net Core, I also looked into using Blazor, but I couldn't wrap my head around it either.
Could somebody point me in the right direction as to what I should/could use to solve this problem? I have a vague understanding that there needs to be some sort of asynchronous function that retrieves the data, but nothing more than that.
You need to fetch the data with JavaScript and manipulate the UI to show a loader. But anyway, a request like this should be so fast, that you don't even need a loader.
I'm also a bit worried that you are passing a tableName as input parameter. You aren't just string concatenating the query right? You might be susceptible to SQL injections, see https://en.wikipedia.org/wiki/SQL_injection.
To do a request with JavaScript, look into the XMLHttpRequest, see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest, or the new way of doing it with fetch(...), see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch.
This answer shows a more practical example: Display loading image while ajax fetches file content.
I have an application in MVC5/C#
My index view is a simple list from a model. I added an additional html actionlink to view the history of any selected item. With this link, I am going to a different controller (ICS_HistoryView) and passing an id parameter.
Originally it broke because some of the items (Old_ItemID field) have / in them, causing the link to break. So, after some research, I learned that I can use Replace to replace / with -, so the url will not break and then switch it back in the controller of the new view. However, I am getting a null error when the view loads, on this line
#Html.ActionLink("History", "History", "ICS_HistoryView", new { id = item.Old_ItemID.Replace('/', '-')}, null)
But, without the Replace, it loads properly. Only when I click the History link, does the url break with the / in the parameter.
#Html.ActionLink("History", "History", "ICS_HistoryView", new { id = item.Old_ItemID}, null)
Can someone help me understand why it becomes null when I use replace and breaks the code?
I can provide the controller code if needed, but it's really simple. This is just a list view.
Example:
Old_ItemID = VNC/2/1
Without the Replace, I get the correct url with parameter VNC/2/1 but I get page not found, obviousl
Adding Replace, I get a null error - and I don't understand why
The only reason I suspect for this error is when item.Old_ItemID is null.
Otherwise it works fine for string with any value including empty string.
Could you try adding null-condition operator like item.Old_ItemID?.Replace("/","-")
For best practice, I would suggest such manipulations in Model/Domain classes.
Create a Get property or a method in Item (or whatever class that is) to replace tokens in URL.
i.e.
public string OldItemIdForUrlGeneration => this.Old_ItemID.Replace("/", "-");
and then
#Html.ActionLink("History", "History", "ICS_HistoryView", new { id = item.OldItemIdForUrlGeneration }, null)
So I have this page which will show an individual record from a database. So my URL will look like:
mysite.com/Vehicle/Edit/1
or it may end it 2,3,4,5 etc.. depending on the record its on. Basically I need a link in this page that will take me to another page but have the same value in the url, so it could look like:
mysite.com/Owner/Add/1
Or it could end in 2,3,4,5 etc.. depending on which record the link was in.
How do I do this using C# MVC, im using Razor if that makes any difference.
Thanks
You'll want to use one of the Html.ActionLink helpers.
Say you're passing in a Model to your view that has a property called Id. You could use Html.ActionLink like this:
#Html.ActionLink("Add Owner", "Add", "Owner", new { id = Model.Id }, null)
The first argument is the text that the link will display.
The second argument is the name of the Action to call.
The third argument is the name of the Controller the Action is in.
The fourth argument is the route values for the Action.
The fifth argument is for html attributes. Say you wanted to add a class to your link. Instead of null, you could use new { #class = "my-link-class" }. Notice the # in front of class. That is because class is a reserved word. If you were setting style, you would just do this: new { style = "background-color: #ffffff;" }.
All of this is assuming your Add Action takes in an int id. So something like this:
public ActionResult Add(int id)
{
// Do stuff.
}
Here are the docs for the specific Html.ActionLink overload I used in my example: http://msdn.microsoft.com/en-us/library/dd504972(v=vs.108).aspx
See this post to get the URL. How to get current page URL in MVC 3
Once you have the url, you can just pick off the trailing characters after the final '/'
I've got an index page which sends users to an edit products page on separate browser tabs.
For each products edited the index rewrites the Session["ProductID"].
The Edit page then has the following code to have a unique identifier for this tab and product:
if (!IsPostBack) //first time page load
{
Random R = new Random(DateTime.Now.Millisecond + DateTime.Now.Second * 1000 + DateTime.Now.Minute * 60000 + DateTime.Now.Minute * 3600000);
PageID.Value = R.Next().ToString();
Session[PageID.Value + "ProductID"] = Session["ProductID"];
}
This works, and when the same user opens multiple tabs I only reference the Session[PageID.Value + "ProductID"] in my code so that I always have the proper ID. (I'm working in a trusted environment this is for an intranet, therefore I'm not too bothered with the level of security).
My issue occurs if the user does a page refresh by hitting the F5 key. At which point the Session[PageID.Value + "ProductID"] gets the Session["ProductID"] of the last product he opened.
For example:
User 1 opens product1 in tab1
User 1 opens product2 in tab2
Whenever they use the tool normally, everything works fine. However if:
User 1 on product1 page hits the refresh button (F5) the product1 page becomes product2 page
Is there a way to detect a page refresh from a "first load/redirect from another page" so that I can then tell my page not to update my Session[PageID.Value + "ProductID"]?
Personally, I would go for URL parameters. E.g. pass the product IDs as URL parameters.
If you need the pages without parameters, you could e.g.
Pass parameter to page.
Page reloads itself if parameter is present and removes the parameter
This way you could distingues between first call (=parameter present) and second+ call (parameter not present).
I've solved a very similar issue by storing two versions of a state-identifying parameter: one in Session and one in either the ViewState or the URL (QueryString).
If you compare the two values on Page_Load, that will tell you whether the session variable has changed since the page was first loaded. This should be just what you need.
EDIT: Rough sketch of the code (warning - haven't seen the actual code since I wrote it 3 years ago):
protected string currentProductID
{
get
{
return Request.QueryString["ProductID"];
//or:
//return (string)ViewState["ProductID"];
//or:
//return HiddenField1.Value;
}
set
{
Response.Redirect(ResolveUrl("~/MyPage.aspx?ProductID=" + value));
//or:
//ViewState.Add("ProductID", value);
//or:
//HiddenField1.Value = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
//If the problem only occurs when not posting back, wrap the below in
// an if(!IsPostBack) block. My past issue occurred on both postbacks
// and page refreshes.
//Note: I'm assuming Session["ProductID"] should never be null.
if (currentProductID == null)
{
//Loading page for the first time.
currentProductID = (string)Session["ProductID"];
}
else if (currentProductID != Session["ProductID"])
{
//ProductID has changed since the page was first loaded, so react accordingly.
//You can use the original ProductID from the first load, or reset it to match the one in the Session.
//If you use the earlier one, you may or may not want to reset the one in Session to match.
}
}
In the above code, note that changes to the ViewState (including the value of a Hidden control) will only take effect on the next PostBack. On a refresh, they'll revert to their most recent value. In my case, that was what I wanted, but it sounds like it's not quite right for your situation. Still, that information could be useful to you, depending on how you implement this.
I've left out a discussion of comparing currentProductID to Session[PageID.Value + "ProductID"], since I've already posted a lot of code, and I don't know the details of what you're trying to do. But there are various ways you can use Session, ViewState, and the QueryString to glean information about the state and history of the page.
Hopefully that should give you the general idea. Let me know if that's not enough to get you going.
You may want to have a look at this. I think it's close to what you're looking for.
Very new to JQuery and MVC and webdevelopment over all.
I'm now trying to accomplish this and is asking for a bit of advise:
I'm basically trying to build a filter with 4 input elements, and 1 output.
I have 4 select (drop down) elements in my page. As soon as one of them is changed, I need to build a href and get the partial view with the return values.
My question is now if I should try to build the href in the select element or if I can do it once in jquery, and don't have to have duplicated code. How would I accomplish this?
each dropdown should be class="FilterSelect" or something like that
when any of them change, it'll fire off a request to a URL that needs to be specified in a context available to all selects.
the following pseudo-code should give an idea:
$('.FilterSelect').change(function()
{
var data = {} // you need to get the selected items of each dropdown somehow
$.get($(this).parents('#FilterContainer').attr('href'), data, function(response)
{
$('#ContentArea').html(response);
}
});
Just to note: you shouldn't build your URL in jQuery because client-side logic shouldn't be concerned with the rules required to build a URL that corresponds to the server-side routing.
.... & also to note: I don't know if this is even valid jQuery! .parents('#FilterContainer')
You can certainly do it once in jQuery in the modular way you're looking for. Something like:
$('select').bind('change',function(e){
// Our select changed. Send it's selected option's value onwards...
getView(this.options[this.selectedIndex].value);
});
And then, somewhere else:
function getView(url){
$.ajax( url : '/your/url/' + url, success : function(){ }, error : function(){ });
}
Basically, store the URL pieces as values for the options in your dropdowns. Observe the change events and fire off the appropriate request. You can make this as modular as you want (I'd store the URL as a constant, make the whole thing a module, etc.) but this is a good starting point.