Add parameter to MVC application - asp.net-mvc

I've got an MVC application with basic view:
myapp.com/category
and a switcher to second one:
myapp.com/category/list
App is used as independent one and as also in other application into iframe where src is: myapp.com/category. I want do not show page header when it is used into iframe, how can I achieve it? I was trying to add querystring, myapp.com/category?show=false, and set this as iframe src, but when I switch to the second view the parameter is not passed.

You could create a helper method to construct URLs that would keep the show parameter in place. For example:
public static string GetModifiedUrl(this UrlHelper helper, string url)
{
string qstring = helper.RequestContext.HttpContext.Request.QueryString["show"];
if (!string.IsNullOrEmpty(qstring)) url += "?show=" + qstring;
return url;
}
Then in the views, for example:
<a href='#Url.GetModifiedUrl(Url.Action("Index", "Home"))'>Home</a>
Another option is to create add a value to the session on the first request, and use that instead. Ie, put some logic in the controller like this:
var qs = Request.QueryString["show"];
if (!string.IsNullOrEmpty(qs))
{
Session["show"] = qs;
}
Then in the views, use #Session["show"] instead of #Request.QueryString["show"] to decide whether you show the header.

Break the main view into two partial views.
Then, when calling for the master/external app, call the partial view that has just the content.
When calling the regular native app, call a VIEW that contains both the partial views (header as well as content).

Related

ServiceStack Razor - Html.RenderAction equivalent

I have the requirement to use Html.RenderAction like you would in ASP.NET MVC.
For instance I have a Home Page with News and Products on.
I would like to do for instance
#Html.RenderAction("/api/products/featured")
Which would start a new service call and output the template to the html stream.
Is this possible using ServiceStack Razor and if so how do I accomplish it?
The PartialExamples.cshtml test page shows different examples of rendering a razor view inside a page, e.g:
Using the new RenderToAction() method which lets you execute a Service and it's rendered partial view with a route and QueryString, e.g:
#Html.RenderAction("/products/1")
This also takes an optional view name if you want a different view than the default:
#Html.RenderAction("/products/1", "CustomProductView")
There's also the normal Html.Partial() to specify which view and model you want to render in the page, e.g:
#Html.Partial("GetProduct",
base.ExecuteService<ProductService>(s => s.Any(new GetProduct { Id = 1 })))
ExecuteService is simply a wrapper around the equivalent ResolveService in a using statement, i.e:
#{
Response response = null;
using (var service = base.ResolveService<ProductService>())
{
response = service.Any(new GetProduct { Id = 1 });
}
}
#Html.Partial("GetProduct", response)
The new RenderToAction() method in Razor Views was added in v4.0.34+ which is now available on MyGet.
*I may be duplicating my answer or I lost it somehow
Looking at the ServiceStack.Razor.ViewPage class there is an Html property of type ServiceStack.Html.HtmlHelper. I don't see 'RenderAction' as a method (or extension method) on this class so it doesn't appear to be available. There is a 'Partial' method that takes the ViewName and an overload that takes a ViewName and an object. Based on your above comment this doesn't appear to be a useful solution.
If I'm correct about the above, I think you'd need your 'Featured View Template' to pull in the data. Could add soemthing like
{ FeaturedResponse products = new JsonServiceClient("http://localhost").Get<FeaturedResponse>("/api/products/featured"); }
to your template. This would allow you to use the products variable like a Model.
Or, use JavaScript to pull the data into the template. You would have have to use JavaScript to get your data into the HTML elements, though.
You could then render the template using #Html.Partial('Featured')
Hope this helps.

Display partialview based on a url

I have a partialview in _Layout.cshtml that I only want to display for certain urls.
My first thought was in my partial I would use a string as the model #model String .
In the actionmethod that is called I would return this
return PartialView("_MyPartial", new string{Request.FilePath});
In the partial I would have an if block wrapping my outer div that would check the model to see if the url it contained was the url that can display the partial.
I don't like this way because I would have to hardcode the url in if block check
#if( Model == "/Test/Home")
{
<div>
Just an example
</div>
}
What would be the best way to do this?
Thanks
You shouldn't need to use hard coded strings, even if you did the validation within your view like you initially intended.
You can use
Request.Url.AbsolutePath
to get your current url and
Url.Action("action", "controller")
to generate the inacceptable locations.
That said, I would keep your logic determining whether to show the partial view within your controller.
if(showPartialView)
return PartialView("_MyPartial");
else
return new EmptyResult();
Deciding actions based on the request is the responsibility of the Controller. Since the controller chooses the view, why not have it choose the partial as well? Figure out what, if any, partial you want in your controller, and pass it to the view on your view model.

ASP.NET MVC : does a partial know if it is bring requested from another page?

