How to get RouteData.Value in class in ASP.NET webforms - c#

I am getting route data value in Page_Load but I want to get this value in a class.
string id = Page.RouteData.Values["id"]; // works in Page_Load
I have tried this code in a class but it didn't work. It's returning null. I don't want to check in Page_Load() on every page. I just want to check using a function in a class if it's possible.
RouteData routeData = HttpContext.Current.Request.RequestContext.RouteData;
if(routeData != null)
{
var id = routeData.Values["id"];
}
else
{
// Routedata returning null;
}
Any idea?

Related

Is there a way to prevent null object errors from complex objects when the page is refreshed?

I've got a controller action that is using TempData to get complex objects from another action. The issue happens when the user refreshes the page and gets null object errors on the view. The complex objects are not passed through the URL like the other values are. Is there a way to prevent this from happening? An alternative solution would be to remove all query parameters from the URL on a page refresh and display the view like it was a new object.
Controller
public IActionResult Daily(Daily daily)
{
new ReportDaily().GetAvailableSavedCriteria(out List<ReportCriteria> reportCriteria, out Notification not);
if (daily.SelectedCriteria == null) {
//Create daily report object and initialize the default values
var newModel = new Daily
{
PaymentTypes = DGetPaymentTypes(),
Users = DGetUsers(),
Criteria = reportCriteria,
StartDate = DateTime.Today.Date,
EndDate = DateTime.Today.Date,
County = true,
Municipality = true
};
return View(newModel);
}
else
{
daily.PaymentTypes = TempData.Get<List<Daily.PaymentType>>("PaymentTypes") == null ? DGetPaymentTypes() : TempData.Get<List<Daily.PaymentType>>("PaymentTypes");
daily.Users = TempData.Get<List<Daily.User>>("Users") == null ? DGetUsers() : TempData.Get<List<Daily.User>>("Users");
daily.Criteria = reportCriteria;
return View("Daily", daily);
}
}
TempData only used for a single redirect, to keep the data from another action after refreshing, you can use Session to achieve it.
To use Session in core mvc, you need to add following codes to the starup.cs fileļ¼š
Add services.AddSession(); in ConfigureServices method.
Add app.UseSession(); in Configure method.
To save complex object in Session,you can convert the list object into a json format for storage, and then deserialize it into a list object when you get it.
HttpContext.Session.SetString("PaymentTypes", JsonConvert.SerializeObject(pamentTypeList));
Daily Action:
//.....
daily.PaymentTypes = HttpContext.Session.GetString("PaymentTypes") == null ? DGetPaymentTypes() : JsonConvert.DeserializeObject<List<Daily.PaymentType>> (HttpContext.Session.GetString("PaymentTypes"));

retrieving session variable from another controller

Is is possible to retrieve a Session variable from a different controller it was created from?
I create this in my Account controller
System.Web.HttpContext.Current.Session["Session"] = sessionGuid;
and from a different controller I'm trying
if (System.Web.HttpContext.Current.Session["Session"] != null)
{
return Json(System.Web.HttpContext.Current.Session["Session"].ToString());
}
return null;
which always returns null.
as a Test I added some code to my Login controller and in that part i do get the value out of it
if (System.Web.HttpContext.Current.Session["Session"] != null)
{
test = System.Web.HttpContext.Current.Session["Session"].ToString();
}
else
{
test = "no";
}
i always got the actual result, not the"no" part of the code
For some reason its different into how i have to access the session, at the other controller i changed to this code and it worked
if (HttpContext.Session["Session"] != null)
{
return Json(HttpContext.Session["Session"].ToString());
}
return null;
if controller is within the same website/virtual directory then YES, however if you are saying your session was created in a different site and you trying to access it within a controller which belongs to different site then you cannot.

Value getting reset between ajax calls in Controller

