问:
How to create a non-persistent Field in an JPA Entity?
I have an Entity called Users that have login, name and department as fields that are stored in Users table.

My Spring-Boot configuration defines the departments that gives the system manager role for users in this application.

The key problem is that I want the login end-point to return the User data with the additional information that he/she is or is not a system manager.

I think that this information should be in the User class, but I do not want this information to be stored in the database along with other fields as the management departments may change or the user my change from one department to another that does not manage the system.

(Edit) I will define this IsManager field when user request login(): I will get user's department field and check against managerDepartment's list to set it to true ou false.

So the question is if it is right to put that information in a non-persistent field in the entity class (and how to do that) or if I may change the ResponseEntity in the rest method to add the additional information (and how) ?

答:
Well, this seems to be a question of  preference / opinion hopefully still not closed because of that.

It does not make any harm to add @Transient fields but still my preference is to avoid changing @Entities like this.

So in a quite similar case I have decided to create a wrapper Response class that holds the User and stuff like "indirect roles" like system manager role.

Mostly this is because I have all entity classes in a separate project/jar that is then used in various clients & services. Then before adding anything in @Entity I analyze if any other dependent code need this stuff or is it related only to this service, for example.

And if the addition is related only to this specific service/client I do not want to add it into @Entity and make it "more complex" because of this service needs only.

So i think my answer is included quite much the previous paragraph.


来源: stackexchange

问:
Apply drop caps to each word in a link
I'd like to recreate the menu effect seen at http://www.thedecoratorsource.co.uk using CSS fonts and drop caps.

I know that I can use

```<code>p.introduction:first-letter {
font-size : 300%;
}
</code>```

which will give me the first word with a larger first characerer but I want to apply it to each word. I'm guessing there isn't a way to do this with CSS(3). Would my best bet with javascript? I've already got Moo on the page so this would be my preferred method.

I don't want to add extra HTML to my links to achieve this.

Thanks

答: It looks like Lettering.js would help with that, although it's for jQuery, not Moo.</p>

ContentLicense: CC BY-SA 2.5

Title: Apply drop caps to each word in a link

Body:
I'd like to recreate the menu effect seen at http://www.thedecoratorsource.co.uk using CSS fonts and drop caps.

I know that I can use

p.introduction:first-letter {
font-size : 300%;
}

which will give me the first word with a larger first characerer but I want to apply it to each word. I'm guessing there isn't a way to do this with CSS(3). Would my best bet with javascript? I've already got Moo on the page so this would be my preferred method.

I don't want to add extra HTML to my links to achieve this.

Thanks


问:
How do I add a border header of a link on my navigation bar while removing the div's border?
This is what it looks like at the moment:
I want to remove the gray border under the 'active' class element (i.e. the Home in this picture), while having the orange thicker bottom-border replace it. How do I go about doing that?

* {
    font-family: 'Asap', sans-serif;
    margin: 0;
}

div.header {
    background-color: rgba(0, 0, 0, 0.1);
    position: absolute;
    width: 100%;
    border-bottom: solid rgba(0, 0, 0, 0.1) 2px;
}

div.header a.text {
    text-decoration: none;
    color: gray;
    padding: 20px;
    text-transform: capitalize;
    float: left;
    transition: 0.1s;
}

div.header a.text:hover {
    color: rgba(0, 0, 0, 0.7);
    background-color: rgba(0, 0, 0, 0.1);
}