I have a partial view which can either be requested via an Action (Action2 in the image below), or rendered inside another page with "Html.Action()" (Action1 in the image below). From within the partial (or the partials controller) is there a way to determine which of these two methods were used to render the page?
You can use ControllerContext.IsChildAction or check DataTokens whether there is something with key "ParentActionViewContext" if you don't have access to ControllerContext.
You should be able to get it from
HttpContext.Current.Request.RawUrl
It should be noted that it is not particularly good practise to do this sort of thing in MVC. The partial should not be concerned about its "parent" ... but if you do need to do this, for whatever reason ...
You can use this code in the partial view's controller to determine if it was loaded directly or included in another page.
// this is the route which was originally used to route the request
string req_controller = Request.RequestContext.RouteData.Values["controller"].ToString();
string req_action = Request.RequestContext.RouteData.Values["action"].ToString();
// this is the route which was used to route to this action/view
string this_controller = RouteData.Values["controller"].ToString();
string this_action = RouteData.Values["action"].ToString();
if (req_controller == this_controller && req_action == this_action)
{
// this partial was loaded directly
}
else
{
// this partial was loaded indirectly
}
my reason for wanting to know this is that I wanted to be able to switch the Layout of a partial view based on whether or not it was rendered from a controller action or from within another page.
ie.
return PartialView("MyView.cshtml");
would result in a layout with the requisite menu bars and other site trimmings.
and
#Html.Partial("MyView")
would just embed the content without adding the rest of the page.
so, in my page's default Layout I have:
#if (this.IsPartial()) {
Layout = null;
} else {
Layout = "_SiteLayout";
}
#RenderBody()
here's what I found:
public static bool IsPartialResult(this WebPageBase #this)
{
return !#this.OutputStack.Any(writer => writer is HttpWriter);
}
it probably won't work in all situations. but it works for me. YMMV/HTH
No, there is no way and a partial shouldn't need to know it.

Retrieving and caching HTML from website using ASP.NET MVC 3

I want a partial view that display some stuff from a website that is not under my control.
The data on the website is only available through HTML, and thus I can only retrieve it by querying the web site and parsing the HTML. (The website holds a list of 50 elements, and I only want the top 10.)
Now, the data from the website is not changing very frequently, so I imagine that I can retrieve the HTML on an hourly basis, and displaying a cached version on my web site.
How can I accomplish this in ASP.NET MVC 3?
Ignoring the MVC3 requirement for now, you should look to using WebClient to grab the html from the website. You can do something like:
var client = new WebClient();
var html = Encoding.UTF8.GetString(client.DownloadData("http://www.somedomain.com"));
If you need to tailor your request, I'd recommend looking at HttpWebRequest, HttpWebResponse. Now that you can grab the html, you need to consider your caching mechanism, possibly in the ASP.NET runtime?
public ActionResult GetHtml()
{
if (HttpRuntime.Cache["html"] == null)
GetHtmlInternal();
return Content((string)HttpRuntime.Cache["html"], "text/html");
}
private void GetHtmlInternal()
{
var html = // get html here.
HttpRuntime.Cache.Insert("html", html, null, DateTime.Now.AddMinutes(60), Cache.NoSlidingExpiration);
}
The first solution that comes to mind is to create an action in a controller that makes an Http request to the remote web page and parses the html you want to return to your own page and then set output caching on your action.
Edit:
What controller to put the action in would depend on the structure of your web site and whether the partial view would be visible on all views or just a specific view. If the partial is visible in all views I'd either place it in the Home controller or create a "General" controller (if I anticipated more actions would go in such a controller).
If you want to manipulate the result I would probably make a model and partial view for the list. If you want to take a part of the returned html and output it as it is I would use the same method as in the answer by Matthew Abbott:
return Content(yourHtmlString);
The end would look something like this:
[OutputCache(Duration = 3600)]
public ActionResult RemoteList()
{
var client = new WebClient();
var html = Encoding.UTF8.GetString(client.DownloadData("http://www.somedomain.com"));
// Do your manipulation here...
return Content(html);
}
(Some of the above code was borrowed from the post by Matthew Abbott.)
You could just add OutputCache attribute on your action and set OutputCache.Duration Property to 3600 seconds (1 hour)

MVC and JQuery UI Tabs - How do I anchor to tabs from various actions?

I have a details view for courses. On that view, I have a lot of information, so I broke it up into nice JQuery UI Tabs sections and everything is great...except...
Some of the tabs have forms on them. For instance, upload course materials, add tasks, edit rosters, etc... after I submit any of the forms, I want to perform the action on my controller and then redirect to the details view again, only this time I want to be anchored to the tab that I was on before I submitted. According to the Tabs documentation, it's just as simple as adding #tabs-4 or #tabs-n to the end of the URL, but I'm not sure how to tell my controller how to do that...
so if one of my form's controller action is (simplified)
public ActionResult CreateTask(Task task)
{
db.Add(task);
db.Save();
//I want to go to /details/id + #tabs-4. How?
return RedirectToAction("Details", new { id = task.CourseID });
}
and then details is (simplified)
public ActionResult Details(int id)
{
Course course = db.GetCourse(id);
// How do I tell the view to open #tabs-4 or 3 or 2??
return View(course);
}
Additionally, I'd like to have other methods that redirect to the same details view, but instead give it a #tabs-3, #tabs-2, etc, so I assume I have to set that up in the first method, and pass it to the details action.
var url = Url.RouteUrl(new { action = "Details", id = task.CourseID });
return Redirect(url + "#tabs-4");
You can use UrlHelper.GenerateUrl method, passing your anchor as fragment.
I would add an extension method to UrlHelper to wrap a call to GenerateUrl, as it takes 10 parameters and you do not need to provide all of them manually in all the cases.

Resources