In my project of MVC I am using OutputCache to cache page on both server and client side. Whenever I load page or reload page data is not coming from cache. Is there any explanation for this?
Controller:Main.cs
[OutputCache(Duration=3600)]
public ActionResult Main()
{
//some code
return View("~/Views/main.cshtml",DateTime.Now);
}
View:main.cshtml
#model DateTime
<h2>Hi</h2>
<h2>Hello</h2>
<h2>#Model</h2>
Related
I'm trying to learn IS4 at the moment, there's 3 projects in my solution: API, .NET MVC and IS4. My problem is when I starts the project, it redirect to IS4's login page, without going to the home page of the application. What did I do wrong?
I set the solution to start API, IS4, MVC - in that order:
And when the MVC project starts, I believe I set it to start at the home page:
And this is my controller's Index action:
[Authorize]
public class GalleryController : Controller
{
public async Task<IActionResult> Index()
{
//await WriteOutIdentityInformation();
var httpClient = _httpClientFactory.CreateClient("APIClient");
var request = new HttpRequestMessage(
HttpMethod.Get,
"/api/images/");
var response = await httpClient.SendAsync(
request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
using (var responseStream = await response.Content.ReadAsStreamAsync())
{
return View(new GalleryIndexViewModel(
await JsonSerializer.DeserializeAsync<List<Image>>(responseStream)));
}
}
}
How/why did it redirect straight away to IdentityServer's login page, skipping the Index page?
I don't think you are doing anything wrong. The [Authorize] attribute on your home page's controller will cause a redirect to IS to authenticate the user.
I'm calling my MVC post method from my php website using curl. The post method hits my API Controller which looks like this fine.
[HttpPost]
public ActionResult TransferView([FromBody] JObject data)
{
var userid = Convert.ToInt32(data["userid"]);
var clientid = Convert.ToInt32(data["clientid"]);
// Rest of Code here
return View(vm);
}
What isn't working is that on the return View it is using the url from the php project. I would like to open the View in my MVC project. Is there anyway for me to change routing to make this work or load the razor view differently? Any help would be much appreciated.
It is returning in the URL back to my php project.
ASP.NET Web API controller method cannot return View. It can return only status code or JsonResult. So your Web API controller method should be as follows:
[HttpPost]
public ActionResult YourMethodName([FromBody] JObject data)
{
var userid = Convert.ToInt32(data["userid"]);
var clientid = Convert.ToInt32(data["clientid"]);
// Rest of Code here
return Json(yourData);
}
Now you can generate view in your Client side (the app consuming the web API) using the returned data.
I am developing an Asp Net Mvc client that is consuming Asp Net Web Api. For some reasons I decided to use System.Net.Http.HttpClient class, instead of jQuery AJAX to send data and get it back from the web api. So the outline of my application flow is this - an mvc controller, by using some service that wraps HttpClient within, gets the model from the web api, and then this model is passed to a View and gets displayed. The problem I am facing now is how can I provide real time data on my views using this approach? If I was using AJAX, I could make some asynchronous calls with some intervals to the web api server directly from a View and without reloading the page display the changes. Can I do it somehow using HttpClient? If not, what are some other alternatives that will align with the approach I chose to communicate with the web api?
Take a look at the simplified code I wrote to better describe my issue:
This is the controller:
public class UsersController : Controller
{
private readonly IUserHttpService _userHttpService;
public UsersController(IUserHttpService userHttpService)
{
_userHttpService = userHttpService;
}
public async Task<ActionResult> Index(int userId)
{
try
{
User user = await _userHttpService.GetUserById(userId);
return View(user);
}
//some simplified exception handling
catch (Exception)
{
return View("UnexpectedError");
}
}
}
This is UserHttpService:
public class UserHttpService : IUserHttpService
{
private const string _baseUri = "http://localhost/rs-webapi/api/users/";
public async Task<User> GetUserById(int userId)
{
string requestUri = $"{_baseUri}getuserbyid?userId={userId}";
//Here using HttpClient I fetch the data from web api
//(and I know that it's better to have one HttpClient for the whole app,
//it's just for the sake of simplicity)
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage response = await httpClient.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsAsync<User>();
}
else
{
throw new System.Exception("Something went wrong");
}
}
}
}
And this is the View:
#model Entities.Entities.UserBase
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>First name: #Model.FirstName, Last name: #Model.LastName</p>
</body>
</html>
Now if the user first name or last name changes, I would like to be able to display it without reloading the page. What are my options?
Now if the user first name or last name changes, I would like to be able to display it without reloading the page. What are my options?
You can completely ignore the WebAPI part of your question here. This scenario is the same as any other MVC website - how do I communicate changes in data to the browser?
And the answers are the same:
Use AJAX.
Use SignalR.
You either have to poll from your browser to your MVC app (i.e., AJAX), or you have to keep an open connection and have the server push updates (e.g., SignalR).
i want to cache my page and use this type of caching
[OutputCache(Duration = 21600, VaryByParam = "none")]
public ActionResult Index()
{
//some codes
return View();
}
but i 'm confused this type of cache will stored on IIS or on client browser?
how can i cache my page on user browser not on the server?
Default asp.net cache pages everywhere it can (server, proxy, client). You can change this by attribute
[Output(Location=OutputCacheLocation.Any)]
You can set the Location property to any one of the following values:
OutputCacheLocation·Any
OutputCacheLocation·Client
OutputCacheLocation.Downstream
OutputCacheLocation.Server
OutputCacheLocation.None
OutputCacheLocation.ServerAndClient
If I receive a request from a Spider, I kick off a Phantom JS process and render back dynamic HTML. (Using a OnExecuting filter and setting the ActionResult)
But the OutputCache filter is in place on this method as well and it is getting in the way!.
E.G:
step 1. Load page with normal user agent. (Output cache caches the URL)
step 2. Load page with spider user agent. (the previous cached response is sent to the spider, and my Phantom JS filter never runs)
Use VaryByCustom to force a 'Cache Miss' when the request is from a Search Engine Crawler.
In your Controller/Action:
[OutputCache(VaryByCustom="Crawler")]
public ActionResult Index()
{
// ...
return View();
}
Then in your Global.asax:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg == "Crawler" && context.Request.Browser.Crawler)
return Guid.NewGuid().ToString();
return base.GetVaryByCustomString(context, arg);
}