shared ViewBag data with different action in MVC4 - asp.net-mvc-4

public ActionResult Completed()
{
ViewBag.PersonalInfo="";
ViewBag.Experience="";
ViewBag.Work="";
}
[HttpPost]
public ActionResult Publication(MainPageModel obj)
{
ViewBag.PersonalInfo="";
ViewBag.Experience="";
ViewBag.Work="";
}
[HttpGet]
public ActionResult Publication(MainPageModel obj)
{
ViewBag.PersonalInfo="";
ViewBag.Experience="";
ViewBag.Work="";
}
I used this ViewBag with this three action but I want to used like method
like
public void methodname()
{
ViewBag.PersonalInfo="";
ViewBag.Experience="";
ViewBag.Work="";
}
and call in different action methodname()
how to do it MVC4?
Is it possible to write like method ?

Related

Asp.net Core + Swagger : How to show APIs of type GET

How can I show only APIs of type GET in Swagger page and hide others?
I found that the attribute [ApiExplorerSettings(IgnoreApi = true)]
can hide the API from Swagger page, but I have lot of APIs to hide and I need an approach to hide the APIs depending on its HTTP type.
I've tried this approach :
public class SwaggerFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var nonGetPaths = swaggerDoc.Paths.Where(x => x.Value.Operations.First().Key != OperationType.Get);
var count=nonGetPaths.Count();
foreach (var item in nonGetPaths)
{
swaggerDoc.Paths.Remove(item.Key);
}
}
}
but it didn't work
Write a custom filter like this:
public class SwaggerFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var path in swaggerDoc.Paths)
{
foreach (var key in path.Value.Operations.Keys )
{
if (key != OperationType.Get)
{
swaggerDoc.Paths.Remove(path.Key);
}
}
}
}
}
Then configure in program.cs(.Net 6)
//.......
builder.Services.AddSwaggerGen(x=>x.DocumentFilter<SwaggerFilter>());
//......
I don't add [ApiExplorerSettings(IgnoreApi = true)] in my apicontroller and it works all fine.
But, Make sure Get endpoint and other type of endpoint have different route in the same controller, You can add attribute route like [HttpGet("/get")] on Get endpoint. If you just write like this in the same controller:
[HttpPost]
public IActionResult Post()
{
return Ok();
}
[HttpGet]
public IActionResult Get()
{
return NotFound();
}
Get and Post endpoint will have the same path. swaggerDoc.Paths.Remove(xxx); will remove all of them.
Reuslt:
Before
After

ASP.NET Core Web API - AmbiguousMatchException: The request matched multiple endpoints

I've been looking at this, but still cannot find a solution, here goes:
To return all players, I will pass in something similar to:
http://localhost:7777/api/teams/34fe3b6f-ba23-4657-820a-6c59dd49173a/players
To return a specific player on a specific team, I will pass in somethign similar to:
http://localhost:7777/api/teams/34fe3b6f-ba23-4657-820a-6c59dd49173a/players/f7de7974-9cbb-4c2c-884e-29036d6c2d76
I keep getting the following error:
System.ArgumentException: 'The route parameter name 'id' appears more than one time in the route template. '
Could someone please advise how to fix this?
[Route("api/Teams/{Id}/Players}")]
[ApiController]
public class PlayersController : ControllerBase
{
[HttpGet]
public IActionResult GetAllTeamPlayers(Guid id)
{
return Ok();
}
[HttpGet]
public IActionResult GetTeamPlayer(Guid id, Guid id2)
{
return Ok();
}
}
You should define the route parameters like this:
[Route("api/Teams/{teamId}/}")]
[ApiController]
public class PlayersController : ControllerBase
{
[HttpGet("players")]
public IActionResult GetAllTeamPlayers([FromRoute] Guid teamId)
{
return Ok();
}
[HttpGet("players/{playerId}")]
public IActionResult GetTeamPlayer([FromRoute] Guid teamId, [FromRoute] Guid playerId)
{
return Ok();
}
}

Resolve routes by named parameters

I have ASP Core 2.2 app. I defined controller:
using Microsoft.AspNetCore.Mvc;
namespace Web.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok();
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
return Ok();
}
}
}
When I request with url /api/users/3 everything works fine, method GetById is called. But if I try to request /api/users?id=3 method Get is called and I don't know how to fix that. Moreover I would like to create two similar method different only by parameter name. For example public IActionResult GetById(int id) and public IActionResult GetByAge(int age) so I need strict routing by named parameters if possible. I don't want to implement custom middleware to resolve routes myself I wanna try to find ASP feature for that.
The url /api/users/3 : "3" is used as part of the route value .
The url /api/users?id=3: "3" is used as a query string in the url .
Attribute routing with Http[Verb] attributes is the value of which is part of the route value
You could change the Route attribute above the controller to specify action name like below :
[Route("api/[controller]/[action]")]
[ApiController]
public class UsersController : ControllerBase
{
// Get api/users/get
[HttpGet]
public IActionResult Get()
{
return Ok();
}
//Get api/users/GetById/3
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
return Ok();
}
}
Reference :https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.2

dependency injection into view model class in asp.net core

I am using the following DTO class in one of my api controller class, in an asp.net core application.
public class InviteNewUserDto: IValidatableObject
{
private readonly IClientRepository _clientRepository;
public InviteNewUserDto(IClientRepository clientRepository)
{
_clientRepository = clientRepository;
}
//...code omitted for brevity
}
This is how I using it in a controller
[HttpPost]
public async Task<IActionResult> RegisterUser([FromBody] InviteNewUserDto model)
{
if (!ModelState.IsValid) return BadRequest(ModelState);
//...omitted for brevity
}
But I am getting a System.NullReferenceException in the DTO class
This is happening since dependency injection is not working in the DTO class.
How can I fix this ?
DI will not resolve dependences for ViewModel.
You could try validationContext.GetService in Validate method.
public class InviteNewUserDto: IValidatableObject
{
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
IClientRepository repository = (IClientRepository)validationContext.GetService(typeof(IClientRepository));
return null;
}
}
Did you register ClientRepository in startup.cs?
public void ConfigureServices(IServiceCollection services)
{
...
// asp.net DI needs to know what to inject in place of IClientRepository
services.AddScoped<IClientRepository, ClientRepository>();
...
}

How to detect in a [HttpPost] handler method the view you came from?

Considering this example:
public ViewResult View1()
{
return View();
}
public ViewResult View2()
{
return View();
}
[HttpPost]
public ActionResult Processor(SomeModel model)
{
if (comeFromView1)
{
}
//implementation
return RedirectToAction("View3");
}
Both View1 and View2 have inside a form that post to Processor.
How to detect inside it where did i come from?
One option would be to check Request.UrlReferrer. However, a user can easily spoof the referrer.
A better way would be an action filter which sets the previous action. Like this:
public class SavePreviousActionAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Session["PreviousAction"] = filterContext.RouteData["action"]
}
}
Add this to all actions by registering it as a global filter (in Global.asax):
GlobalFilters.Filters.Add(new SavePreviousActionAttribute());
And then access it in your action:
if (Session["PreviousAction"].ToString() == "View1")
{
// Came from view1
}