AngularJs Windows Intranet User - asp.net

Using ASP.Net Web API service I can get the current windows user using the following.
public class UserController : ApiController
{
public string Get()
{
var id = WindowsIdentity.GetCurrent();
return id.Name;
}
}
My question is how can I find the current user logged in a angularjs controller without having to call the web api service?

myApp.controller('TestCtrl', function ($scope) {
$scope.getUserData = function(){
$http({method: 'GET', url: '/URLtoResourceInWebService'}).
success(function(data, status, headers, config) {
//use the data of your User object
}).error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
}); //End of Controller
Here is a real simple example of how to hit an endpoint in Angular and get back a resource from a WebService. I would actually suggest extracting out your API calls however into a service rather than using the "$http" because then you centralize them in one place, and if you switch API's your code doesn't break all over. Let me know if this helps.

Related

Azure Function SignalR Negotiate function works but Send function fails

i have a xamarin app that is trying to talk to use SignalR in Azure functions.
i have 2 azure functions as per the documentation.
public static class NegotiateFunction
{
[FunctionName("negotiate")]
public static SignalRConnectionInfo GetSignalRInfo(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
[SignalRConnectionInfo(HubName = "chat")] SignalRConnectionInfo connectionInfo)
//, UserId = "{headers.x-ms-client-principal-id}"
{
return connectionInfo;
}
}
and
public static class SendMessageFunction
{
[FunctionName("Send")]
public static Task SendMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
[SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
// var chatObj = (ChatObject)(message);
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to this user ID
// UserId = chatObj.ReciversId,
Target = "Send",
Arguments = new[] { message }
});
}
}
in my xamarin client i am connecting like this.
try
{
_connection = new HubConnectionBuilder()
.WithUrl("http://192.168.1.66:7071/api")
.Build();
_connection.On<string>("Send", (message) =>
{
AppendMessage(message);
});
await _connection.StartAsync();
}
I send message using this code in one of the pages of Xamarin app page.
try
{
await _connection.SendAsync("Send", MessageEntry.Text);
MessageEntry.Text = "";
}
connection code works it hits "negotiate" function properly but when i call SendAsync it does not hit break-point in [FunctionName("Send")] and nothing happens. It doesn't give me any exception as well.
local settings are like this
Update
i also tried Invoke. it didnt worked.
Should i try making a POST call to [FunctionName("Send")] ?
The way SignalR SaaS works in Functions is slightly different to using the NuGet package in a .NET Application.
You can't invoke a function using the SignalR library, as you can see on the attribute in your function, it's expecting a Http trigger so you have to do a POST to this endpoint instead of invoking it as you normally would.
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]
You still want to listen to the Send target as normal.

aspnetboilerplate: SignalR JWT Authentication

We are trying to integrate SignalR in an 3rd party application to talk to our Hubs we have for our aspnetboilerplate application. This is using the .NET Core template. We are having an issue with the session in aspnetboilerplate having a null UserId even when getting past the attribute on our Hub to check for authorization.
The issue we are having is at random times the UserId inside of AbpSession will just be null. It gets past the [Authorize] attribute but aspnetboilerplate seems to think the UserId is null at random times. I can invoke a method on our Hub and see the UserId is correct for that user. Then the very next time I invoke that same method on the hub with the same user the UserId inside of AbpSession is null. I can then invoke the method again and the UserId will sometimes be null or sometimes be correct. Their doesn't seem to be any consistency in this issue. Every now and then it will alternate between being null and having the correct UserId.
Our client code:
let connection = new signalR.HubConnectionBuilder()
.withUrl('ENTER HUB URL HERE',
{
transport: signalR.HttpTransportType.LongPolling,
accessTokenFactory: () => {
return 'BEARER TOKEN HERE'
}}).build()
connection.invoke('sendGroupMessage', text, hardCodedChatGroup)
Here is a sample of our SignalR Hub on the server:
[AbpMvcAuthorize]
public class OpenChatHub : Hub, ITransientDependency
{
public IAbpSession AbpSession { get; set; }
public ILogger Logger { get; set; }
public OpenChatHub()
{
AbpSession = NullAbpSession.Instance;
Logger = NullLogger.Instance;
}
public async Task SendGroupMessage(string message, string groupName)
{
// logic for the SendGroupMessage would be here
var msg = new
{
sendById = AbpSession.UserId, // this will be null at random times
message = message
};
await Clients.Group(group).SendAsync("receiveChatMessage", msg);
}
}
I can view the requests for SignalR negotiating and communicating with the Hub and I can see the token being passed correctly each time.
After doing a bit more research on this while trying to get a test project together that I could put on GitHub to reproduce the issue I did end up solving the issue.
Using the following inside of our Hub gives us the correct UserId each time now. Context.User.Identity.GetUserId();
I believe this must be a bug inside of aspnetboilerplate now. I will be trying to get an issue reported on the GitHub.

Which happens when user send multiple Asynchronous requests from a client to specific web service in c#

