Routing View from external post - asp.net-mvc

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.

Related

ASP.NET MVC page redirect to IS4's login straight away without going to home page

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.

How to Access Client_id of Calling Client in Identity Server 4 Controller

I am using Identity Server 4 for authentication for both a website and WPF application. On the website, I want users to have the ability to check a Remember Me box when signing in, but I don't want that for the WPF application. I have the logic to disable that checkbox on the front end, but am having trouble in my controller. I have this function
[HttpGet]
public async Task<IActionResult> Login(string returnUrl)
{
LoginViewModel _vm;
_vm = await BuildLoginViewModelAsync(returnUrl);
//if(Client_id == "wpf") <- this is what I need help with
//{
// _vm.AllowRememberMe = false;
//}
return View(_vm);
}
This controller contains
private readonly IIdentityServerInteractionService mInteraction;
private readonly IClientStore mClientStore;
private readonly IAuthenticationSchemeProvider mSchemeProvider;
private readonly IEventService mEvents;
Any help would be appreciated
You can get the client id from the AuthorizationRequest returned from the IIdentityServerInteractionService as follows using your code snipet:
var context = await mInteraction.GetAuthorizationContextAsync(returnUrl);
_vm.AllowedRememberMe = context.ClientId != "wpf";
However, you would be better off placing this logic in your BuildLoginViewModelAsync method where the view model is constructed rather than setting the property after construction.
I don't believe the client_id is directly available from any IS4 constructs in the Login method. However, depending on your OIDC flow, it's likely that your client_id was passed as part of the "returnUrl" parameter. Look at your return URL and see if it's there.
For example, I have a spa website connecting to IS4 that shows a returnURL of:
https://localhost:8080/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DspaClient%26redirect_uri%3Dhttps...(long url continues)
You can see that it contains the "client_id" parameter with a value of "spaClient". Simply parse the returnUrl using your code of choice (e.g. RegEx) and extract the client_id from there. I don't have any WPF experience, so it may behave differently and not pass this parameter.

ASP.Net Web API: Regarding web api action calling url or end point url

i am new in asp.net web api. just reading a article on web api from this url http://www.c-sharpcorner.com/article/remote-bind-kendo-grid-using-angular-js-and-Asp-Net-web-api/
now see this code
[RoutePrefix("api/EmployeeList")]
public class EmployeeDetailsController : ApiController
{
[HttpGet]
[Route("List")]
public HttpResponseMessage EmployeeList()
{
try
{
List<Employee> _emp = new List<Employee>();
_emp.Add(new Employee(1, "Bobb", "Ross"));
_emp.Add(new Employee(2, "Pradeep", "Raj"));
_emp.Add(new Employee(3, "Arun", "Kumar"));
return Request.CreateResponse(HttpStatusCode.OK, _emp, Configuration.Formatters.JsonFormatter);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.OK, ex.Message, Configuration.Formatters.JsonFormatter);
}
}
}
as per my understanding the requesting url should be /api/EmployeeList/List but if anyone look the above image then must notice different url api/Employee/GetEmployeeList is being used to call list action method. so i just like to know the reason why different url is getting issued to call List action function ?
also do not understand how this url api/Employee/GetEmployeeList can work in this situation because controller name is EmployeeDetailsController but RoutePrefix has been used to address it api/EmployeeList and action method name is EmployeeList() which has been change to List..........so some one tell me how this url api/Employee/GetEmployeeList can invoke list action of web api ?
please discuss in detail. thanks
Did you activate AttributeRouting? If not, standard routing is in place and your current attributes will be ignored.
You need to do this in the WebApi registration process, like this:
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Other Web API configuration not shown.
}
Then, you can remove any method call like this:
config.Routes.MapHttpRoute
to disable conventional routing.
BTW, the call api/Employee/GetEmployeeList is valid because Employee is the name of your controller, Get is the verb and EmployeeList is the name of the method.
Did you enable attribute routing? You do this by default in webapiconfig.cs by adding this line of code:
config.MapHttpAttributeRoutes();
#Monojit-Sarkar. The URL the user showed in postman did not also match the code. In the code, these are the users we expect to see:
_emp.Add(new Employee(1, "Bobb", "Ross"));
_emp.Add(new Employee(2, "Pradeep", "Raj"));
_emp.Add(new Employee(3, "Arun", "Kumar"));
But the results in postman are different as shown in the image the user posted. So something is disconnected from the article/image and the sample code.

AuthorizationCodeWebApp.AuthResult result is NULL randomly! after AJAX call in MVC app

