Convert ASMX webservice using HTTP to WCF webservice using netTcpBinding means alternative to using HttpContext

894 views Asked by At

I've been studying WCF and been refactoring my ASMX webservice solution (multiple projects) slowly according to "best practices" I've found and I've come upon some design/architecture issues where I feel a great need to pause and seek advice.

SUMMARY: How to use HttpContext in a WCF service that does NOT use ASP.Net MVC and "routes"?

DETAILS: Better performance is a primary goal for this re-write and I've read that NetTcpBinding is best for that, and so I think I need to avoid:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

and need to avoid:

serviceHostingEnvironment aspNetCompatibilityEnabled="true"

Thus, the webservice refactored for WCF needs to avoid ASP.NET dependencies such as HttpContext, Session, etc. I don't use Session at all but one webmethod (UploadFile) currently uses HttpContext as in these snippets:

[WebMethod(Description = "Upload a file with metadata properties packed in a delimited string")]
    public string UploadFile(string trimURL
                , byte[] incomingArray
                , string fileName
                , string RecordTypeName
                , string metaDataString)
    {
    string pathFileInfo; // declared here in a "bare block" so it is in scope for the finally block too
        try
        {
            pathFileInfo = ByteArrayToFile(fileName, incomingArray);
            FileInfo fi = new FileInfo(pathFileInfo);
            if (fi.Exists)
            {

and here is where HttpContext is used:

        public string ByteArrayToFile(string _FileName, byte[] _ByteArray)
    {
        string fullName = HttpContext.Current.Server.MapPath(@".\UploadWorkArea\") + _FileName;
        using (FileStream _FileStream = new FileStream(fullName
                    , FileMode.Create
                    , FileAccess.Write))
        {
            _FileStream.Write(_ByteArray, 0, _ByteArray.Length);
            _FileStream.Close();
            return fullName;
        }
    }

Therefore, I found this advice here: http://msdn.microsoft.com/en-us/library/aa702682.aspx:

"Within an AppDomain, features implemented by the HTTP runtime apply to ASP.NET content but not to WCF. Many HTTP-specific features of the ASP.NET application platform do not apply to WCF Services hosted inside of an AppDomain that contains ASP.NET content. Examples of these features include the following:

  • HttpContext: Current is always null when accessed from within a WCF service. Use RequestContext instead.

and just below that:

"These restrictions apply only to WCF services hosted in IIS application. The behavior of ASP.NET content is not affected by the presence of WCF. WCF applications that require functionality traditionally provided by the HTTP pipeline should consider using the WCF equivalents, which are host and transport independent:

OperationContext instead of HttpContext."

Finally, I have added this namespace:

using System.Web.Routing;

.. in order to resolve this issue with this:

public RequestContext(
HttpContextBase httpContext,
RouteData routeData

)

And I have arrived at the point where I'm feeling very uncertain about proceeding further. I've read a little bit about ASP.NET MVC and it's use of "routing" but I am not really there - I am just thinking about rebuilding this so it could use a faster binding for performance.

Hopefully, my question is clear and I have not rambled too much for you to give me some advice on this.

2

There are 2 answers

1
Tim Carter On BEST ANSWER

refer to the second answer at How to get working path of a wcf application?

string mappedPath = string.Format(@"{0}\UploadWorkArea\", System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath);

Did I miss something or is that all you need?

0
Jeff Ogata On

I tried HostingEnvironment.MapPath(), but that threw an exception - you might still try it to see if it works under your configuration. I also checked HttpServerUtility.MapPath() in ILSpy and found that it calls HttpRequest.MapPath(), but I don't know if it's possible to get an HttpRequest instance within your WCF method.

If all else fails, you could try using the HostingEnvironment.ApplicationPhysicalPath property. I tried the code below and it returned the same path as Server.MapPath() when called in an ASP.NET MVC application.

Path.GetFullPath(Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @".\UploadWorkArea\", _FileName));

See this question regarding the use of Path.GetFullPath.