I'm trying to send a class that contains a Function over http.
Can this be accomplished?
Its supposed to work like this:
1) Client contacts Web.API.
2) Web.API returns class with the Function
3) Client executes Function.
Class will look a bit like this :
public class UploadTicket
{
public string url { get; set; }
public List<Tuple<string, string>> Headers { get; set; }
public Func<string> SpecialFunction { get; set; }
}
I need this function to alter the uploadurl by appending an ID every time a package is sent - but only if it's to certain dataproviders, and in other cases uploadurls must be modified in other ways. I need to do it this way, so i can keep the client side code as general as possible.
Sounds a little goofy but yeah you can, on the condition that you send source to the client and not some pre-compiled version (otherwise it'd really be a gaping security hole). Just use the C# runtime compiler. But it implies the client is C#, that's why it sounds goofy.
This is actually a common pattern everybody uses every day. Think of the web browser that hits a web server and gets a page with javascript in it. The same thing happens. The browser compiles the JS and executes it, even though the source was produced remotely.
Related
I have recorded a test with my webtest recorder in VS2015. When I am rerunning the test,at one point it fails at a dependent GET request of a .css file. The url in the webtest result shows something like this https://mycompany/blah/Style%20Guides/Global_CSS.css The error is a simple 404 error.
Now I go to the main request and search for this particular dependent request so that I can set its Parse_Dependent_Request option as False or set the Extected_Http_Status_Code as 404, which ever works is fine for me. But I am not able to find this particular dependent request under the main or any other request.
I have tried to change all the Parse_Dependent_Request option of all the dependent requests to false and understand which one actually sends the Get request, but none of them worked.I did a generate code from the webtest and literally did a page search but in vain.Do how do I get the request?
Many dependent requests (DRs) are not explicit in the web test. When parse dependent requests of the main request is true, Visual Studio processes the HTML response of that main request to find the DRs and they are added to the list of DRs. Any DR responses that are HTML may also be parsed and their DRs added to the list.
One technique to handle missing or problematic DRs is to run a plugin that modifies the list of DRs. The code below is based on the WebTestDependentFilter on page 189 of the "Visual Studio Performance Testing Quick Reference Guide" (Version 3.6) available from Codeplex. The Codeplex document has lots of other good information about web and load testing.
public class WebTestDependentFilter : WebTestPlugin
{
public string FilterDependentRequestsThatStartWith { get; set; }
public string FilterDependentRequestsThatEndWith { get; set; }
public override void PostRequest(object sender, PostRequestEventArgs e)
{
WebTestRequestCollection depsToRemove = new WebTestRequestCollection();
// Note, you can't modify the collection inside a foreach, hence the second collection
// requests to remove.
foreach (WebTestRequest r in e.Request.DependentRequests)
{
if (!string.IsNullOrEmpty(FilterDependentRequestsThatStartWith))
{
if (r.Url.StartsWith(FilterDependentRequestsThatStartWith))
{
depsToRemove.Add(r);
}
}
else if (!string.IsNullOrEmpty(FilterDependentRequestsThatEndWith))
{
if (r.Url.EndsWith(FilterDependentRequestsThatEndWith))
{
depsToRemove.Add(r);
}
}
}
foreach (WebTestRequest r in depsToRemove)
{
e.WebTest.AddCommentToResult(string.Format("Removing dependent: {0}", r.Url));
e.Request.DependentRequests.Remove(r);
}
}
}
The search criteria in the above code can easily be modified to (for example) check the middle parts of the URL.
Another variation is to set the expected response code of some DRs to other values. This might make a more accurate performance test than deleting the failing DRs as the server is still required to handle the request and return a response.
I am trying to design client/server application, that would be able to exchange "commands". The thing is, that server application is processing some stuff and I would like the client to be able to for example send command "pause" to the server.
The thing is, that my manager suggested, that best approach would be to create interface (ICommand for example) and then class for each command (Pause, Resume) that would inherit from the ICommand. After that, we could simply create an object Pause with [DataContract] attribute, that would be sent over to server.
For that purpouse, I tried to use shared-types, so I created seprated assembly in which I designed all the [DataContracts], so that both server and client can use them (they have reference leading to them).
On the server, we would then have [OperationContract], that would take the [DataContract] as parameter and return [DataContract] as well, like this:
[ServiceKnownType(typeof(PauseServer))]
[ServiceKnownType(typeof(Resume))]
[ServiceContract]
public interface ITestService
{
[OperationContract]
ICommand DoCommand(ICommand command);
}
The problem is, that apart from some properties, we would like to have for example method "Execute(param1,param2)", that would do certain operation - this method would do different operation on server (pause the process) and different operation on client side (change the status and enable "Resume" button for example). Like this:
[DataContract(Namespace="PauseContract")]
public class Pause
{
string _param1;
int _param2;
public void Execute()
{
// DO SOMETHING HERE
}
[DataMember]
public string Param1
{
get
{
return _param1;
}
set
{
this._param1 = value;
}
}
[DataMember]
public int Param2
{
get
{
return _param2;
}
set
{
this._param2 = value;
}
}
}
In the end, the whole process would like this:
1) Client wants to pause the process, so it creates object "Pause", that would contain for example ID of the process.
2) This object is passed to the DoCommand() method, which creates object "Pause" on server side and run its "Execute()" method with the given parameters.
3) If the Pausing process ended well, the Pause object is returned back to client (with process ID and other attributes)
4) If client gets this response, it will know that the process has eben paused and run its own "Execute()" method on its own Pause object, that would change the GUI and so on.
So my question is - is it somehow possible, to have different implementation of contracts stored in common library on both server/client side? Or is this approach wrong in general? From what I have heards, it is not advised to include behaviour (methods) to [DataContracts], but I thought it would be ok, if I dont mark them with [DataMember] attribute.
Thank You, Jakub.
To be honest, I don't think the ICommand with ServiceKnownType attribute idea works well for commands.
ServiceKnownType is designed to support polymorphism across service boundaries in the context of type properties and not behavior.
Your Pause/Resume scenario would be very easily implement with the exchange of two distinct request/response DataContract definitions.
I am administrator of a small practice project web application, AngularJS front-end pulling its back-end data from a C#/.NET WebAPI, and I'm handling security using the SimpleMembershipProvider.
I suspect that the way I implemented said security is not the best (I'm told ASP.NET Identity is now the way to go?) but that's another question altogether.
The issue that I'm very bewilderingly running into is that I get occasional reports that on a given page load to display a particular user's data, it returns somebody else's. Reloading the page fixes the issue (evidently) and I haven't been able to duplicate the scenario myself, or figure out anything particularly consistent in the users to which this happens.
None of the information being displayed is at all sensitive in nature (the app's just a friendly front end for an already public third-party API) so I'm not in panic mode about this, but I am both concerned and confused and want it fixed.
Here is what one of my API controller endpoints looks like:
[Authorize]
public class UserController : ApiController
{
private static int _userId;
private readonly IUserProfileRepository _userProfileRepository;
public UserController()
{
_userProfileRepository = new UserProfileRepository(new DatabaseContext());
_userId = WebSecurity.GetUserId(User.Identity.Name);
}
public UserProfileDto Get()
{
return _userProfileRepository.GetUserProfileById(_userId).ToDto();
}
}
Any feedback on where I might be going wrong here or what might be causing the intermittant inconsistency would be very much appreciated. (Laughter also acceptable if the way I handled this is just really bad. :P )
Static class fields are shared by all instances/threads of the same AppDomain (in your case - process). Different http requests are processed by threads running in parallel. Any two threads running [almost] at the same time may (will) change the value of _userId. You are assigning _userId in the constructor of your controller, and a new instance of this controller is created for each http request that is to be responded to by UserController. Therefore, this assignment will happen multiple times.
You will have hard time replicating this problem, since you are a single user testing the code, hence there are no overlapping request threads.
Remove static specifier from the _userId field declaration of the controller class.
Note: make sure that DatabaseContext is disposed of. One place that can be used for this is the overriden Controller.Dispose.
Change the Get to retrieve the user id rather than from a static variable:
public UserProfileDto Get()
{
return _userProfileRepository.GetUserProfileById(WebSecurity.GetUserId(User.Identity.Name)).ToDto();
}
Looking for some way to make one post method in WCF restful service which can accept both xml and json. I can see that is possible with Get method which automatically returns json/xml based on request header.
One solution I could think of is:
Get the post data as "Stream" and read it to a string.
Check request header and deserialize it to json or xml.
Set OutgoingResponse format accrodingly and return response.
I'm able to do #1 but stuck in #2 and #3.
Microsoft has already done this for you, don't reinvent the wheel.
public class DataController : ApiController
{
public void Post(DataModel model)
{
// Whether the body contains XML, JSON, or Url-form-encoded it will be deserialized
// into the model object which you can then interact with in a strongly-typed manner
}
}
public class DataModel
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
}
You can download ASP.NET MVC4 for free which includes the new Web API. http://www.asp.net/mvc/mvc4 . This is basically the final product of the WCF Web API, which is no longer supported. Unless you have so much code already written with the original Web API that it wouldn't be practical to make the switch, this will save you a lot of time in the long run. Otherwise you will be stuck with a Beta product that has bugs which will never be fixed.
For reasons I would rather not discuss, I need to create a custom authentication system for my app. I was just reviewing the system and am having some doubts if my solution is thread safe. My goal was to create a solution that would allow my app to authenticate a user one time and that users authentication info would be shared by all master pages, pages, classes, user controls, etc that are used. (But not share the same info between users)
Here is my setup:
PageHttpModule.cs - this is added to the web.config as a httpModule.
public class PageHttpModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.AuthenticateRequest += new EventHandler(OnAuthenticateRequest);
}
public void OnAuthenticateRequest(Object s, EventArgs e)
{
CurrentUser.Initialize();
}
public void Dispose() { }
}
CurrentUser.cs
public static class CurrentUser
{
public static bool IsAuthenticated { get; private set; }
public static string Email {get; set;}
public static string RealName {get; set;
public static string UserId {get; set;}
public static void Initialize()
{
CurrentUser.AuthenticateUser();
}
Note: this is a scaled down version of my authentication code.
public static void AuthenticateUser()
{
UserAuthentication user = new UserAuthentication();
user.AuthenticateUser();
if (user.IsAuthenticated)
{
CurrentUser.IsAuthenticated = true;
CurrentUser.UserId = user.UserId;
CurrentUser.Email = user.Email;
CurrentUser.RealName = user.RealName;
}
}
}
UserAuthentication.cs
public class UserAuthentication
{
public string Email { get; set; }
public string RealName { get; set; }
public string UserId { get; set; }
public bool IsAuthenticated { get; private set; }
public UserAuthentication()
{
IsAuthenticated = false;
Email = String.Empty;
RealName = String.Empty;
UserId = String.Empty;
}
public void AuthenticateUser()
{
//do some logic here.. if the user is ok then
IsAuthenticated = true
Email = address from db
UserId = userid from db;
Realname = name from db;
}
}
I have tested between 3 different browsers and it seems to work fine, but I am still learning and don't want to make a huge mistake.
If my logic is totally wrong, then how should I do it so I dont have to put user lookups on every page directly?
No, this is not thread-safe. For instances of the application living in separate processes or AppDomains, this will be just fine. But if your ASP.NET server is going to serve multiple requests at once using threading, you are going to have some very bad side effects if two people try to use the application at the same time.
In the Init method, the HttpApplication parameter is described as:
An HttpApplication that provides access to the methods, properties, and events common to all application objects within an ASP.NET application
The key here is that there is one PageHttpModule for the lifetime of the app, and all static objects that exist in the lifetime of the app will share those variables.
BUT... the lifetime of CurrentUser is only within the scope of the OnAuthenticateRequest event, unless some other reference keeps the object alive. If it were a PageHttpModule member-level variable, you'd have issues that you would have noticed immediately. In your situation, however, you'll work fine so long as you don't get more than one simultaneously-processed OnAuthenticateRequest call.
The answer to your question is no, you're not guaranteed to be thread-safe. If two authentication requests come in simultaneously, you're not guaranteed to have one event complete before the other begins, in which case the second user can appear authenticated, when it's really the first user that was logged on.
Update
I think part of the problem is coming from a misunderstanding of AuthenticateRequest... By the time this event is called, the user has already been authenticated by either Windows or Forms authentication... you're just getting notified that it's happened. In fact, the property User.Identity.IsAuthenticated has already been set (I believe this event fires even if the user fails authentication, but I won't swear to that without double-checking).
If I understand what you are after, you're really trying to write your own custom membership provider. If you take this approach, you will have all the benefits of the built-in authentication... all of the standard properties related to authentication will be set and accessible, and will be isolated to a user's session in the manner you want.
Writing a custom provider is not a small feat, but it is doable, and you should be able to reuse a lot of the logic and code you're currently using for your classes.
Trying to completely re-write the authentication mechanism would be jumping through painful, complicated hoops.
Some links:
http://www.devx.com/asp/Article/29256/0/page/3
http://www.codeproject.com/KB/aspnet/WSSecurityProvider.aspx
http://msdn.microsoft.com/en-us/library/f1kyba5e%28v=VS.90%29.aspx
The properties you must implement may look daunting, but unless you need a specific functionality (such as ResetPassword), you can simply throw a NotImplementedException. Code only what you'll use.
Why not just do it the way microsoft recommends?
http://msdn.microsoft.com/en-us/library/9wff0kyh.aspx
I've done custom authentication this way and it works fine.
Here is another link which should prove useful:
Link
What you have done with IHttpModule seems like a good path to tackle this kind of issue. One of the purposes of the http module as stated by microsoft is to enable for any kind of special authentication. When http module intializes it uses the same instance for new requests. Since you dont have any global variables I am not so sure how to address your thread safe question. It seems like you are onlu reading some data out, so please elaborate!