I need an advice. I wrote an MVC app to access Google Gmail API (using Google OAuth 2 Authentication), as explained in Google's Tutorial: https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-aspnet-mvc
The idea is - Index action initializes
private static AuthorizationCodeWebApp.AuthResult result;
after it performs Google OAuth2 authentication. That result object has Credentials.Token property that contains issued AccessToken and RefreshToken. Next, Index action returns a vew (rendered HTML) that has a DIV where I want to load Gmail messages asynchronously. When the page loads, there is a Javascript function that fires on page load even in a browser. Simple. That Javascript function makes an AJAX call to Gmail() action in HomeController. It makes these calls with a 1 minute interval (js timer). Since result object is marked as static it should be available to pass Credentials to Gmail API Service method that is implemented in GmailManager helper class:
return PartialView(GmailManager.GetGmail(result.Credential));
The problem is sometimes the result object is null inside the Gmail() action and the NullReferenceException is thrown
I dont understand why this is happening if the result was initialized in Index action and it is static, so it should be alive by the time the call is made to Gmail() action. It should never be null. If it was constantly null I would understand and try to debug and fix it, but it is random and I cannot understand the logic.
If someone understands what is happening please advice.
Below is my HomeController code:
public class HomeController : Controller
{
private static AuthorizationCodeWebApp.AuthResult result;
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).AuthorizeAsync(cancellationToken);
if (result.Credential == null)
return new RedirectResult(result.RedirectUri);
if (!string.IsNullOrEmpty(result.Credential.Token.RefreshToken))
SaveRefreshTocken(result.Credential.Token.RefreshToken);
return View();
}
public ActionResult Gmail()
{
result.Credential.Token.RefreshToken = WebConfigurationManager.AppSettings["RefreshToken"];
return PartialView(GmailManager.GetGmail(result.Credential));
}
private static void SaveRefreshTocken(string refreshToken)
{
Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
config.AppSettings.Settings["RefreshToken"].Value = refreshToken;
config.Save();
}
}

how do i call webservice from MVC3 Razor Controller?

In my project I need to call a web service from a controller. I have already done the following, and it works.
Add the web reference for the web service to the project.
Call the service as follows:
Service Wservice=new Service();
Wservice.loginCompleted+=new Wservice_login_Completed;
WService.login_Async("username","Password");
Note: Whenever i call this service it throws an error that is
"An asynchronous operation cannot be started at this time.
Asynchronous operations may only be started within an asynchronous handler
or module or during certain events in the Page lifecycle. If this
exception occurred while executing a Page, ensure that the Page is marked
<%# Page Async="true" %>."
To overcome this issue I use
[Httppost]
public ActionResult login(logmodel model)
{
Task.Factory.StartNew(() =>
{
Wservice.loginCompleted+=new Wservice_login_Completed;
WService.login_Async("username","Password");
});
if(finalresult==true)
{
*** return View();
}
}
void Wservice_login_completed()
{
Here i got the output.
}
But the calling of Wservice_login_completed() function was after the View*** was returned,, so I'm not getting the result. How do I achieve "calling webservice from Controller".. Any ideas?
Finally i called the webservice from MVC Controller Successfully.
Note: Add ServiceReference instead of WebReference and avoid
"Task.Factory.StartNew(()=>);" Process.
[Httppost]
public ActionResult login(logmodel model)
{
Wservice.ServiceSoapClient _host = new Wservice.ServiceSoapClient("ServiceSoap");
var result_out = _host.login(uname, pwd, "test1", "test2", "test3", "test4");
}
Here "ServiceSoap" is an endpoint for our service.. you may got the endpoint to be presented in app.confiq or web.config files.
Happy Coding...!
get the following NuGet:
microsoft http client
(id = Microsoft.Net.Http)
Create a Web API Controller (webapi_Controller_Name)
Your Post function should be similar to the following function
Put this function in your Web Api Controller
[HttpPost]
public void PostForm(objUser ws_Obj)
{
// put you code here
}
Call your Web Service from you regular Controller as follows.
This is an Async call and will Web Service will return immediately.
//call the web service, Asynch
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("52323/");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.PostAsJsonAsync("//52323/api/webapi_Controller_Name/PostForm", objContact);
First, create a service reference by right clicking on the project name in the solution explorer, then hover over the "Add" option and click on "Service Reference..."
Second, paste your web service address in the "Address" field of the "Add Service Reference" page, be sure to add "?wsdl" to the end of your web service address or it won't work, and then press "Go". You will see the web service appear in the "Services" area. Click on the service to see the available services which will appear in the "Operations" section. Rename the service if you want, then press OK to create the service.
Finally, put the following code in your MVC Controller. Place the code in a Get or Post controller, it doesn't matter.
// Declare the Request object.
ServiceReference1.GetSurveyRequest myGSRq = new ServiceReference1.GetSurveyRequest();
// You can set the webservice parameters here like...
myGSRq.Address = getUserData[0].address;
myGSRq.City = getUserData[0].city;
myGSRq.State = getUserData[0].state;
// Now declare the Response object.
ServiceReference1.GetSurveyResponse myGSR = new ServiceReference1.GetSurveyResponse();
//And then use the following to process the request and response.
ServiceReference1.EMPortTypeClient emptc = new ServiceReference1.EMPortTypeClient();
myGSR = emptc.GetSurvey(myGSRq);
// In this example the response Object comes back with a URL used to redirect the user
//after the webservice has been processed.
if (myGSR.Url != null)
Response.Redirect(myGSR.Url.ToString());
else
Response.Write("Error");
return null;
Pretty simple, hope this helps!
If you are creating a new service and have the option of using a webservice or a Web API, I suggest using Web API.
Build RESTful API's with ASP.NET Web API

Resources