In my controller, the method that returns the View also initializes a few values for some class-level properties:
private string igc = String.Empty;
private string igcCode = String.Empty;
private bool isSuggested = false;
public ActionResult Codes(Codes objCodes)
{
try
{
FillDropDowns(objCodes);
igc = String.Empty;
if (objICDCodes.FromWhere.IndexOf("MedicalInfo-Suggested") >= 0)
{
igc = objCodes.FromWhere.Remove(0, "MedicalInfo-Suggested-".Length);
igcCode = igc.Substring(0, igc.IndexOf("-")).Trim();
objCodes.ICGCode = igcCode;
isSuggested = true;
}
}
catch (Exception ex)
{
//logging error
ElmahLogUtility.ErrorException(ex);
}
return View(base.GetViewPath("Codes"), objCodes);
}
Additionally, there is this method which gets called to bind data to a grid on the page:
public JsonResult GetSelectedCodesInfo(List<SearchField> searchFields, GridDataSourceRequest request)
{
//creating the instance of DataSourceResult.
DataSourceResult dataSourceResult = null;
try
{
// Creating the instance of CommonBLL to load the values.
CommonBLL objCommonBLL = new CommonBLL();
if (isSuggested)
{
searchFields.Add(new SearchField() { ElementName = "aIGCode", Value = igcCode });
searchFields.Add(new SearchField() { ElementName = "aFor", Value = "EtiologicDiagnosis" });
}
// Getting the Codes information and storing in the DataSource Result.
dataSourceResult = objCommonBLL.GetSelectedCodesInfo(searchFields, request);
}
catch (Exception ex)
{
//Logging the Exception
ElmahLogUtility.ErrorException(ex);
}
// Returning the Result.
return Json(dataSourceResult, JsonRequestBehavior.AllowGet);
}
isSuggested gets set to true when the View is created, but when the data is bound to the grid isSuggested is set to false for some reason.
My grid is defined in a Razor view like so:
#Html.Grid("CodesSelectionGrid").ReadSource("Controller", "GetSelectedCodesInfo").OnGridDataBound("AssignCodeValues").Lazyload(true).EnableGrouping(false).EnableSorting(true).PageSize(10).Height("390px").Width("610px").EnablePaging(true).EnableFiltering(false).EnableMultiSelect(true).SelectionMode(SelectionMode.Single, "GetSelectedCodeDetails").RowSelection(GridRowSelection.None).ShowToolBar(true).SelectionCSSClass("icd-editable-cell").PageButtonCount(3)
That .ReadSource("Controller", "GetSelectedCodesInfo") bit is what refers to the Controller and the method on the controller to call. So, it's calling the second snippet of code above.
I must be accessing two separate instances of my Controller class, but I do not know how to solve this problem. How can I do this? How could I have my grid pass a reference of the Codes object? Then I could just get the values from there for the grid...
This is the expected behavior. isSuggested is a class level variable. Every time you make an Http request, a new instance of your controller will be created. That means the variable will be initialized to false. Remember, Http is Stateless :)
If you want to persist a variable value between multiple http calls, you need to persist it. You have different options like
Persist to a database table and read from that in the second call
Write to a file in disk and read from that in the second call
Save to user session and read from that in the second call

How do i keep the Sharepoint context when moving around an ASP.NET MVC application without using the query string?

