In our WebApplication we have a lot of [WebMethod] calls. For the purpose of security we want to check if its a logged in user or not (using session). How can I check it without writing code inside all WebMethods?
eg.
[WebMethod]
public static bool WebMethodCall()
{// check if its a logged in user or not before executing the webmethod
return true;
}
I am giving you this answer by example
i have webservice named common.cs
now
public class Common : System.Web.Services.WebService
{
public Common ()
{
//here you can check your session so when ever your
webmethod will be executed this code will call first then your webmethod
}
//this webmethod will be executed after common
[WebMethod]
public static bool WebMethodCall()
{// check if its a logged in user or not before executing the webmethod
return true;
}
[WebMethod]
public static bool WebMethodCall1()
{// check if its a logged in user or not before executing the webmethod
return true;
}
}
So explaination will be like this
you have common class named common and two webmethod webmethodcall and webmethodcall1
add your common code in common
I hope this will help you regards...:)
My first thought is to utilize a custom httpModule. However, further readings indicate using SoapExtensions can do the trick. See example:
http://www.hanselman.com/blog/ASMXSoapExtensionToStripOutWhitespaceAndNewLines.aspx
Related
I am asking this because after long time searching I haven't found a good answer on this yet...
Here is what I want:
Example: I have a domain model "JobPosting" which a user should be able to change state to published, if it is still a draft. Before publishing I must not only validate the model properties I must also validate many different requirements regarding the user account, it's registered company etc. All this validation logic is put into a service layer. So far so good...
This is how my service layer looks like:
public IValidationResult ValidatePublish(JobPosting jobPosting){
...
}
public void Publish(JobPosting jobPosting){
jobPosting.State = JobPostingState.Published;
...
}
Any my controller:
public ActionResult Publish(PublishViewModel model){
...
var validationResult = _jobService.ValidatePublish(jobPosting);
if(validationResult.Success){
_jobService.Publish(jobPosting);
...
}
...
}
And here now my questions:
I want to be able to call the ValidatePublish from the controller to show validation errors in the view. However I must never be able to publish a job when validation fails.
So to have my code more robust I added a second validation check in my Publish method in service layer:
public void Publish(JobPosting jobPosting){
if(ValidatePublish(jobPosting).Success){
jobPosting.State = JobPostingState.Published;
...
}
}
but I have not such a good feeling with this approach because now I am calling the validation twice when validation is OK during each controller publish request.
What do you think. Is the second call to much? Is there a better approach?
I am asking because my whole application looks like that and if I would ever forget a validation call in controller I might end up with an not allowed domain model state in database. That's why I added the second validation check in each service method.
Thanks in advance for your thoughts on this!!!
One quick solution might be to have the Publisher class require the JobPosting and IValidationResult objects as arguments.
public void Publish(JobPosting jobPosting, IValidationResult validation)
{
if (validation.IsValid)
{
jobPosting.State = JobPostingState.Published;
// other work here...
}
}
Your Controller can then call the Validator, receive an IValidationResult and pass that back to the presentation layer if needed. Otherwise pass on to Publisher
public ActionResult Publish(PublishViewModel model)
{
var validationResult = _jobService.ValidatePublish(jobPosting);
if(validationResult.Success) _jobService.Publish(jobPosting, validationResult);
else return View("error", validationResult);
}
Edit:
A cleaner solution may be to have the Publisher class return a PublishAttempt result.
public class PublishAttempt : IValidationResult
{
public enum AttemptOutcome {get; set;}
}
public ActionResult Publish(PublishViewModel model)
{
var attempt = _jobService.Publish(jobPosting);
if (attempt.Success) return View("success");
else return View("error", attempt.ValidationResults);
}
The following just came into my mind... what do you think:
I change my service method to:
public IValidationResult Publish(JobPosting jobPosting, bool validateOnly = false){
var validationResult = ValidatePublish(jobPosting);
if(validateOnly) return validationResult;
jobPosting.State = JobPostingState.Published;
...
return validationResult;
}
And then in controller I always call only the Publish method and not the extra ValidatePublish anymore:
public ActionResult Publish(PublishViewModel model)
{
var validationResult = _jobService.Publish(jobPosting);
if(!validationResult.Success) return View("error", validationResult);
}
And when I need only simple validation I do
var validationResult = _jobService.Publish(jobPosting, true);
Is this okey to do it like that?
Or is it not good looking if a normal service call returns IValidationResult?
i have some action inside controller likes:
public class ValuesController : Controller
{
[HttpPost]
public string GetInfo()
{
Thread.Sleep(30000); // logics imitation
return "result";
}
}
when I send request from client-side on this action I'll receive "Main Thread blocking" (like deadlock) while awaiting "logics imitations"
how i can prevent it?
already tried:
public class ValuesController : Controller
{
[HttpPost]
public async Task<string> GetInfo()
{
return await Task.Factory.StartNew(() =>
{
Thread.Sleep(30000);
return "result";
});;
}
}
Not working...
already looked (ASP.NET MVC and Ajax, concurrent requests?), but SessionState.ReadOnly way is not for me...
also tried using .svc service instead controller-action but have same troubles.
MVC by default blocks parallel sessions, and there is only one way to avoid it:
[SessionState(SessionStateBehavior.ReadOnly)]
Attribute on Controller and clearly separating logics with using writing and reading sessions.
This question was posted by my colleague. Yes, we have the situation where we need to "fire and forget" (we are trying to call actions asynchronically, when different actions are executed at the same time, but still all we have managed to get is to call actions one after another)
I am having trouble using JSF just wanted to run it by so if there is anything obvious someone can spot. I have a managed bean which is giving me trouble. In my faces-config.xml I have:
<managed-bean>
<description>Info Bean</description>
<managed-bean-name>InfoBean</managed-bean-name>
<managed-bean-class>bean.InfoBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
In my JSF I have the following:
<h:outputText value="#{InfoBean.deviceModel}" rendered="true"></h:outputText>
I have a POJO for InfoBean as follows:
public class InfoBean {
String deviceModel;
String userEmail;
String active;
public InfoBean() {
// TODO Auto-generated constructor stub
}
public String getDeviceModel() {
return deviceModel;
}
public void setDeviceModel(String deviceModel) {
this.deviceModel = deviceModel;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
}
There is a no arg constructor in POJO too, but for some reason the deviceModel value does not get displayed to the screen and I cannot figure out why! Any help much appreciated. I have a handler which is also in the faces-config as a separate managed bean, when the user clicks a button, control goes to handler class which calls a service that populates fields in the POJO InfoBean, so as I can see it should appear but it does not!
Any help much appreciated.
I have sorted out the issue and the solution is that since I had a model like this: JSP button is clicked->call goes to Handler->handler calls method in service->Service populates the managed bean InfoBean and returns it to handler
The managed bean even though declared in the config file with scope as session was NOT actually part of the session. In my handler after returning the InfoBean I added:
HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false);
session.setAttribute("InfoBean", InfoBean);
This placed it in the session and immediately and values started appearing! :-))
I have read several articles about this and never seen this mentioned, so I am wondering how it is done otherwise. One other suggestion I got was make InfoBean a private instance of the Handler with getters and setters, this way it will get created with the handler and will also be olk. I have not tried this approach though. Thanks to all who helped.
How your deviceModel property of the bean is populated?
Are you sure that it is not null? You can eventually check that by putting a log in the getter method:
public String getDeviceModel() {
System.out.println("Getter called: " + deviceModel + ".");
return deviceModel;
}
Eventually, you can modify the scope of the bean to set it as session.
Your post shows it being defined in request scope not session scope. If you change it to session, you won't need put it in using setAttribute(). Or maybe I'm missing something.
Despite changign the scope to session, it was not working, the above code where I add it to the HttpSession is necessary in order for this to work, or so I have found.
Thanks.
I have a number of permissions, and based on a set of conditions these permission determine if a user can see certain features. I have written a helper function for this as the logic in the view became quite extensive.
Essentially I'm looking for a function the same as Html.ActionLink that I can access from a class file (Ideally if I can access the Helper that would be great) So I can do somthing like so,
public static string GetAdminLinks()
{
if(PermCheck)
{
return(Html.ActionLink(...));
}
}
Any sugestions?
in controller:
Url.Action("Index", "Home", null, Request.Url.Scheme);
It largely depends on how your permission check is implemented (and of which information it needs to determine the user's permissions). Anyhow, I'd implement it as an extension to the HtmlHelper class.
Somewhere in your App_Code:
using System.Web.Mvc.Html;
public static class HtmlHelperExtensions {
public static string SecureActionLink(this HtmlHelper htmlHelper, string action, string controller){
if(PermCheck)
return htmlHelper.ActionLink(action, controller);
else
return string.Empty;
}
//add other ActionLink overrides if you like...
}
Then you'll be able to call the extension method from anywhere in your ViewPages without any code behind.
I have a method on a page marked with the webmethod and scriptmethod tags..
The method returns a collection of objects to a jquery function as JSON data with no hassles and without me having to manually serialize it.
I am now trying to recreate that same method using a HTTPHandler and was wondering why i have to now manually serialize the data.
What makes the webmethod different?
Because an HTTP handler (kind of) sits above the ASP WebForms Stack, you are totally responsible for the workings and output of the handler.
You can utilise (almost) anything you can get your hands on within the .NET framework, but for sure, an HTTPHandler will be more work than an off-the-shelf solution provided by ASP.NET.
The ASP.NET page handler is only one
type of handler. ASP.NET comes with
several other built-in handlers such
as the Web service handler for .asmx
files.
You can create custom HTTP handlers
when you want special handling that
you can identify using file name
extensions in your application
See http://msdn.microsoft.com/en-us/library/ms227675(VS.85).aspx
Web method provides you a connection between your c# class and Js file. Nowadays Using Json is a best way to get the return message in a smart format for a js function or anywhere in js file.
Regards
For lesser work:
Move your method to an ASMX (Web Service):
You will benefit the built-in serialization provided by the ScriptService:
namespace WS{
[System.web.Script.Services.ScriptService()]
[System.Web.Services.WebService(Namespace:="http://tempuri.org/")]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public Person GetDummyPerson()
{
Person p = new Person();
p.Name = "John Wayne";
p.Age = 20;
}
[WebMethod]
public IList GetPersonsByAge(int age)
{
//do actual data retrieval
List result = new List();
result.add(new Person());
result.add(new Person());
return result;
}
}
class Person
{
String Name;
int Age;
}
}
On the client side:
WS.GetDummyPerson(function(p){
alert(p.Name + "-->" + p.Age);
});
WS.GetPersonsByAge(10,function(list){
for(var i=0;i<list.length;i++)
{
document.write(list[i].Name + "==>" + list[i].Age);
}
});