div.header a.text.active {
    color: #ff5e00;
    border-bottom: solid #ff5e00;```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE>
<html>
    <head>
        <title>Ant Arni's Crappy Site!</title>
        <link href="css/main.css" type="text/css" rel=stylesheet>
        <link href="https://fonts.googleapis.com/css?family=Asap" rel="stylesheet">
    </head>
    <body>
        <div class=header>
            Home
            Members
            Handbook
            Apply
            Staff
        </div>
    </body>
</html></code>```

答:
use :psuedo elemnt :afterinstead of direct if you want costum position.

here the snippet :

div.header {
    background-color: rgba(0, 0, 0, 0.1);
    position: absolute;
    width: 100%;
    border-bottom: solid rgba(0, 0, 0, 0.1) 2px;
}

div.header a.text {
    text-decoration: none;
    position:relative;
    color: gray;
    padding: 20px;
    text-transform: capitalize;
    float: left;
    transition: 0.1s;
}

div.header a.text:hover {
    color: rgba(0, 0, 0, 0.7);
    background-color: rgba(0, 0, 0, 0.1);
}

div.header a.text.active {
    color: #ff5e00;
 }

 div.header a.text.active:after{
       content: " ";
    position: absolute;
    width: 100%;
    height: 2px;
    border-bottom: solid #ff5e00;
    bottom: -2px;
    left: 0;
 }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class=header>
            Home
            Members
            Handbook
            Apply
            Staff
        </div></code>```

ContentLicense: CC BY-SA 3.0

Body:
This is what it looks like at the moment:
I want to remove the gray border under the 'active' class element (i.e. the Home in this picture), while having the orange thicker bottom-border replace it. How do I go about doing that?

* {
    font-family: 'Asap', sans-serif;
    margin: 0;
}

div.header {
    background-color: rgba(0, 0, 0, 0.1);
    position: absolute;
    width: 100%;
    border-bottom: solid rgba(0, 0, 0, 0.1) 2px;
}

div.header a.text {
    text-decoration: none;
    color: gray;
    padding: 20px;
    text-transform: capitalize;
    float: left;
    transition: 0.1s;
}

div.header a.text:hover {
    color: rgba(0, 0, 0, 0.7);
    background-color: rgba(0, 0, 0, 0.1);
}

div.header a.text.active {
    color: #ff5e00;
    border-bottom: solid #ff5e00;

<!DOCTYPE>

        <title>Ant Arni's Crappy Site!</title>
        <link href="css/main.css" type="text/css" rel=stylesheet>
        <link href="https://fonts.googleapis.com/css?family=Asap" rel="stylesheet">

            Home
            Members
            Handbook
            Apply
            Staff

Body:
use :psuedo elemnt :afterinstead of direct if you want costum position.

here the snippet :

div.header {
    background-color: rgba(0, 0, 0, 0.1);
    position: absolute;
    width: 100%;
    border-bottom: solid rgba(0, 0, 0, 0.1) 2px;
}

div.header a.text {
    text-decoration: none;
    position:relative;
    color: gray;
    padding: 20px;
    text-transform: capitalize;
    float: left;
    transition: 0.1s;
}

div.header a.text:hover {
    color: rgba(0, 0, 0, 0.7);
    background-color: rgba(0, 0, 0, 0.1);
}

div.header a.text.active {
    color: #ff5e00;
 }

 div.header a.text.active:after{
       content: " ";
    position: absolute;
    width: 100%;
    height: 2px;
    border-bottom: solid #ff5e00;
    bottom: -2px;
    left: 0;
 }

<div class=header>
            <a href=# class="text active">Home</a>
            <a href=# class=text>Members</a>
            <a href=# class=text>Handbook</a>
            <a href=# class=text>Apply</a>
            <a href=# class=text>Staff</a>
        </div>


问:
std::string_view on temporary string - catch by ASan
This is dangling pointer|reference example:

```<code>#include <string>
#include <string_view>
#include <iostream>

std::string foo() {
    return "test";
}

int main() {
    std::string_view bar = foo(); // bar is pointed to destructed string
    std::cout << bar << std::endl;
}
</code>```

Address sanitizer cannot catch it, at least with default options.
Is it possible to catch such errors with address sanitizer?

UPD.

Reported this bug:

https://bugs.llvm.org/show_bug.cgi?id=35285

https://github.com/google/sanitizers/issues/879

答:
My guess (you haven't provided compiler version) is that operator << is implemented externally so Asan can't sanitize it and detect error (unless you rebuild libstdc++ with Asan). Here's what I get with my GCC 6.2 (I slightly modified repro as I don't have access to c++1z):

```<code>  call    operator delete(void*)
.L17:
  movq    %rbx, %rsi
  movl    std::cout, %edi
  call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  call    std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
</code>```

Body:
This is dangling pointer|reference example:

#include <string>
#include <string_view>
#include <iostream>

std::string foo() {
    return "test";
}

int main() {
    std::string_view bar = foo(); // bar is pointed to destructed string
    std::cout << bar << std::endl;
}

Address sanitizer cannot catch it, at least with default options.
Is it possible to catch such errors with address sanitizer?

UPD.

Reported this bug:

https://bugs.llvm.org/show_bug.cgi?id=35285

https://github.com/google/sanitizers/issues/879

Body:
My guess (you haven't provided compiler version) is that operator << is implemented externally so Asan can't sanitize it and detect error (unless you rebuild libstdc++ with Asan). Here's what I get with my GCC 6.2 (I slightly modified repro as I don't have access to c++1z):

  call    operator delete(void*)
.L17:
  movq    %rbx, %rsi
  movl    std::cout, %edi
  call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
  call    std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)


问:
Is signed char overflow undefined within the range -255 to 255?
Is the following code undefined behavior according to GCC in C99 mode:</p>

```<code>signed char c = CHAR_MAX; // assume CHAR_MAX < INT_MAX
c = c + 1;
printf("%d", c);
</code>```

答:
No, it has implementation-defined behavior, either storing an implementation-defined result or possibly raising a signal.

Firstly, the usual arithmetic conversions are applied to the operands. This converts the operands to type int and so the computation is performed in type int. The result value 128 is guaranteed to be representable in int, since INT_MAX is guaranteed to be at least 32767 (5.2.4.2.1 Sizes of integer types), so next a value 128 in type int must be converted to type char to be stored in c. If char is unsigned, CHAR_MAX is guaranteed to be at least 255; otherwise, if SCHAR_MAX takes its minimal value of 127:

6.3.1.3 Signed and unsigned integers

When a value with integer type is converted to another integer type, [if]  the new type is signed and the value cannot be represented in it[,] either the
  result is implementation-defined or an implementation-defined signal is raised.

In particular, gcc can be configured to treat char as either signed or unsigned (-f\[un\]signed-char); by default it will pick the appropriate configuration for the target platform ABI, if any. If a signed char is selected, all current gcc target platforms that I am aware of have an 8-bit byte (some obsolete targets such as AT&T DSP1600 had a 16-bit byte), so it will have range [-128, 127] (8-bit, two's complement) and gcc will apply modulo arithmetic yielding -128 as the result:

  The result of, or the signal raised by, converting an integer to a signed integer type when the value cannot be represented in an object of that type (C90 6.2.1.2, C99 and C11 6.3.1.3).

For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised.

Body:
Is the following code undefined behavior according to GCC in C99 mode:

signed char c = CHAR_MAX; // assume CHAR_MAX < INT_MAX
c = c + 1;
printf("%d", c);


问:
Compute word n-grams on original text or after lemma/stemming process?
I'm thinking about use word n-grams techniques on a raw text. But I have a doubt:

does it have sense use word n-grams after applying lemma/stemming on text? If not, why should I use word n-grams only on raw files? What are pros and cons?

答:
Computing word n-grams after lemmatization or stemming would be done for the same reasons as you would want to before stemming. Sometimes this gets you false positives, e.g., (D3) but it usually increases recall in such a meaningful way that you want to do it.

In some domains, e.g., short-text, stemming can hurt. The best thing to do is to test, but in general, I would suggest stemming and case-folding, but it really depends on your domain and queries.

Q="criminal records"

D1 = "... has a criminal record ..." (match on stem)

D2 = "... released the criminal records ..." (match normally)

D3 = "... while working on 'Smooth Criminal', recording ..." (false match on stem)

It's a precision/recall tradeoff. You can increase recall by stemming (always) and you can increase precision by not stemming. But it depends on what kinds of queries you are serving. If you're running code search, for instance, you almost never want to stem or preprocess, because users expect to type in exact symbol names and then find them.


问:
How to make invisible datatable when there is no data?
Is it possible to hide a table when it doesn't have any data(rows) inside?
I'm using the query datatables plugin.

I couldn't find any option in the documentation.

答:
I did with draw event, for every time my datatable changes it checks if has data:</p>

```<code>var table = $('#example').DataTable();

table.on('draw', function () {
    if (table.data().any()) {
        $(this).parent().show();
    } else {
        $(this).parent().hide();
    }
});
</code>```

Body:
I did with draw event, for every time my datatable changes it checks if has data:

var table = $('#example').DataTable();

table.on('draw', function () {
    if (table.data().any()) {
        $(this).parent().show();
    } else {
        $(this).parent().hide();
    }
});


问:
gradient descent seems to fail
I implemented a gradient descent algorithm to minimize a cost function in order to gain a hypothesis for determining whether an image has a good quality. I did that in Octave. The idea is somehow based on the algorithm from the machine learning class by Andrew Ng

Therefore I have 880 values "y" that contains values from 0.5 to ~12. And I have 880 values from 50 to 300 in "X" that should predict the image's quality.

Sadly the algorithm seems to fail, after some iterations the value for theta is so small, that theta0 and theta1 become "NaN". And my linear regression curve has strange values...

here is the code for the gradient descent algorithm:
(theta = zeros(2, 1);, alpha= 0.01, iterations=1500)

```<code>function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters

    tmp_j1=0;
for i=1:m,
    tmp_j1 = tmp_j1+ ((theta (1,1) + theta (2,1)*X(i,2)) - y(i));
end

    tmp_j2=0;
for i=1:m,
    tmp_j2 = tmp_j2+ (((theta (1,1) + theta (2,1)*X(i,2)) - y(i)) *X(i,2));
end

    tmp1= theta(1,1) - (alpha *  ((1/m) * tmp_j1))
    tmp2= theta(2,1) - (alpha *  ((1/m) * tmp_j2))

    theta(1,1)=tmp1
    theta(2,1)=tmp2

    % ============================================================

    % Save the cost J in every iteration
    J_history(iter) = computeCost(X, y, theta);
end
end
</code>```

And here is the computation for the costfunction:

```<code>function J = computeCost(X, y, theta)   %

m = length(y); % number of training examples
J = 0;
tmp=0;
for i=1:m,
    tmp = tmp+ (theta (1,1) + theta (2,1)*X(i,2) - y(i))^2; %differenzberechnung
end
J= (1/(2*m)) * tmp
end
</code>```

ContentLicense: CC BY-SA 4.0

Title: gradient descent seems to fail

Body:
I implemented a gradient descent algorithm to minimize a cost function in order to gain a hypothesis for determining whether an image has a good quality. I did that in Octave. The idea is somehow based on the algorithm from the machine learning class by Andrew Ng

Therefore I have 880 values "y" that contains values from 0.5 to ~12. And I have 880 values from 50 to 300 in "X" that should predict the image's quality.

Sadly the algorithm seems to fail, after some iterations the value for theta is so small, that theta0 and theta1 become "NaN". And my linear regression curve has strange values...

here is the code for the gradient descent algorithm:
(theta = zeros(2, 1);, alpha= 0.01, iterations=1500)

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters

    tmp_j1=0;
for i=1:m,
    tmp_j1 = tmp_j1+ ((theta (1,1) + theta (2,1)*X(i,2)) - y(i));
end

    tmp_j2=0;
for i=1:m,
    tmp_j2 = tmp_j2+ (((theta (1,1) + theta (2,1)*X(i,2)) - y(i)) *X(i,2));
end

    tmp1= theta(1,1) - (alpha *  ((1/m) * tmp_j1))
    tmp2= theta(2,1) - (alpha *  ((1/m) * tmp_j2))

    theta(1,1)=tmp1
    theta(2,1)=tmp2

    % ============================================================

    % Save the cost J in every iteration
    J_history(iter) = computeCost(X, y, theta);
end
end

And here is the computation for the costfunction:

function J = computeCost(X, y, theta)   %

m = length(y); % number of training examples
J = 0;
tmp=0;
for i=1:m,
    tmp = tmp+ (theta (1,1) + theta (2,1)*X(i,2) - y(i))^2; %differenzberechnung
end
J= (1/(2*m)) * tmp
end

Body:
This should work:-

theta(1,1) = theta(1,1) - (alpha*(1/m))*((X*theta - y)'* X(:,1) );

theta(2,1) = theta(2,1) - (alpha*(1/m))*((X*theta - y)'* X(:,2) );


问:
Regex in Google Analytics Advanced Custom Filter not working as expected
I'm trying to setup a custom advanced filter in Google analytics to remove a particular query parameter (sys_id) from the URL when another parameter (id=ticket) is set in the URL.

For example, I want this URL:

```<code>/sp?id=ticket&table=incident&sys_id=cb7a9061db05c300d70a38ff9d9619f8
</code>```

to be captured as:

```<code>/sp?id=ticket&table=incident
</code>```

In my custom advanced filter, I have Field A -> Extract A set to Request URI with regex: (.*id\=ticket.*)(&sys_id=(\w|\d){32})($|\&.*)

In the Output To -> Constructor, I have set Request URI to $A1$A3

Result: Google analytics is logging /sp?id=ticket&table=incident8

Why am I getting the last character (the 8 in the above example) at the end of the string and how do I get rid of it to get just the output I want?

答:
The third capturing group (\w|\d){32} in your pattern is a repeated capturing group, and it stores the last captured value in the group memory buffer (the 8 in your test case).

Since \w already matches digits, you do not even need the alternation group. You may safely replace (\w|\d){32} with \w{32}.

Body:
I'm trying to setup a custom advanced filter in Google analytics to remove a particular query parameter (sys_id) from the URL when another parameter (id=ticket) is set in the URL.

For example, I want this URL:

/sp?id=ticket&table=incident&sys_id=cb7a9061db05c300d70a38ff9d9619f8

to be captured as:

/sp?id=ticket&table=incident

In my custom advanced filter, I have Field A -> Extract A set to Request URI with regex: (.*id\=ticket.*)(&sys_id=(\w|\d){32})($|\&.*)

In the Output To -> Constructor, I have set Request URI to $A1$A3

Result: Google analytics is logging /sp?id=ticket&table=incident8

Why am I getting the last character (the 8 in the above example) at the end of the string and how do I get rid of it to get just the output I want?


问:
How to send a notification to another PC?
Is there a way i can send a notification/message to another PC in C/C++? I think something like net send, but i don't know if there is another way to send a notification/message. I created an application which will run on every PC, and i want, that if my application has finished it should send a notification to my PC, that it has finished running. I don't know if there is a solution for my question, but if yes, could someone tell me, how to do that?

Thanks,

kampi

答:
Net Send is an option, but I think it will annoy the crap out of you, as it sends console toast to your computer, which pops up in front of the tasks you are working on. Personally, I would find that incredibly annoying.

If you created the application, you have the ability to include notication code. As an example, you can set up a service on your box and write the code to contact that service. On a windows machine, this can be a WCF service. You can also wrap this in a windows service if you want to fire up non-annoying toast.

I am not sure how to set up C to access a service, so another option might be to drop something in a folder and have a file watcher tell you. A bit kludgy, of course.


问:
WooCommerce orderby rand not working
Our product template displays four cross sells after adding a product to cart. If the product doesn't have four cross sells defined then any gaps are filled with products that have been marked with a "generic cross sell" custom field, in a random order.

```<code>remove_all_filters('posts_orderby'); // suggested by other answers
$args = array(
    'post_type' => 'product',
    'orderby' => 'rand',
    'order' => 'desc',
    'posts_per_page' => $gaps_to_fill,
    'post__not_in' => $posts_to_exclude,
    'meta_query' => array(
        array(
            'key' => 'is_generic_cross_sell',
            'compare' => '==',
            'value' => '1'
        )
    )
);
$generics = new WP_Query( $args );
if( $generics->have_posts() ) :
    while ( $generics->have_posts() ) : $generics->the_post();
        wc_get_template_part( 'content', 'product-modal' );
    endwhile;
endif;
wp_reset_query();
</code>```

If I run print_r($generics) the query looks like:

```<code>WP_Query Object ( [query] => Array ( [post_type] => product [orderby] => rand [order] => desc [posts_per_page] => 4 [post__not_in] => Array ( [0] => 908 ) [meta_query] => Array ( [0] => Array ( [key] => is_generic_cross_sell [compare] => == [value] => 1 ) ) )
</code>```

But query_vars looks like:

```<code> [query_vars] => Array ( [post_type] => product [orderby] => menu_order [order] => ASC [posts_per_page] => 4 [post__not_in] => Array ( [0] => 914 ) [meta_query] => Array ( [0] => Array ( [key] => is_generic_cross_sell [compare] => == [value] => 1 ) )
</code>```

i.e. orderby changes from "rand" to "menu_order".

Why does this happen and how can I prevent it?

答:
The problem was caused by the "Simple Custom Post Order" plugin.

Solution:
Replaced "Simple Custom Post Order" with "Post Types Order" (identical functionality).
Update query to include:

```<code>"suppress_filters" => true
</code>```

Query now returns random order but client can still drag and drop to rearrange product order in the backend.

Title: WooCommerce orderby rand not working

Body:
Our product template displays four cross sells after adding a product to cart. If the product doesn't have four cross sells defined then any gaps are filled with products that have been marked with a "generic cross sell" custom field, in a random order.

remove_all_filters('posts_orderby'); // suggested by other answers
$args = array(
    'post_type' => 'product',
    'orderby' => 'rand',
    'order' => 'desc',
    'posts_per_page' => $gaps_to_fill,
    'post__not_in' => $posts_to_exclude,
    'meta_query' => array(
        array(
            'key' => 'is_generic_cross_sell',
            'compare' => '==',
            'value' => '1'
        )
    )
);
$generics = new WP_Query( $args );
if( $generics->have_posts() ) :
    while ( $generics->have_posts() ) : $generics->the_post();
        wc_get_template_part( 'content', 'product-modal' );
    endwhile;
endif;
wp_reset_query();

If I run print_r($generics) the query looks like:

WP_Query Object ( [query] => Array ( [post_type] => product [orderby] => rand [order] => desc [posts_per_page] => 4 [post__not_in] => Array ( [0] => 908 ) [meta_query] => Array ( [0] => Array ( [key] => is_generic_cross_sell [compare] => == [value] => 1 ) ) )

But query_vars looks like:

 [query_vars] => Array ( [post_type] => product [orderby] => menu_order [order] => ASC [posts_per_page] => 4 [post__not_in] => Array ( [0] => 914 ) [meta_query] => Array ( [0] => Array ( [key] => is_generic_cross_sell [compare] => == [value] => 1 ) )

i.e. orderby changes from "rand" to "menu_order".

Why does this happen and how can I prevent it?

Body:
The problem was caused by the "Simple Custom Post Order" plugin.

Solution:
Replaced "Simple Custom Post Order" with "Post Types Order" (identical functionality).
Update query to include:

"suppress_filters" => true

Query now returns random order but client can still drag and drop to rearrange product order in the backend.


问:
Root URL's for ServiceStack and .NET Core 2
I've recently had cause to upgrade a servicestack service from .NET Core 1.1 to .NET Core 2.0.

Previously, my root URL was defined in the program class a bit like this...

IWebHost host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseStartup<Startup>()
    .UseUrls("http://*:44444/api/myservice")
    .Build();
host.Run();

With .NET Core 2.0, it appears that it is not possible to specify the root path in 'UseUrls' method - I get an exception which says System.InvalidOperationException: A path base can only be configured using IApplicationBuilder.UsePathBase() to use incorporate the UsePathBaseMiddleware in order to set the root path.

I find, that when I specify just the root path + port number in the WebHostBuilder and set the UsePathBase in the apphost file (either before or after a call to app.UseServiceStack(...)) that everything is available from the root (i.e. I think my call to UsePathBase is being ignored?!).

My requests are decorated with a route attribute which look like this:

[Route("users/{username}", "Get"]

Using .NET Core 1.1, I was able to access this service at

http://[URL]:[PORT]/api/user/users/[USERNAME]

Using .NET Core 2.0, the service appears at

http://[URL]:[PORT]/users/[USERNAME]

Now, I can hard code the routes to include the '/api/user' prefix on each defined route attribute, or I think I can do something in GetRouteAttributes() in the AppHost to override all the discovered routes and apply a prefix as I need - but the metadata page always appears at the root address (i.e. http://[URL]:[PORT]/metadata ) rather than at http://[URL]:[PORT]/api/[SERVICE]/metadata.

This is a problem for me because I have dozens of services at the same public URL (the port is hidden by an API Gateway), so I need the metadata pages to appear at somewhere other than the root.

Is there an (preferably low-impact) way to make services routes behave as they did in .NET Core 1.1?

UPDATE - 18/09/17 after a bit of research

I've been able to find two ways of making this work (neither of them ideal...)

The first way:

This is a complete repo of my first solution. I figured out how to use app.UsePathBase to change to root URL, but the metadata detail pages don't take this path base into account, so they just show every service method starting from '/'

```<code>using Funq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ServiceStack;
using System;
using System.Threading.Tasks;

namespace ServiceStackCore1Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "My Service";

            IWebHost host = WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseUrls("http://*:32505/")
                .Build();
            host.Run();

        }
    }

    internal class PathSetupStartupFilter : IStartupFilter
    {
        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
        {
            return app =>
            {
                app.UsePathBase("/api/myservice");
                next(app);
            };
        }
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging();
            services.AddTransient<IStartupFilter, PathSetupStartupFilter>();

        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {

            loggerFactory.AddConsole((x, y) => y > LogLevel.Trace);
            app.UseServiceStack(Activator.CreateInstance<AppHost>());

            app.Run(context => Task.FromResult(0) as Task);
        }
    }

    public class AppHost : AppHostBase
    {
        public AppHost()
            : base("ASM Cloud - My Service", typeof(MyService).GetAssembly())
        {
        }

        /// <summary>
        /// Configure the given container with the
        /// registrations provided by the funqlet.
        /// </summary>
        /// <param name="container">Container to register.</param>
        public override void Configure(Container container)
        {
            this.Plugins.Add(new PostmanFeature());
        }
    }

    public class MyService : Service
    {
        public TestResponse Any(TestRequest request)
        {
            //throw new HttpError(System.Net.HttpStatusCode.NotFound, "SomeErrorCode");
            return new TestResponse { StatusCode = 218, UserName = request.UserName };
        }

        [Route("/test/{UserName}", "GET", Summary = "test")]
        public class TestRequest : IReturn<TestResponse>
        {

            public string UserName { get; set; }
        }

        public class TestResponse : IHasStatusCode
        {
            public int StatusCode { get; set; }
            public string UserName { get; set; }
        }

    }
}
</code>```

The second way - this does provide correct functionality - both for service routing and metadata display but Servicestack throws an exception when resolving the path at every call. In this full repo, I use the HandlerFactoryPath to set my base URI, which according to servicestack docs should specify the base route of the application.

```<code>using Funq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ServiceStack;
using System;
using System.Threading.Tasks;

namespace ServiceStackCore1Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "My Service";

            IWebHost host = WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseUrls("http://*:32505/")
                .Build();
            host.Run();
        }
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole((x, y) => y > LogLevel.Trace);
            app.UseServiceStack(Activator.CreateInstance<AppHost>());

            app.Run(context => Task.FromResult(0) as Task);
        }
    }

    public class AppHost : AppHostBase
    {
        public AppHost()
            : base("My Service", typeof(MyService).GetAssembly())
        {
        }

        /// <summary>
        /// Configure the given container with the
        /// registrations provided by the funqlet.
        /// </summary>
        /// <param name="container">Container to register.</param>
        public override void Configure(Container container)
        {

            Plugins.Add(new PostmanFeature());
            SetConfig(new HostConfig
            {
                HandlerFactoryPath = "/api/myservice"
            });
        }
    }

    public class MyService : Service
    {
        public TestResponse Any(TestRequest request)
        {
            return new TestResponse { StatusCode = 200, UserName = request.UserName };
        }

        [Route("/test/{UserName}", "GET", Summary = "test")]
        public class TestRequest : IReturn<TestResponse>
        {
            public string UserName { get; set; }
        }

        public class TestResponse : IHasStatusCode
        {
            public int StatusCode { get; set; }
            public string UserName { get; set; }
        }
    }
}
</code>```

So, like I said, this solution works, but throws an exception

fail: Microsoft.AspNetCore.Server.Kestrel[13]
        Connection id "0HL7UFC5AIAO6", Request id "0HL7UFC5AIAO6:00000004": An unhandled exception was thrown by the application.
  System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
  Parameter name: startIndex
     at System.String.Substring(Int32 startIndex, Int32 length)
     at ServiceStack.AppHostBase.d__7.MoveNext() in C:\BuildAgent\work\799c742886e82e6\src\ServiceStack\AppHostBase.NetCore.cs:line 101
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame1.<ProcessRequestsAsync>d__2.MoveNext()
  fail: Microsoft.AspNetCore.Server.Kestrel[13]
        Connection id "0HL7UFC5AIAO6", Request id "0HL7UFC5AIAO6:00000004": An unhandled exception was thrown by the application.
  System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
  Parameter name: startIndex
     at System.String.Substring(Int32 startIndex, Int32 length)
     at ServiceStack.AppHostBase.<ProcessRequest>d__7.MoveNext() in C:\BuildAgent\work\799c742886e82e6\src\ServiceStack\AppHostBase.NetCore.cs:line 101
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame1.d__2.MoveNext()

Findings aside, the actual problem (not the stuff I have shown above in the update) could be down to the following two issues with ASPNet hosting:

https://github.com/aspnet/Hosting/issues/815

https://github.com/aspnet/Hosting/issues/1120

I'm still at a bit of a loss as to what to do to solve my original problem - so I'd appreciate any help.

答:
Not sure if you ever found a solution to this, but someone on the servicestack forums had the same issue (as did I myself when I started using CORE edition of servicestack).

if you have access to that forum, you can follow progress here

and if you don't, in summary @mythz noted that:

"This is a breaking change they've added in .NET Core 2.0, we'll investigate to see if there's a workaround but otherwise I'd avoid fighting .NET Core conventions and just host it on a port and use a reverse proxy to implement the desired base hosting url."

Body:
I've recently had cause to upgrade a servicestack service from .NET Core 1.1 to .NET Core 2.0.

Previously, my root URL was defined in the program class a bit like this...

IWebHost host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseStartup<Startup>()
    .UseUrls("http://*:44444/api/myservice")
    .Build();
host.Run();

With .NET Core 2.0, it appears that it is not possible to specify the root path in 'UseUrls' method - I get an exception which says System.InvalidOperationException: A path base can only be configured using IApplicationBuilder.UsePathBase() to use incorporate the UsePathBaseMiddleware in order to set the root path.

I find, that when I specify just the root path + port number in the WebHostBuilder and set the UsePathBase in the apphost file (either before or after a call to app.UseServiceStack(...)) that everything is available from the root (i.e. I think my call to UsePathBase is being ignored?!).

My requests are decorated with a route attribute which look like this:

[Route("users/{username}", "Get"]

Using .NET Core 1.1, I was able to access this service at

http://[URL]:[PORT]/api/user/users/[USERNAME]

Using .NET Core 2.0, the service appears at

http://[URL]:[PORT]/users/[USERNAME]

Now, I can hard code the routes to include the '/api/user' prefix on each defined route attribute, or I think I can do something in GetRouteAttributes() in the AppHost to override all the discovered routes and apply a prefix as I need - but the metadata page always appears at the root address (i.e. http://[URL]:[PORT]/metadata ) rather than at http://[URL]:[PORT]/api/[SERVICE]/metadata.

This is a problem for me because I have dozens of services at the same public URL (the port is hidden by an API Gateway), so I need the metadata pages to appear at somewhere other than the root.

Is there an (preferably low-impact) way to make services routes behave as they did in .NET Core 1.1?

UPDATE - 18/09/17 after a bit of research

I've been able to find two ways of making this work (neither of them ideal...)

The first way:

This is a complete repo of my first solution. I figured out how to use app.UsePathBase to change to root URL, but the metadata detail pages don't take this path base into account, so they just show every service method starting from '/'

using Funq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ServiceStack;
using System;
using System.Threading.Tasks;

namespace ServiceStackCore1Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "My Service";

            IWebHost host = WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseUrls("http://*:32505/")
                .Build();
            host.Run();

        }
    }

    internal class PathSetupStartupFilter : IStartupFilter
    {
        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
        {
            return app =>
            {
                app.UsePathBase("/api/myservice");
                next(app);
            };
        }
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging();
            services.AddTransient<IStartupFilter, PathSetupStartupFilter>();

        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {

            loggerFactory.AddConsole((x, y) => y > LogLevel.Trace);
            app.UseServiceStack(Activator.CreateInstance<AppHost>());

            app.Run(context => Task.FromResult(0) as Task);
        }
    }

    public class AppHost : AppHostBase
    {
        public AppHost()
            : base("ASM Cloud - My Service", typeof(MyService).GetAssembly())
        {
        }

        ///
        /// Configure the given container with the
        /// registrations provided by the funqlet.
        ///
        /// <param name="container">Container to register.</param>
        public override void Configure(Container container)
        {
            this.Plugins.Add(new PostmanFeature());
        }
    }

    public class MyService : Service
    {
        public TestResponse Any(TestRequest request)
        {
            //throw new HttpError(System.Net.HttpStatusCode.NotFound, "SomeErrorCode");
            return new TestResponse { StatusCode = 218, UserName = request.UserName };
        }

        [Route("/test/{UserName}", "GET", Summary = "test")]
        public class TestRequest : IReturn<TestResponse>
        {

            public string UserName { get; set; }
        }

        public class TestResponse : IHasStatusCode
        {
            public int StatusCode { get; set; }
            public string UserName { get; set; }
        }

    }
}

The second way - this does provide correct functionality - both for service routing and metadata display but Servicestack throws an exception when resolving the path at every call. In this full repo, I use the HandlerFactoryPath to set my base URI, which according to servicestack docs should specify the base route of the application.

using Funq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ServiceStack;
using System;
using System.Threading.Tasks;

namespace ServiceStackCore1Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "My Service";

            IWebHost host = WebHost.CreateDefaultBuilder()
                .UseStartup<Startup>()
                .UseUrls("http://*:32505/")
                .Build();
            host.Run();
        }
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole((x, y) => y > LogLevel.Trace);
            app.UseServiceStack(Activator.CreateInstance<AppHost>());

            app.Run(context => Task.FromResult(0) as Task);
        }
    }

    public class AppHost : AppHostBase
    {
        public AppHost()
            : base("My Service", typeof(MyService).GetAssembly())
        {
        }

        ///
        /// Configure the given container with the
        /// registrations provided by the funqlet.
        ///
        /// <param name="container">Container to register.</param>
        public override void Configure(Container container)
        {

            Plugins.Add(new PostmanFeature());
            SetConfig(new HostConfig
            {
                HandlerFactoryPath = "/api/myservice"
            });
        }
    }

    public class MyService : Service
    {
        public TestResponse Any(TestRequest request)
        {
            return new TestResponse { StatusCode = 200, UserName = request.UserName };
        }

        [Route("/test/{UserName}", "GET", Summary = "test")]
        public class TestRequest : IReturn<TestResponse>
        {
            public string UserName { get; set; }
        }

        public class TestResponse : IHasStatusCode
        {
            public int StatusCode { get; set; }
            public string UserName { get; set; }
        }
    }
}

So, like I said, this solution works, but throws an exception

fail: Microsoft.AspNetCore.Server.Kestrel[13]
        Connection id "0HL7UFC5AIAO6", Request id "0HL7UFC5AIAO6:00000004": An unhandled exception was thrown by the application.
  System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
  Parameter name: startIndex
     at System.String.Substring(Int32 startIndex, Int32 length)
     at ServiceStack.AppHostBase.d__7.MoveNext() in C:\BuildAgent\work\799c742886e82e6\src\ServiceStack\AppHostBase.NetCore.cs:line 101
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.d__3.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame1.<ProcessRequestsAsync>d__2.MoveNext()
  fail: Microsoft.AspNetCore.Server.Kestrel[13]
        Connection id "0HL7UFC5AIAO6", Request id "0HL7UFC5AIAO6:00000004": An unhandled exception was thrown by the application.
  System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
  Parameter name: startIndex
     at System.String.Substring(Int32 startIndex, Int32 length)
     at ServiceStack.AppHostBase.<ProcessRequest>d__7.MoveNext() in C:\BuildAgent\work\799c742886e82e6\src\ServiceStack\AppHostBase.NetCore.cs:line 101
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame1.d__2.MoveNext()

Findings aside, the actual problem (not the stuff I have shown above in the update) could be down to the following two issues with ASPNet hosting:

https://github.com/aspnet/Hosting/issues/815

https://github.com/aspnet/Hosting/issues/1120

I'm still at a bit of a loss as to what to do to solve my original problem - so I'd appreciate any help.


问:
I cant get this conditional update or insert statement to work in SQL Server
This code is supposed to update a record if the name of the person in table 1 is the same as the name of the person in table 2 and if it is not then just insert the name and age of the person as a new record into table 1.    </p>

```<code> SELECT
    CASE
    WHEN
    [Name] = @Name
    THEN
    UPDATE
    dbo.EmployeeInfo
    SET
    dbo.EmployeeInfo.Age = V.Age
    FROM dbo.EmployeeInfo I
    INNER JOIN
    dbo.UpdateEmployeeInfo V
    ON
    V.[Name] = I.[Name]

    ELSE

    SELECT * INTO dbo.EmployeeInfo
    FROM dbo.UpdateEmployeeInfo
    WHERE [Name] = @Name

    END
    FROM dbo.EmployeeInfo
</code>```

<p>I have edited the code just to use IF conditions yet it still does not work </p>

```<code>IF
dbo.EmployeeInfo.[Name] = @Name
THEN
UPDATE
dbo.EmployeeInfo
SET
dbo.EmployeeInfo.Age = V.Age
FROM dbo.EmployeeInfo I
INNER JOIN
dbo.UpdateEmployeeInfo V
ON
V.[Name] = I.[Name]

ELSE

SELECT * INTO dbo.EmployeeInfo
FROM dbo.UpdateEmployeeInfo
WHERE [Name] = @Name
</code>```

答:
update a record if the name of the person in table 1 is the same as the name of the person in table 2 and if it is not then just insert the name and age of the person as a new record into table 1.

You also could use merge

```<code>merge table1 as t
using table2 as s
on s.name=t.name
when matched then
update
set t.name=s.name
when not matched by target
then
insert (name,age)
values(age,name)
</code>```

Merge has some issues as per this thread by Paul White..You could also use seperate statements like below  in a transaction as per your need

```<code>update t
set t.name=s.name
from table1 t1
join
table2 s
on s.name=t.name

if @@rowcount=0
insert into table1
(name,age)
values
(10,'a')
</code>```

Body:
This code is supposed to update a record if the name of the person in table 1 is the same as the name of the person in table 2 and if it is not then just insert the name and age of the person as a new record into table 1.

 SELECT
    CASE
    WHEN
    [Name] = @Name
    THEN
    UPDATE
    dbo.EmployeeInfo
    SET
    dbo.EmployeeInfo.Age = V.Age
    FROM dbo.EmployeeInfo I
    INNER JOIN
    dbo.UpdateEmployeeInfo V
    ON
    V.[Name] = I.[Name]

    ELSE

    SELECT * INTO dbo.EmployeeInfo
    FROM dbo.UpdateEmployeeInfo
    WHERE [Name] = @Name

    END
    FROM dbo.EmployeeInfo

I have edited the code just to use IF conditions yet it still does not work

IF
dbo.EmployeeInfo.[Name] = @Name
THEN
UPDATE
dbo.EmployeeInfo
SET
dbo.EmployeeInfo.Age = V.Age
FROM dbo.EmployeeInfo I
INNER JOIN
dbo.UpdateEmployeeInfo V
ON
V.[Name] = I.[Name]

ELSE

SELECT * INTO dbo.EmployeeInfo
FROM dbo.UpdateEmployeeInfo
WHERE [Name] = @Name

Body:
update a record if the name of the person in table 1 is the same as the name of the person in table 2 and if it is not then just insert the name and age of the person as a new record into table 1.

You also could use merge

merge table1 as t
using table2 as s
on s.name=t.name
when matched then
update
set t.name=s.name
when not matched by target
then
insert (name,age)
values(age,name)

Merge has some issues as per this thread by Paul White..You could also use seperate statements like below  in a transaction as per your need

update t
set t.name=s.name
from table1 t1
join
table2 s
on s.name=t.name

if @@rowcount=0
insert into table1
(name,age)
values
(10,'a')