I'm building a small application in MVC 4.5. I've got an Azure database, and i'm using code first with the Entity framework to set it up. The app is hosted on my development sharepoint area.
The Home controller's Index() Action has the [SharePointContextFilter] and loads, among other things, the username of the logged in user. When the application is debugged and this first action runs, the Sharepoint {StandardTokens} get appended to the url, so SPHostUrl and AppWebUrl and a few other variables get added to the query string.
If i navigate away to an action without the [SharePointContextFilter] it works fine, until i navigate back to the action with the [SharePointContextFilter]. Then i get an error saying:
Unknown User
Unable to determine your identity. Please try again by launching the app installed on your site.
I assume this is because a few of the Sharepoint {StandardTokens} are missing, because if i manually append them to the link like so:
#Url.Action("Index", "Home", new { SPHostUrl = SharePointContext.GetSPHostUrl(HttpContext.Current.Request).AbsoluteUri })
and mark the other action with the [SharePointContextFilter] as well, it still works.
Hovever this seems like a needlessly complex way to solve this problem. I don't want to mark every single action in my app with the [SharePointContextFilter], and manually insert the {StandardTokens} into the query string for every link i create. Shouldn't it be possible to save this information to session or a cookie in some way, so i don't have to do this?
For reference, here is some code:
HomeController.Index(), the first Action that is run.
[SharePointContextFilter]
public ActionResult Index()
{
User spUser = null;
var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
using (var clientContext = spContext.CreateUserClientContextForSPHost())
{
if (clientContext != null)
{
spUser = clientContext.Web.CurrentUser;
clientContext.Load(spUser, user => user.Title);
clientContext.ExecuteQuery();
ViewBag.UserName = spUser.Title;
}
}
return View();
}
Here is the [SharePointContextFilter] attribute (generated by visual studio):
/// <summary>
/// SharePoint action filter attribute.
/// </summary>
public class SharePointContextFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
SharePointContext currentContext = SharePointContextProvider.Current.GetSharePointContext(filterContext.HttpContext);
Uri redirectUrl;
switch (SharePointContextProvider.CheckRedirectionStatus(filterContext.HttpContext, out redirectUrl))
{
case RedirectionStatus.Ok:
return;
case RedirectionStatus.ShouldRedirect:
filterContext.Result = new RedirectResult(redirectUrl.AbsoluteUri);
break;
case RedirectionStatus.CanNotRedirect:
filterContext.Result = new ViewResult { ViewName = "Error" };
break;
}
}
}
The links that i use. From the _Layout.cshtml file.:
<li id="Home">Home</li>
<li id="Contract">Avrop</li>
If i try to use these links from an Action that isn't marked with the [SharePointContextFilter] filter, the SPHostUrl isn't found. If i try to link to an Action which is marked with the [SharePointContextFilter] filter, i get the aforementioned error if the SPHostUrl isn't included.
This basically creates a situation where i can navigate away from the filtered actions, but then i can never return to them.
I hope this was clear enough.
We had the same problem - ASP.NET MVC 4.5. There are two things that worked for us:
1) There is a spcontext.js file (included in the solution - you just have to add a reference to it) that will automatically append the tokens to the URL for you. However, we were given a requirement that the URL must look "nice," so we went with option 2..
2) Put the context in the session. Have the filter first look to see if you have the context in your session, and if it's there, then use that. If not, try the query string and put the retrieved context in your session. This means that you originally have to access your site with the tokens attached to your url string, and it also means that your context will be in the session for however long that's alive - so you have to decide if that's ok.
Another option would be to comment out the validation of the SPHostUrl in the SharePointContext class at the two places shown below. It works fine without it and voids the need for passing around QueryString parameters as it will just pull it from the Session state.
Location 1 is in public SharePointContext GetSharePointContext(HttpContextBase httpContext):
/// <summary>
/// Gets a SharePointContext instance associated with the specified HTTP context.
/// </summary>
/// <param name="httpContext">The HTTP context.</param>
/// <returns>The SharePointContext instance. Returns <c>null</c> if not found and a new instance can't be created.</returns>
public SharePointContext GetSharePointContext(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
// Commented out to allow it to work without the SPHostUrl being passed around
//Uri spHostUrl = SharePointContext.GetSPHostUrl(httpContext.Request);
//if (spHostUrl == null)
//{
// return null;
//}
SharePointContext spContext = LoadSharePointContext(httpContext);
if (spContext == null || !ValidateSharePointContext(spContext, httpContext))
{
spContext = CreateSharePointContext(httpContext.Request);
if (spContext != null)
{
SaveSharePointContext(spContext, httpContext);
}
}
return spContext;
}
Location 2 is in protected override bool ValidateSharePointContext(SharePointContext spContext, HttpContextBase httpContext):
protected override bool ValidateSharePointContext(SharePointContext spContext, HttpContextBase httpContext)
{
SharePointAcsContext spAcsContext = spContext as SharePointAcsContext;
if (spAcsContext != null)
{
// Commented out to allow it to work without the SPHostUrl being passed around
//Uri spHostUrl = SharePointContext.GetSPHostUrl(httpContext.Request);
string contextToken = TokenHelper.GetContextTokenFromRequest(httpContext.Request);
HttpCookie spCacheKeyCookie = httpContext.Request.Cookies[SPCacheKeyKey];
string spCacheKey = spCacheKeyCookie != null ? spCacheKeyCookie.Value : null;
// Commented out to allow it to work without the SPHostUrl being passed around
//return spHostUrl == spAcsContext.SPHostUrl &&
return !string.IsNullOrEmpty(spAcsContext.CacheKey) &&
spCacheKey == spAcsContext.CacheKey &&
!string.IsNullOrEmpty(spAcsContext.ContextToken) &&
(string.IsNullOrEmpty(contextToken) || contextToken == spAcsContext.ContextToken);
}
return false;
}
Make sure the landing page of your App which will receive the initial request with the SPAppToken variable in the HTTP Post calls SharePointContext so the session variable will be created. This can be done by adding the following attribute either above your MVC Controller class or above your MVC Action method:
[SharePointContextFilter]
Or instead calling the following line of code from the MVC Controller:
SharePointContextProvider.Current.GetSharePointContext(HttpContext);

Session is coming null in handler in asp.net?

I want to access session in handler for that i am inheriting "IRequireSessionState" Class. but while evaluating the session it is coming null, but on the web page it has value. i dont know why this is happening my code of handler is:
public void ProcessRequest(HttpContext context)
{
String Name = Common.GetSessionValue("UserId").ToString() ;
// my code.........
Here is my common method to Get Session's value
public static Guid GetSessionValue(string SessionName)
{
Guid returnvalue = Guid.Empty;
if (HttpContext.Current.Session[SessionName] != null)
{
returnvalue = new Guid(HttpContext.Current.Session[SessionName].ToString());
}
else
{
HttpContext.Current.Response.Redirect("Login.aspx");
}
return returnvalue;
}
Please help me. Thanks in advance
You can try this by Exposing the value to the outside world http://forums.asp.net/t/1506625.aspx/1 and then trying to fetch the value in handler using
context.Request.Form["returnvalue"];
You can see the exposed value in firebug AddOn in Mozilla

Categories