I have an ASP.Net MVC project in a specific page which has multiple partial pages.
Each partial page sends an Asynchronous request to a specific web service in a server.
Does IIS create a separate instance for each request?(run each web service as parallel or create a sequential queue for all requests).
I have 10 partial pages and each partial page send a request in javascript like below:
$http({
method: 'Post',
url: WebServiceUrl,
params: params
}).then(function successCallback(response) {
...
});
And on the other side(web service):
[HttpPost]
public string MyWebService(int ApplicationId)
{
try
{
using (xRDSEntities db = new xRDSEntities())
{
....
}
}
catch (Exception)
{
return "Error";
}
}
According to comments the all requests run concurrently even if the requested resource and the user be same and the web service be synchronous

use json format in an URL

I am building a rest API with asp.net my problem is that when I try to add a student to my database like that :
http://localhost:50001/api/Students?&FirstName=cc&LastName=cc&Email=student10#gmail.com&DropOut=false&Live=false&ClassId=1&ImageId=1
I get "the value variable is null",
this is my code to add a student:
// Get All Students
[Route("api/Students")]
public IEnumerable<Student> Get()
{
return _StudentService.Queryable().ToList();
}
// Insert Student
[Route("api/Students/")]
public IEnumerable<Student> Post(Student value)
{
cc.Students.Add(value);
cc.SaveChanges();
return Get();
}
I have used "Fiddler web Debugger" to test my URLs an it works only in this way:
now If I have an angularJS client that tries to add a new student to the database,how can I send data as a json format in an URL
this is how I add a new student from my client angularJS:
$http({method: 'POST', url: 'http://localhost:50001/api/Students?&FirstName=cc&LastName=cc&Email=student10#gmail.com&DropOut=false&Live=false&ClassId=1&ImageId=1})
.success(function (data) {
console.log("success");
}).error(function (data, status, headers, config) {
console.log("data error ...");
});
thanks a lot for help
If you are saying you want a true Rest API you should continue to use the POST verb as it is more semantically right for creating a new student.
Passing a new student on the URL is possible but not in the configuration you have provided.
Your API method expects a POST request and that the new student be located in the HTTP body.
Just configure your angular call to use jsonData and post it to your API.

SignalR recording when a Web Page has closed

I am using MassTransit request and response with SignalR. The web site makes a request to a windows service that creates a file. When the file has been created the windows service will send a response message back to the web site. The web site will open the file and make it available for the users to see. I want to handle the scenario where the user closes the web page before the file is created. In that case I want the created file to be emailed to them.
Regardless of whether the user has closed the web page or not, the message handler for the response message will be run. What I want to be able to do is have some way of knowing within the response message handler that the web page has been closed. This is what I have done already. It doesnt work but it does illustrate my thinking. On the web page I have
$(window).unload(function () {
if (event.clientY < 0) {
// $.connection.hub.stop();
$.connection.exportcreate.setIsDisconnected();
}
});
exportcreate is my Hub name. In setIsDisconnected would I set a property on Caller? Lets say I successfully set a property to indicate that the web page has been closed. How do I find out that value in the response message handler. This is what it does now
protected void BasicResponseHandler(BasicResponse message)
{
string groupName = CorrelationIdGroupName(message.CorrelationId);
GetClients()[groupName].display(message.ExportGuid);
}
private static dynamic GetClients()
{
return AspNetHost.DependencyResolver.Resolve<IConnectionManager>().GetClients<ExportCreateHub>();
}
I am using the message correlation id as a group. Now for me the ExportGuid on the message is very important. That is used to identify the file. So if I am going to email the created file I have to do it within the response handler because I need the ExportGuid value. If I did store a value on Caller in my hub for the web page close, how would I access it in the response handler.
Just in case you need to know. display is defined on the web page as
exportCreate.display = function (guid) {
setTimeout(function () {
top.location.href = 'GetExport.ashx?guid=' + guid;
}, 500);
};
GetExport.ashx opens the file and returns it as a response.
Thank you,
Regards Ben
I think a better bet would be to implement proper connection handling. Specifically, have your hub implementing IDisconnect and IConnected. You would then have a mapping of connectionId to document Guid.
public Task Connect()
{
connectionManager.MapConnectionToUser(Context.ConnectionId, Context.User.Name);
}
public Task Disconnect()
{
var connectionId = Context.ConnectionId;
var docId = connectionManager.LookupDocumentId(connectionId);
if (docId != Guid.Empty)
{
var userName = connectionManager.GetUserFromConnectionId(connectionId);
var user = userRepository.GetUserByUserName(userName);
bus.Publish( new EmailDocumentToUserCommand(docId, user.Email));
}
}
// Call from client
public void GenerateDocument(ClientParameters docParameters)
{
var docId = Guid.NewGuid();
connectionManager.MapDocumentIdToConnection(Context.ConnectionId, docId);
var command = new CreateDocumentCommand(docParameters);
command.Correlationid = docId;
bus.Publish(command);
Caller.creatingDocument(docId);
}
// Acknowledge you got the doc.
// Call this from the display method on the client.
// If this is not called, the disconnect method will handle sending
// by email.
public void Ack(Guid docId)
{
connectionManager.UnmapDocumentFromConnectionId(connectionId, docId);
Caller.sendMessage("ok");
}
Of course this is from the top of my head.

Resources